From 617a6af686f16c96b0061cf5d5885ed45df61cd1 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sat, 16 Oct 2010 18:47:32 -0600 Subject: [PATCH 001/746] Alpha version number for the v5.0.2 release --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 1f04c3eb3e..fea4623d18 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.0.1.8" +#define MZSCHEME_VERSION "5.0.1.900" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 0 #define MZSCHEME_VERSION_Z 1 -#define MZSCHEME_VERSION_W 8 +#define MZSCHEME_VERSION_W 900 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From f29e7130f75d3561e8505829ae025cc84f6d124d Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 16 Oct 2010 21:08:26 -0400 Subject: [PATCH 002/746] New Racket version 5.0.1.900. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index 09a45493a5..ae7eb2b7d5 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,7 +1,7 @@ Date: Sat, 16 Oct 2010 07:29:49 -0600 Subject: [PATCH 003/746] fix an interaction of `dynamic-wind' pre thunks and composable continuations Merge to 5.0.2 (cherry picked from commit caa747e5c65a45f59b7b60908f7553cdfe89e83a) --- collects/tests/racket/prompt-tests.rktl | 162 +++++++++++++++++++++++- src/racket/src/fun.c | 53 +++++--- 2 files changed, 199 insertions(+), 16 deletions(-) diff --git a/collects/tests/racket/prompt-tests.rktl b/collects/tests/racket/prompt-tests.rktl index 60c9bcf5f3..67bc988b32 100644 --- a/collects/tests/racket/prompt-tests.rktl +++ b/collects/tests/racket/prompt-tests.rktl @@ -1739,6 +1739,167 @@ (continuation-mark-set->list (current-continuation-marks) 'x))))) a))))) + +;; ---------------------------------------- +;; Tests related to cotinuations that capture pre-thunk frames + +;; Simple case: +(let ([t + (lambda (wrapper) + (test + '(pre1 mid1 post1 pre2 mid1 post1 post2) + 'cc1 + (let ([k #f] + [recs null]) + (define (queue v) (set! recs (cons v recs))) + (call-with-continuation-prompt + (lambda () + (dynamic-wind + (lambda () + (queue 'pre1) + (call-with-composable-continuation + (lambda (k0) + (set! k k0)))) + (lambda () (queue 'mid1)) + (lambda () (queue 'post1))))) + (wrapper + (lambda () + (dynamic-wind + (lambda () (queue 'pre2)) + (lambda () (k)) + (lambda () (queue 'post2))))) + (reverse recs))))]) + (t (lambda (f) (f))) + (t call-with-continuation-prompt)) + +;; Mix in some extra dynamic winds: +(test + '(pre1 mid1 post1 pre2 mid1 post1 post2 pre2 mid1 post1 post2) + 'cc2 + (let ([k #f] + [k2 #f] + [recs null]) + (define (queue v) (set! recs (cons v recs))) + (call-with-continuation-prompt + (lambda () + (call-with-continuation-prompt + (lambda () + (dynamic-wind + (lambda () + (queue 'pre1) + ((call-with-composable-continuation + (lambda (k0) + (set! k k0) + void)))) + (lambda () (queue 'mid1)) + (lambda () (queue 'post1))))) + (let/ec esc + (dynamic-wind + (lambda () (queue 'pre2)) + (lambda () + (k (lambda () + (let/cc k0 + (set! k2 k0)))) + (esc)) + (lambda () (queue 'post2)))))) + (call-with-continuation-prompt + (lambda () (k2))) + (reverse recs))) + +;; Even more dynamic-winds: +(test + '(pre0 pre1 mid1 post1 post0 + pre1.5 pre2 pre0 mid1 post1 post0 post2 post1.5 + pre3 pre1.5 pre2 pre0 mid1 post1 post0 post2 post1.5 post3) + 'cc3 + (let ([k #f] + [k2 #f] + [recs null]) + (define (queue v) (set! recs (cons v recs))) + (call-with-continuation-prompt + (lambda () + (dynamic-wind + (lambda () + (queue 'pre0)) + (lambda () + (dynamic-wind + (lambda () + (queue 'pre1) + ((call-with-composable-continuation + (lambda (k0) + (set! k k0) + void)))) + (lambda () (queue 'mid1)) + (lambda () (queue 'post1)))) + (lambda () + (queue 'post0))))) + (call-with-continuation-prompt + (lambda () + (dynamic-wind + (lambda () (queue 'pre1.5)) + (lambda () + (dynamic-wind + (lambda () (queue 'pre2)) + (lambda () (k (lambda () + (call-with-composable-continuation + (lambda (k0) + (set! k2 k0)))))) + (lambda () (queue 'post2)))) + (lambda () (queue 'post1.5))))) + (call-with-continuation-prompt + (lambda () + (dynamic-wind + (lambda () (queue 'pre3)) + (lambda () (k2)) + (lambda () (queue 'post3))))) + (reverse recs))) + +;; Arrange for the captured pre-thunk to trigger extra cloning +;; of dynmaic wind records in continuation application: +(test + '(pre1 pre2 post2 post1 pre1 pre2 post2 post1 last pre2 post2 post1) + 'cc4 + (let ([k #f] + [k2 #f] + [recs null] + [tag (make-continuation-prompt-tag)]) + (define (queue v) (set! recs (cons v recs))) + (call-with-continuation-prompt + (lambda () + (dynamic-wind + (lambda () + (queue 'pre1) + ((call-with-composable-continuation + (lambda (k0) + (set! k k0) + void)))) + (lambda () + (dynamic-wind + (lambda () (queue 'pre2)) + (lambda () + ((call-with-composable-continuation + (lambda (k0) + (set! k2 k0) + void)))) + (lambda () (queue 'post2)))) + (lambda () (queue 'post1))))) + (let ([k3 + (call-with-continuation-prompt + (lambda () + (call-with-continuation-prompt + (lambda () + (k2 (lambda () + (call-with-composable-continuation + (lambda (k0) + (abort-current-continuation tag (lambda () k0))))))))) + tag)]) + (queue 'last) + (call-with-continuation-prompt + (lambda () + (k void)) + tag)) + (reverse recs))) + ;; ---------------------------------------- ;; Try long chain of composable continuations @@ -1804,4 +1965,3 @@ (k (lambda () (abort-current-continuation (default-continuation-prompt-tag) (lambda () 45)))))))) - diff --git a/src/racket/src/fun.c b/src/racket/src/fun.c index 2efcb55a08..a5841f9c2a 100644 --- a/src/racket/src/fun.c +++ b/src/racket/src/fun.c @@ -5141,7 +5141,7 @@ static Scheme_Overflow *clone_overflows(Scheme_Overflow *overflow, void *limit, } static Scheme_Dynamic_Wind *clone_dyn_wind(Scheme_Dynamic_Wind *dw, - Scheme_Object *limit_prompt_tag, int limit_depth, + Scheme_Object *limit_prompt_tag, int limit_depth, int limit_count, Scheme_Dynamic_Wind *tail, int keep_tail, int composable) { @@ -5153,6 +5153,8 @@ static Scheme_Dynamic_Wind *clone_dyn_wind(Scheme_Dynamic_Wind *dw, break; if (composable && limit_prompt_tag && (dw->prompt_tag == limit_prompt_tag)) break; + if (cnt == limit_count) + break; scheme_ensure_dw_id(dw); naya = MALLOC_ONE_RT(Scheme_Dynamic_Wind); memcpy(naya, dw, sizeof(Scheme_Dynamic_Wind)); @@ -5525,13 +5527,15 @@ static MZ_MARK_STACK_TYPE exec_dyn_wind_pres(Scheme_Dynamic_Wind_List *dwl, { Scheme_Thread *p = scheme_current_thread; int old_cac = scheme_continuation_application_count; + int need_clone = 0; + Scheme_Dynamic_Wind *dw; for (; dwl; dwl = dwl->next) { if (dwl->dw->pre) { - p->dw = dwl->dw->prev; p->next_meta = dwl->meta_depth + dwl->dw->next_meta; if (dwl->meta_depth > 0) { - scheme_apply_dw_in_meta(dwl->dw, 0, dwl->meta_depth, cont); + if (!skip_dws) + scheme_apply_dw_in_meta(dwl->dw, 0, dwl->meta_depth, cont); } else { /* Restore the needed part of the mark stack for this dynamic-wind context. Clear cached info on restore @@ -5555,6 +5559,19 @@ static MZ_MARK_STACK_TYPE exec_dyn_wind_pres(Scheme_Dynamic_Wind_List *dwl, } p = scheme_current_thread; } + + if (p->dw != dwl->dw->prev) { + /* something happened in the pre-thunk to change the + continuation that we're building */ + need_clone = 1; + } + + if (need_clone) { + dw = clone_dyn_wind(dwl->dw, NULL, -1, 1, p->dw, 0, 0); + dw->next_meta = p->next_meta; + } else + dw = dwl->dw; + p->dw = dw; } return copied_cms; } @@ -5603,7 +5620,7 @@ static Scheme_Cont *grab_continuation(Scheme_Thread *p, int for_prompt, int comp else if (prompt) { Scheme_Dynamic_Wind *dw; if (p->dw) { - dw = clone_dyn_wind(p->dw, prompt_tag, -1, NULL, 0, composable); + dw = clone_dyn_wind(p->dw, prompt_tag, -1, -1, NULL, 0, composable); cont->dw = dw; cont->next_meta = p->next_meta; } else @@ -6031,7 +6048,7 @@ static void restore_continuation(Scheme_Cont *cont, Scheme_Thread *p, int for_pr p->next_meta = common_next_meta; if (p->dw) { /* can be empty if there's only the implicit prompt */ /* also, there may be no dw with prompt_tag if there's only the implicit prompt */ - all_dw = clone_dyn_wind(p->dw, cont->prompt_tag, -1, NULL, 1, 0); + all_dw = clone_dyn_wind(p->dw, cont->prompt_tag, -1, -1, NULL, 1, 0); for (dw = all_dw; dw && !SAME_OBJ(dw->prompt_tag, cont->prompt_tag); dw = dw->prev) { p->dw = p->dw->prev; } @@ -6048,8 +6065,12 @@ static void restore_continuation(Scheme_Cont *cont, Scheme_Thread *p, int for_pr if (cont->dw) { int meta_depth; + /* The allow_dw chain that we build up here is actually + premature, in that the tail to splice onto may change + in pre-thunks. It doesn't usually happen, and we can + detect that case in exec_dyn_wind_pres() in re-clone. */ common_depth = (p->dw ? p->dw->depth : -1); - all_dw = clone_dyn_wind(cont->dw, NULL, cont->common_dw_depth, p->dw, 0, 0); + all_dw = clone_dyn_wind(cont->dw, NULL, cont->common_dw_depth, -1, p->dw, 0, 0); if ((common_depth != -1) && (common_depth != all_dw->depth)) { /* Move p->next_meta to the last added dw's next_meta. */ @@ -6077,7 +6098,6 @@ static void restore_continuation(Scheme_Cont *cont, Scheme_Thread *p, int for_pr copied_cms = exec_dyn_wind_pres(dwl, dwl_len, cont, copied_cms, clear_cm_caches, &sub_conts, cont->skip_dws); p = scheme_current_thread; - p->dw = all_dw; p->next_meta = cont->next_meta; } } @@ -8734,6 +8754,17 @@ Scheme_Object *scheme_dynamic_wind(void (*pre)(void *), p = scheme_current_thread; + if (pre) { + ASSERT_SUSPEND_BREAK_ZERO(); + p->suspend_break++; + pre(data); + p = scheme_current_thread; + --p->suspend_break; + } + + /* set up `dw' after pre(), in case a continuation + is captured in pre() and composed later */ + dw = MALLOC_ONE_RT(Scheme_Dynamic_Wind); #ifdef MZTAG_REQUIRED dw->type = scheme_rt_dyn_wind; @@ -8749,14 +8780,6 @@ Scheme_Object *scheme_dynamic_wind(void (*pre)(void *), dw->depth = 0; dw->next_meta = p->next_meta; - if (pre) { - ASSERT_SUSPEND_BREAK_ZERO(); - p->suspend_break++; - pre(data); - p = scheme_current_thread; - --p->suspend_break; - } - p->next_meta = 0; p->dw = dw; From 0b8537e24670fee2cf97c58b71d714b15661707c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 16 Oct 2010 22:24:16 -0500 Subject: [PATCH 004/746] fixed mangled test case (cherry picked from commit 93260c7dd0d2d9a846121b140cecc6693e48942a) --- collects/redex/tests/tl-test.rkt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/collects/redex/tests/tl-test.rkt b/collects/redex/tests/tl-test.rkt index f071a0c17d..3684c5d138 100644 --- a/collects/redex/tests/tl-test.rkt +++ b/collects/redex/tests/tl-test.rkt @@ -564,10 +564,9 @@ (v .... 2)) (define-metafunction/extension f M g : v -> v - [(g 2) 2])) + [(g 2) 2]) -(current-traced-metafunctions 'all) -(term (g (2))) + (term (g (2)))) (let () (define-metafunction empty-language From fef3bc2b7748551adf2ca8f576029b6ccb2af173 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 17 Oct 2010 06:34:06 -0600 Subject: [PATCH 005/746] initialize `make-flvector' result with default 0.0s Merge to 5.0.2 (cherry picked from commit 51f20afd0b4d93b27645351dbe8b3e903dd4e0b6) --- src/racket/src/number.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/racket/src/number.c b/src/racket/src/number.c index 455eb1009f..a3a0020ff2 100644 --- a/src/racket/src/number.c +++ b/src/racket/src/number.c @@ -3321,6 +3321,8 @@ static Scheme_Object *do_make_flvector (const char *name, int as_shared, int arg { Scheme_Double_Vector *vec; long size; + double d; + int i; if (SCHEME_INTP(argv[0])) size = SCHEME_INT_VAL(argv[0]); @@ -3348,14 +3350,14 @@ static Scheme_Object *do_make_flvector (const char *name, int as_shared, int arg #endif vec = scheme_alloc_flvector(size); - if (argc > 1) { - int i; - double d = SCHEME_DBL_VAL(argv[1]); - for (i = 0; i < size; i++) { - vec->els[i] = d; - } + if (argc > 1) + d = SCHEME_DBL_VAL(argv[1]); + else + d = 0.0; + for (i = 0; i < size; i++) { + vec->els[i] = d; } - + return (Scheme_Object *)vec; } From 83dfd8850512025f161e2de6e9890f0eaaeec547 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 17 Oct 2010 08:51:18 -0600 Subject: [PATCH 006/746] fix --disable-jit plus --disable-futures Merge to 5.0.2 (cherry picked from commit aaeb21e0cc165a53fb8577fe35212af1b1b53876) --- src/racket/src/fun.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/racket/src/fun.c b/src/racket/src/fun.c index a5841f9c2a..a32297bd88 100644 --- a/src/racket/src/fun.c +++ b/src/racket/src/fun.c @@ -8358,6 +8358,8 @@ static Scheme_Object *continuation_prompt_available(int argc, Scheme_Object *arg JIT-generated code. The code here manages capture and restore for the runstack and mark stack, while the rest is in the JIT. */ +#ifdef MZ_USE_JIT + struct Scheme_Lightweight_Continuation { MZTAG_IF_REQUIRED /* scheme_rt_lightweight_cont */ Scheme_Current_LWC *saved_lwc; @@ -8639,6 +8641,12 @@ int scheme_push_marks_from_thread(Scheme_Thread *p2, Scheme_Cont_Frame_Data *d) return 0; } +#else + +void scheme_init_thread_lwc(void) XFORM_SKIP_PROC { } + +#endif + /*========================================================================*/ /* dynamic-wind */ /*========================================================================*/ From 9610515529af5eb128c9d46e70de3b15967c679d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 17 Oct 2010 08:53:44 -0600 Subject: [PATCH 007/746] fix 3m problem with --disable-jit and --disable-futures Merge to 5.0.2 (cherry picked from commit 68079d738d89324de0e4dfc1622a193239ab4b4f) --- src/racket/src/fun.c | 2 ++ src/racket/src/mzmark.c | 4 ++++ src/racket/src/mzmarksrc.c | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/src/racket/src/fun.c b/src/racket/src/fun.c index a32297bd88..81d136d461 100644 --- a/src/racket/src/fun.c +++ b/src/racket/src/fun.c @@ -9823,7 +9823,9 @@ static void register_traversers(void) GC_REG_TRAV(scheme_rt_dyn_wind_cell, mark_dyn_wind_cell); GC_REG_TRAV(scheme_rt_dyn_wind_info, mark_dyn_wind_info); GC_REG_TRAV(scheme_cont_mark_chain_type, mark_cont_mark_chain); +#ifdef MZ_USE_JIT GC_REG_TRAV(scheme_rt_lightweight_cont, mark_lightweight_cont); +#endif } END_XFORM_SKIP; diff --git a/src/racket/src/mzmark.c b/src/racket/src/mzmark.c index 01ad1b3693..15b3802ed4 100644 --- a/src/racket/src/mzmark.c +++ b/src/racket/src/mzmark.c @@ -3319,6 +3319,8 @@ static int mark_cont_mark_chain_FIXUP(void *p, struct NewGC *gc) { #define mark_cont_mark_chain_IS_CONST_SIZE 1 +#ifdef MZ_USE_JIT + static int mark_lightweight_cont_SIZE(void *p, struct NewGC *gc) { return gcBYTES_TO_WORDS(sizeof(Scheme_Lightweight_Continuation)); @@ -3352,6 +3354,8 @@ static int mark_lightweight_cont_FIXUP(void *p, struct NewGC *gc) { #define mark_lightweight_cont_IS_CONST_SIZE 1 +#endif + #endif /* FUN */ /**********************************************************************/ diff --git a/src/racket/src/mzmarksrc.c b/src/racket/src/mzmarksrc.c index 6c60c9aa24..cfd9d10e45 100644 --- a/src/racket/src/mzmarksrc.c +++ b/src/racket/src/mzmarksrc.c @@ -1336,6 +1336,8 @@ mark_cont_mark_chain { gcBYTES_TO_WORDS(sizeof(Scheme_Cont_Mark_Chain)); } +#ifdef MZ_USE_JIT + mark_lightweight_cont { mark: Scheme_Lightweight_Continuation *lw = (Scheme_Lightweight_Continuation *)p; @@ -1349,6 +1351,8 @@ mark_lightweight_cont { gcBYTES_TO_WORDS(sizeof(Scheme_Lightweight_Continuation)); } +#endif + END fun; /**********************************************************************/ From 81a6c4ff435429cd44e4ff65896200f1937511dd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 17 Oct 2010 19:20:18 -0700 Subject: [PATCH 008/746] fix problem with recursive prints in custom printers Merge to 5.0.2 (cherry picked from commit bb799ee9eea58f3ce3abb75b2aa4214277ae6a0f) --- src/racket/src/print.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/racket/src/print.c b/src/racket/src/print.c index a47332ea70..f7e5ce2dea 100644 --- a/src/racket/src/print.c +++ b/src/racket/src/print.c @@ -3983,7 +3983,6 @@ static void custom_write_struct(Scheme_Object *s, Scheme_Hash_Table *ht, a[1] = o; if (notdisplay >= 3) { a[2] = scheme_bin_plus(pp->depth_delta, scheme_make_integer(notdisplay - 3)); - pp->depth_delta = a[2]; } else a[2] = (notdisplay ? scheme_true : scheme_false); From 478425520f98d8608dbe2972a1151aa6ab63c73c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 17 Oct 2010 19:24:40 -0700 Subject: [PATCH 009/746] fix quotability annotation on HtDP-language structs Merge to 5.0.2 (cherry picked from commit 9f959f247ee12fabcab48796e5340198bbb9755e) --- collects/lang/private/teach.rkt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collects/lang/private/teach.rkt b/collects/lang/private/teach.rkt index ae4150420c..d5febf48df 100644 --- a/collects/lang/private/teach.rkt +++ b/collects/lang/private/teach.rkt @@ -824,6 +824,8 @@ #,@(map-with-index (lambda (i _) #`(recur (raw-generic-access r #,i))) fields)))) + (cons prop:custom-print-quotable + 'never) (cons prop:custom-write ;; Need a transparent-like printer, but hide auto field. ;; This simplest way to do that is to create an instance From ee41160d08cf5359ae50358b65ea9669dd069dce Mon Sep 17 00:00:00 2001 From: John Clements Date: Sun, 17 Oct 2010 18:10:27 -0700 Subject: [PATCH 010/746] exr -> expr (cherry picked from commit 9f7eeee570b70f24724a8aa1cd8eb486122952ef) --- collects/scribblings/reference/define-struct.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/reference/define-struct.scrbl b/collects/scribblings/reference/define-struct.scrbl index 75a963f651..06360bb868 100644 --- a/collects/scribblings/reference/define-struct.scrbl +++ b/collects/scribblings/reference/define-struct.scrbl @@ -21,7 +21,7 @@ (code:line #:inspector inspector-expr) (code:line #:auto-value auto-expr) (code:line #:guard guard-expr) - (code:line #:property prop-expr val-exr) + (code:line #:property prop-expr val-expr) (code:line #:transparent) (code:line #:prefab) (code:line #:constructor-name constructor-id) From 6772e78474d1aea2f7276443a789e3ef23877733 Mon Sep 17 00:00:00 2001 From: John Clements Date: Sun, 17 Oct 2010 20:13:34 -0700 Subject: [PATCH 011/746] r/exact-integer?/fixnum/ (cherry picked from commit bb160fbc043f4a6c7a69f0a024592c1160eaceb3) --- collects/scribblings/reference/hashes.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/reference/hashes.scrbl b/collects/scribblings/reference/hashes.scrbl index d9c592837c..07d8ac85fa 100644 --- a/collects/scribblings/reference/hashes.scrbl +++ b/collects/scribblings/reference/hashes.scrbl @@ -435,7 +435,7 @@ Returns a @tech{fixnum}; for any two calls with @scheme[eqv?] values, the returned number is the same.} -@defproc[(equal-hash-code [v any/c]) exact-integer?]{ +@defproc[(equal-hash-code [v any/c]) fixnum?]{ Returns a @tech{fixnum}; for any two calls with @scheme[equal?] values, the returned number is the same. A hash code is computed even when From ef2e9705395dc5c7fc8fb5c89df87332fc9a1cbf Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Mon, 18 Oct 2010 09:36:17 +0200 Subject: [PATCH 012/746] For DMdA, follow Robby's fix for htpd-langs.ss. Namely, don't set an uncaught-exception-handler. (cherry picked from commit 2a418b9cf0b8f7e2623d3987f92e9bb8d746dab9) --- collects/deinprogramm/deinprogramm-langs.rkt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/collects/deinprogramm/deinprogramm-langs.rkt b/collects/deinprogramm/deinprogramm-langs.rkt index 8758535a8c..d3c653b435 100644 --- a/collects/deinprogramm/deinprogramm-langs.rkt +++ b/collects/deinprogramm/deinprogramm-langs.rkt @@ -191,11 +191,6 @@ ;; hack: the test-engine code knows about the test~object name; we do, too (namespace-set-variable-value! 'test~object (build-test-engine)) - (uncaught-exception-handler - (let ((previous (uncaught-exception-handler))) - (lambda (exc) - (display-results) - (previous exc)))) ;; record signature violations with the test engine (signature-violation-proc (lambda (obj signature message blame) From 33d4a451b33d0f7b9e5eeb48c2f8f4a91a268299 Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Mon, 18 Oct 2010 09:37:48 +0200 Subject: [PATCH 013/746] Unbreak the test-engine-test.rkt test suite. - signatures are only in ASL now - the error messages for the DMdA languages are different (cherry picked from commit 32455894bce355f48e2159f3104a200afd4e9df9) --- collects/tests/drracket/test-engine-test.rkt | 42 +++++++++----------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/collects/tests/drracket/test-engine-test.rkt b/collects/tests/drracket/test-engine-test.rkt index a61d5fc111..3f4f9348ff 100644 --- a/collects/tests/drracket/test-engine-test.rkt +++ b/collects/tests/drracket/test-engine-test.rkt @@ -12,7 +12,7 @@ (define (set-language close-dialog?) (set-language-level! (language) close-dialog?)) -(define (common) +(define (common-test-engine) (test-expression "(check-expect 1 1)" "The test passed!" #:repl-expected "Both tests passed!") @@ -26,7 +26,7 @@ #:check-failures-expected (list (make-check-expect-failure "1" "2" 1 0)))) -(define (common-*sl) +(define (common-signatures-*sl) (test-expression "(: foo Integer) (define foo 5)" "" #:repl-expected "define: cannot redefine name: foo") @@ -36,13 +36,13 @@ #:signature-violations-expected (list (make-signature-violation "\"bar\"" 1 7)))) -(define (common-DMdA) +(define (common-signatures-DMdA) (test-expression "(: foo integer) (define foo 5)" "" - #:repl-expected "define: cannot redefine name: foo") + #:repl-expected "define: Zweite Definition für denselben Namen") (test-expression "(: foo integer) (define foo \"bar\")" "" - #:repl-expected "define: cannot redefine name: foo" + #:repl-expected "define: Zweite Definition für denselben Namen" #:signature-violations-expected (list (make-signature-violation "\"bar\"" 1 7)))) @@ -65,8 +65,7 @@ (define (beginner) (parameterize ([language (list "How to Design Programs" #rx"Beginning Student(;|$)")]) (prepare-for-test-expression) - (common) - (common-*sl))) + (common-test-engine))) ; @@ -89,8 +88,7 @@ (parameterize ([language (list "How to Design Programs" #rx"Beginning Student with List Abbreviations(;|$)")]) (prepare-for-test-expression) - (common) - (common-*sl))) + (common-test-engine))) ; @@ -112,8 +110,7 @@ (define (intermediate) (parameterize ([language (list "How to Design Programs" #rx"Intermediate Student(;|$)")]) (prepare-for-test-expression) - (common) - (common-*sl))) + (common-test-engine))) ; ; @@ -136,8 +133,7 @@ (parameterize ([language (list "How to Design Programs" #rx"Intermediate Student with lambda(;|$)")]) (prepare-for-test-expression) - (common) - (common-*sl))) + (common-test-engine))) ; @@ -160,33 +156,33 @@ (define (advanced) (parameterize ([language (list "How to Design Programs" #rx"Advanced Student(;|$)")]) (prepare-for-test-expression) - (common) - (common-*sl))) + (common-test-engine) + (common-signatures-*sl))) (define (DMdA-beginner) (parameterize ([language (list "DeinProgramm" #rx"Die Macht der Abstraktion - Anfänger(;|$)")]) (prepare-for-test-expression) - (common) - (common-DMdA))) + (common-test-engine) + (common-signatures-DMdA))) (define (DMdA-vanilla) (parameterize ([language (list "DeinProgramm" #rx"Die Macht der Abstraktion(;|$)")]) (prepare-for-test-expression) - (common) - (common-DMdA))) + (common-test-engine) + (common-signatures-DMdA))) (define (DMdA-assignments) (parameterize ([language (list "DeinProgramm" #rx"Die Macht der Abstraktion mit Zuweisungen(;|$)")]) (prepare-for-test-expression) - (common) - (common-DMdA))) + (common-test-engine) + (common-signatures-DMdA))) (define (DMdA-advanced) (parameterize ([language (list "DeinProgramm" #rx"Die Macht der Abstraktion - fortgeschritten(;|$)")]) (prepare-for-test-expression) - (common) - (common-DMdA))) + (common-test-engine) + (common-signatures-DMdA))) (define (prepare-for-test-expression) (let ([drs (wait-for-drscheme-frame)]) From c4766f1fafe06120896fd6dae87fe3ad29c6f798 Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Mon, 18 Oct 2010 10:00:49 +0200 Subject: [PATCH 014/746] Made sperber responsible for `test-engine-tests.rkt'. (cherry picked from commit 0821f694afffbc347644a210cda4327ace1c511d) --- collects/meta/props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/meta/props b/collects/meta/props index 7ac191972e..9cb417b48b 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -1411,7 +1411,7 @@ path/s is either such a string or a list of them. "collects/tests/drracket/teaching-lang-coverage.rkt" responsible (robby matthias) drdr:command-line (gracket *) "collects/tests/drracket/teaching-lang-save-file.rkt" responsible (robby matthias) drdr:command-line (gracket *) "collects/tests/drracket/teachpack.rkt" responsible (robby matthias) drdr:command-line (gracket *) -"collects/tests/drracket/test-engine-test.rkt" drdr:command-line (gracket *) +"collects/tests/drracket/test-engine-test.rkt" responsible (sperber) drdr:command-line (gracket *) drdr:timeout 240 "collects/tests/drracket/time-keystrokes.rkt" drdr:command-line (gracket-text "-t" *) "collects/tests/errortrace/alert.rkt" responsible (eli) "collects/tests/framework" responsible (robby) From 9146b803eed91742b19b6bdf50f8bafc9b541768 Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Mon, 18 Oct 2010 10:10:27 +0200 Subject: [PATCH 015/746] Don't annoy the user with test-engine summaries. Make sure the test-engine summary is only printed when there's something new to say. (cherry picked from commit 43d097cc05f25637abbd1a4f4dbc1f779c7aa778) --- collects/test-engine/test-engine.rkt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/collects/test-engine/test-engine.rkt b/collects/test-engine/test-engine.rkt index 3cc7fba2a4..d8b25f2562 100644 --- a/collects/test-engine/test-engine.rkt +++ b/collects/test-engine/test-engine.rkt @@ -126,6 +126,7 @@ (define display-rep #f) (define display-event-space #f) (define silent-mode #t) + (define test-run-since-last-display? #f) (super-instantiate ()) @@ -172,11 +173,13 @@ [(mixed-results) (display-results display-rep display-event-space)])))) (else - (display-disabled port)))) + (display-disabled port))) + (set! test-run-since-last-display? #f)) (define/private (display-success port event-space count) - (clear-results event-space) - (send test-display display-success-summary port count)) + (when test-run-since-last-display? + (clear-results event-space) + (send test-display display-success-summary port count))) (define/public (display-results rep event-space) (cond @@ -190,16 +193,19 @@ [else (send test-display display-results)])) (define/public (display-untested port) - (unless silent-mode - (send test-display display-untested-summary port))) + (when (and test-run-since-last-display? + (not silent-mode)) + (send test-display display-untested-summary port))) (define/public (display-disabled port) - (send test-display display-disabled-summary port)) + (when test-run-since-last-display? + (send test-display display-disabled-summary port))) (define/pubment (initialize-test test) (inner (void) initialize-test test)) (define/pubment (run-test test) + (set! test-run-since-last-display? #t) (inner (void) run-test test)) (define/pubment (run-testcase testcase) From c1746d7649a66a7cf462fc0fb17fd62b5daedfec Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Mon, 18 Oct 2010 13:30:34 +0200 Subject: [PATCH 016/746] Two more (hopefully last) renamings "Vertrag" -> "Signatur" (i.e. "contract" -> "signature" in German) (cherry picked from commit 17c4cb925461ab9a0a4f117bb17dc682b30420d7) --- collects/deinprogramm/scribblings/DMdA-beginner.scrbl | 2 +- collects/deinprogramm/signature/signature-syntax.rkt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/deinprogramm/scribblings/DMdA-beginner.scrbl b/collects/deinprogramm/scribblings/DMdA-beginner.scrbl index 7101baa3d5..5b3f51cf21 100644 --- a/collects/deinprogramm/scribblings/DMdA-beginner.scrbl +++ b/collects/deinprogramm/scribblings/DMdA-beginner.scrbl @@ -153,7 +153,7 @@ Diese Form liefert die Signatur mit der Notation @scheme[sig]. Diese Form erklärt @scheme[sig] zur gültigen Signatur für @scheme[id]. } -@subsection{Eingebaute Verträge} +@subsection{Eingebaute Signaturen} @defidform[number]{ Signatur für beliebige Zahlen. diff --git a/collects/deinprogramm/signature/signature-syntax.rkt b/collects/deinprogramm/signature/signature-syntax.rkt index bd5b66def5..e8962846ec 100644 --- a/collects/deinprogramm/signature/signature-syntax.rkt +++ b/collects/deinprogramm/signature/signature-syntax.rkt @@ -264,7 +264,7 @@ (define-for-syntax (within-signature-syntax-error stx name) (raise-syntax-error #f - "darf nur in Verträgen vorkommen" + "darf nur in Signaturen vorkommen" name)) ;; Expression -> Expression From 4965622a6395f0a26efff4878ad05a89e176983f Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 18 Oct 2010 08:40:50 -0600 Subject: [PATCH 017/746] Disabled redex test per Robby's request (no corresponding master commit) --- collects/redex/tests/tl-test.rkt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/collects/redex/tests/tl-test.rkt b/collects/redex/tests/tl-test.rkt index 3684c5d138..52543da215 100644 --- a/collects/redex/tests/tl-test.rkt +++ b/collects/redex/tests/tl-test.rkt @@ -549,7 +549,8 @@ (define-metafunction/extension f empty-language [(g any) 2]) (test (term (g 0)) 2)) - + + #: (let () (define-language L (v 1 (v))) @@ -2118,4 +2119,4 @@ (test-bad-equiv-arg test-->>)) (print-tests-passed 'tl-test.ss) - \ No newline at end of file + From d06ef8bc05135b4d3a7f6020c334285b240f6490 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 18 Oct 2010 13:45:10 -0700 Subject: [PATCH 018/746] fix non-inlined `in-vector' sequence on proxied vectors Merge to 5.0.2 Closes PR 11225 (cherry picked from commit ddca8cd29b005701fb49377521ffe8909ec20a0b) --- collects/racket/private/for.rkt | 2 +- collects/tests/racket/for.rktl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/racket/private/for.rkt b/collects/racket/private/for.rkt index 1fd601a8c8..654425ab3a 100644 --- a/collects/racket/private/for.rkt +++ b/collects/racket/private/for.rkt @@ -420,7 +420,7 @@ (define (:vector-gen v start stop step) (values ;; pos->element - (lambda (i) (unsafe-vector-ref v i)) + (lambda (i) (unsafe-vector*-ref v i)) ;; next-pos ;; Minor optimisation. I assume add1 is faster than \x.x+1 (if (= step 1) add1 (lambda (i) (+ i step))) diff --git a/collects/tests/racket/for.rktl b/collects/tests/racket/for.rktl index bcd35ec4ba..d03c478227 100644 --- a/collects/tests/racket/for.rktl +++ b/collects/tests/racket/for.rktl @@ -110,6 +110,7 @@ (test-generator [(a b c)] (in-mlist (mlist 'a 'b 'c))) (test-generator [(a b c)] #(a b c)) (test-generator [(a b c)] (in-vector #(a b c))) +(test-generator [(a b c)] (in-vector (chaperone-vector #(a b c) (lambda (vec i val) val) (lambda (vec i val) val)))) (test-generator [(b c d)] (in-vector #(a b c d) 1)) (test-generator [(b c d)] (in-vector #(a b c d e) 1 4)) (test-generator [(b d f)] (in-vector #(a b c d e f g h) 1 7 2)) From 8007ba625691b77e0f175ee3fe8198268a1987fe Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Tue, 19 Oct 2010 11:56:24 +0200 Subject: [PATCH 019/746] Unbreak the stepper on `check-expect'. All kinds of things expand into (let () ...), so all kinds of things break. (cherry picked from commit fd5e9d4d6342933f0973b080a1bbf28c60107f1f) --- collects/test-engine/racket-tests.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/test-engine/racket-tests.rkt b/collects/test-engine/racket-tests.rkt index f2154c25e2..9a9ca79375 100644 --- a/collects/test-engine/racket-tests.rkt +++ b/collects/test-engine/racket-tests.rkt @@ -106,7 +106,7 @@ #'test-engine)))))))) 'stepper-skipto (append skipto/third ;; let - skipto/third skipto/second ;; unless (it expands into a begin) + skipto/third skipto/third ;; unless (it expands into (if (let-values () ...)) skipto/cdr skipto/third ;; application of insert-test '(syntax-e cdr cdr syntax-e car) ;; lambda ))) From 754dde06117d1eb428e6ae616b30a438b6d90467 Mon Sep 17 00:00:00 2001 From: John Clements Date: Tue, 19 Oct 2010 11:42:39 -0700 Subject: [PATCH 020/746] got testing harness working again. (cherry picked from commit 2083181d2e964f7c130b96ad5fa15647e695802c) --- collects/tests/stepper/automatic-tests.rkt | 4 +- collects/tests/stepper/test-engine.rkt | 20 ++-- collects/tests/stepper/through-tests.rkt | 133 +++++++++++---------- 3 files changed, 89 insertions(+), 68 deletions(-) diff --git a/collects/tests/stepper/automatic-tests.rkt b/collects/tests/stepper/automatic-tests.rkt index 638b280cc3..4474909648 100644 --- a/collects/tests/stepper/automatic-tests.rkt +++ b/collects/tests/stepper/automatic-tests.rkt @@ -1,7 +1,8 @@ #lang scheme (require "through-tests.ss" - "test-engine.ss") + "test-engine.ss" + test-engine/racket-tests) (let ((outer-namespace (current-namespace))) (parameterize ([display-only-errors #t] @@ -9,6 +10,7 @@ [current-namespace (make-base-namespace)]) ;; make sure the tests' print-convert sees the teaching languages' properties (namespace-attach-module outer-namespace 'mzlib/pconvert-prop (current-namespace)) + (namespace-require 'test-engine/racket-tests) (if (run-all-tests-except '(bad-and bad-cons check-error begin-let-bug prims qq-splice time set! local-set! lazy1 lazy2 lazy3 local-struct/i local-struct/ilam)) (exit 0) diff --git a/collects/tests/stepper/test-engine.rkt b/collects/tests/stepper/test-engine.rkt index 7ae23940f2..cc221f1509 100644 --- a/collects/tests/stepper/test-engine.rkt +++ b/collects/tests/stepper/test-engine.rkt @@ -183,14 +183,20 @@ (error-display-handler current-error-display-handler))) ;; call-iter-on-each : (-> syntax?) (syntax? (-> 'a) -> 'a) -> void/c -;; call the given iter on each syntax in turn (iter bounces control) -;; back to us by calling the followup-thunk. +;; call the given iter on each syntax in turn (iter bounces control +;; back to us by calling the followup-thunk). (define (call-iter-on-each stx-thunk iter) - (let* ([next (stx-thunk)] - [followup-thunk (if (eof-object? next) void (lambda () (call-iter-on-each stx-thunk iter)))] - [expanded (expand next)]) - ;;(printf "~v\n" expanded) - (iter expanded followup-thunk))) + (parameterize ([current-namespace (make-base-empty-namespace)]) + (namespace-require 'racket/base) + (namespace-require 'test-engine/racket-tests) + ;; make the test engine happy by adding a binding for test~object: + (namespace-set-variable-value! 'test~object #f) + (let iter-loop () + (let* ([next (stx-thunk)] + [followup-thunk (if (eof-object? next) void iter-loop)] + [expanded (expand next)]) + ;;(printf "~v\n" expanded) + (iter expanded followup-thunk))))) (define (warn error-box who fmt . args) diff --git a/collects/tests/stepper/through-tests.rkt b/collects/tests/stepper/through-tests.rkt index c0086856ca..9d31565cdb 100755 --- a/collects/tests/stepper/through-tests.rkt +++ b/collects/tests/stepper/through-tests.rkt @@ -14,7 +14,7 @@ ) -(provide run-test run-tests run-all-tests run-all-tests-except) +(provide run-test run-tests/s run-all-tests run-all-tests-except) (define list-of-tests null) @@ -57,7 +57,7 @@ (run-one-test/helper maybe-test) (error 'run-test "test not found: ~.s" name)))) -(define (run-tests names) +(define (run-tests/s names) (ormap/no-shortcut run-test names)) @@ -68,12 +68,7 @@ (define (andmap/no-shortcut f args) (foldl (lambda (a b) (and a b)) #t (map f args))) -(t 'mz1 m:mz - (for-each (lambda (x) x) '(1 2 3)) - :: {(for-each (lambda (x) x) `(1 2 3))} -> (... {1} ...) - :: ... -> (... {2} ...) - :: ... -> (... {3} ...) - :: ... -> {(void)}) + ;; new test case language: ;; an expected is (listof step) @@ -105,17 +100,12 @@ ;; * a `finished-stepping' is added if no error was specified ;; * a `{...}' is replaced with `(hilite ...)' -(t 'mz-app m:mz - (+ 3 4) - :: {(+ 3 4)} -> {7}) - -(t 'mz-app2 m:mz - ((lambda (x) (+ x 3)) 4) - :: {((lambda (x) (+ x 3)) 4)} -> {(+ 4 3)} -> {7}) - -(t 'mz-if m:mz - (if 3 4 5) - :: {(if 3 4 5)} -> {4}) + (t 'mz1 m:mz + (for-each (lambda (x) x) '(1 2 3)) + :: {(for-each (lambda (x) x) `(1 2 3))} -> (... {1} ...) + :: ... -> (... {2} ...) + :: ... -> (... {3} ...) + :: ... -> {(void)}) (t 'simple-if m:upto-int/lam (if true false true) @@ -126,44 +116,6 @@ :: (if {(if true false true)} false true) -> (if {false} false true) :: {(if false false true)} -> {true}) -(t 'direct-app m:mz - ((lambda (x) x) 3) - :: {((lambda (x) x) 3)} -> {3}) - -; (m:mz "((lambda (x) x) (begin (+ 3 4) (+ 4 5)))" -; `((before-after ((begin (hilite (+ 3 4)) (+ 4 5))) -; ((begin (hilite 7) (+ 4 5)))) -; (before-after ((hilite (begin 7 (+ 4 5)))) ((hilite (+ 4 5)))) -; (before-after ((hilite (+ 4 5))) ((hilite 9))) -; (finished-stepping))) - -(t 'curried m:mz - ((lambda (a) (lambda (b) (+ a b))) 14) - :: {((lambda (a) (lambda (b) (+ a b))) 14)} - -> {(lambda (b) (+ 14 b))}) - -(t 'case-lambda m:mz - ((case-lambda ((a) 3) ((b c) (+ b c))) 5 6) - :: {((case-lambda ((a) 3) ((b c) (+ b c))) 5 6)} - -> {(+ 5 6)} - -> {11}) - -;; not really a part of base mzscheme anymore -#;(t '2armed-if m:mz - (if 3 4) - :: {(if 3 4)} -> {4}) - -;(m:mz "((call-with-current-continuation call-with-current-continuation) (call-with-current-continuation call-with-current-continuation))" -; `((before-after (((hilite ,h-p) (call-with-current-continuation call-with-current-continuation))) ((call-with-current-continuation call-with-current-continuation)) -; (((hilite ,h-p) (call-with-current-continuation call-with-current-continuation))) ((lambda args ...))) -; (before-after (((lambda args ...) (hilite ,h-p))) ((call-with-current-continuation call-with-current-continuation)) -; (((lambda args ...) (hilite ,h-p))) ((lambda args ...))))) - -;(m:mz '(begin (define g 3) g) -; `((before-after ((hilite ,h-p)) (g) -; ((hilite ,h-p)) 3))) - -;(syntax-object->datum (cadr (annotate-expr test2 'mzscheme 0 (lambda (x) x)))) (t 'top-def m:upto-int/lam (define a (+ 3 4)) @@ -1464,8 +1416,69 @@ -> (define (f x) (local ((define-struct a (b c))) x)) {(define-struct a_1 (b c))} {1}) - + ;; oh dear heavens; putting these tests early on seems to "mess up" the namespace + ;; so that test~object can't be seen by the teaching-language tests. This is almost + ;; certainly the stepper test framework doing something stupid. + #;(t 'mz1 m:mz + (for-each (lambda (x) x) '(1 2 3)) + :: {(for-each (lambda (x) x) `(1 2 3))} -> (... {1} ...) + :: ... -> (... {2} ...) + :: ... -> (... {3} ...) + :: ... -> {(void)}) + +(t 'mz-app m:mz + (+ 3 4) + :: {(+ 3 4)} -> {7}) + +(t 'mz-app2 m:mz + ((lambda (x) (+ x 3)) 4) + :: {((lambda (x) (+ x 3)) 4)} -> {(+ 4 3)} -> {7}) + +(t 'mz-if m:mz + (if 3 4 5) + :: {(if 3 4 5)} -> {4}) + +(t 'direct-app m:mz + ((lambda (x) x) 3) + :: {((lambda (x) x) 3)} -> {3}) + +; (m:mz "((lambda (x) x) (begin (+ 3 4) (+ 4 5)))" +; `((before-after ((begin (hilite (+ 3 4)) (+ 4 5))) +; ((begin (hilite 7) (+ 4 5)))) +; (before-after ((hilite (begin 7 (+ 4 5)))) ((hilite (+ 4 5)))) +; (before-after ((hilite (+ 4 5))) ((hilite 9))) +; (finished-stepping))) + +(t 'curried m:mz + ((lambda (a) (lambda (b) (+ a b))) 14) + :: {((lambda (a) (lambda (b) (+ a b))) 14)} + -> {(lambda (b) (+ 14 b))}) + +(t 'case-lambda m:mz + ((case-lambda ((a) 3) ((b c) (+ b c))) 5 6) + :: {((case-lambda ((a) 3) ((b c) (+ b c))) 5 6)} + -> {(+ 5 6)} + -> {11}) + +;; not really a part of base mzscheme anymore +#;(t '2armed-if m:mz + (if 3 4) + :: {(if 3 4)} -> {4}) + +;(m:mz "((call-with-current-continuation call-with-current-continuation) (call-with-current-continuation call-with-current-continuation))" +; `((before-after (((hilite ,h-p) (call-with-current-continuation call-with-current-continuation))) ((call-with-current-continuation call-with-current-continuation)) +; (((hilite ,h-p) (call-with-current-continuation call-with-current-continuation))) ((lambda args ...))) +; (before-after (((lambda args ...) (hilite ,h-p))) ((call-with-current-continuation call-with-current-continuation)) +; (((lambda args ...) (hilite ,h-p))) ((lambda args ...))))) + +;(m:mz '(begin (define g 3) g) +; `((before-after ((hilite ,h-p)) (g) +; ((hilite ,h-p)) 3))) + +;(syntax-object->datum (cadr (annotate-expr test2 'mzscheme 0 (lambda (x) x)))) + + ;; run whatever tests are enabled (intended for interactive use): (define (ggg) (parameterize (#;[disable-stepper-error-handling #t] @@ -1474,8 +1487,8 @@ #;[show-all-steps #t]) #;(run-tests '(check-expect forward-ref check-within check-within-bad check-error check-error-bad)) #;(run-tests '(teachpack-universe)) - (run-tests '(local-struct/i local-struct/ilam)) - #;(run-all-tests))) + (run-all-tests) + #;(run-test 'simple-if))) From 5f7993c6db978d502e3f393557d4e8a43b3fd7a7 Mon Sep 17 00:00:00 2001 From: John Clements Date: Tue, 19 Oct 2010 17:42:11 -0700 Subject: [PATCH 021/746] looks like a fix for cond (cherry picked from commit 0536d52efd294638a06ad29e2e92027d777cd78b) --- collects/tests/stepper/automatic-tests.rkt | 3 +- collects/tests/stepper/test-engine.rkt | 21 ---- collects/tests/stepper/through-tests.rkt | 129 +++++++++------------ 3 files changed, 58 insertions(+), 95 deletions(-) diff --git a/collects/tests/stepper/automatic-tests.rkt b/collects/tests/stepper/automatic-tests.rkt index 4474909648..b7327a177d 100644 --- a/collects/tests/stepper/automatic-tests.rkt +++ b/collects/tests/stepper/automatic-tests.rkt @@ -1,8 +1,7 @@ #lang scheme (require "through-tests.ss" - "test-engine.ss" - test-engine/racket-tests) + "test-engine.ss") (let ((outer-namespace (current-namespace))) (parameterize ([display-only-errors #t] diff --git a/collects/tests/stepper/test-engine.rkt b/collects/tests/stepper/test-engine.rkt index cc221f1509..8757dbca38 100644 --- a/collects/tests/stepper/test-engine.rkt +++ b/collects/tests/stepper/test-engine.rkt @@ -6,7 +6,6 @@ lang/run-teaching-program (only-in srfi/13 string-contains) scheme/contract - #;(file "/Users/clements/clements/scheme-scraps/eli-debug.ss") "language-level-model.ss") @@ -93,11 +92,6 @@ ;; run the named test, return #t if a failure occurred during the test. -;; WARNING: evaluating code expanded using run-teaching-program causes mutation of the -;; current namespace. Unfortunately, wrapping a parameterize around each test (i.e., in this -;; file) causes unacceptable slowdown and severe weirdness. I tried saving and restoring -;; the namespace through mutation, and got severe weirdness again. - (define (run-one-test name models exp-str expected-steps) (unless (display-only-errors) (printf "running test: ~v\n" name)) @@ -270,20 +264,5 @@ -;; DEBUGGING TO TRY TO FIND OUT WHY THIS DOESN'T WORK IN AN AUTOMATED TESTER: -;; test-sequence : ll-model? string? steps? -> (void) -;; given a language model and an expression and a sequence of steps, -;; check to see whether the stepper produces the desired steps -;;define (test-sequence the-ll-model exp-str expected-steps error-box) -#;(match mz - [(struct ll-model (namespace-spec teachpack-specs render-settings show-lambdas-as-lambdas? enable-testing?)) - (let* ([p2 (open-input-string "134")] - [module-id (gensym "stepper-module-name-")] - ;; thunk this so that syntax errors happen within the error handlers: - [expanded-thunk - (lambda () (expand-teaching-program p2 read-syntax namespace-spec teachpack-specs #f module-id enable-testing?))]) - (display (expanded-thunk)) - (test-sequence/core render-settings show-lambdas-as-lambdas? expanded-thunk '() (box #f)))]) - diff --git a/collects/tests/stepper/through-tests.rkt b/collects/tests/stepper/through-tests.rkt index 9d31565cdb..9f1b29a3ca 100755 --- a/collects/tests/stepper/through-tests.rkt +++ b/collects/tests/stepper/through-tests.rkt @@ -14,7 +14,7 @@ ) -(provide run-test run-tests/s run-all-tests run-all-tests-except) +(provide run-test run-tests run-all-tests run-all-tests-except) (define list-of-tests null) @@ -57,7 +57,7 @@ (run-one-test/helper maybe-test) (error 'run-test "test not found: ~.s" name)))) -(define (run-tests/s names) +(define (run-tests names) (ormap/no-shortcut run-test names)) @@ -107,6 +107,59 @@ :: ... -> (... {3} ...) :: ... -> {(void)}) +(t 'mz-app m:mz + (+ 3 4) + :: {(+ 3 4)} -> {7}) + +(t 'mz-app2 m:mz + ((lambda (x) (+ x 3)) 4) + :: {((lambda (x) (+ x 3)) 4)} -> {(+ 4 3)} -> {7}) + +(t 'mz-if m:mz + (if 3 4 5) + :: {(if 3 4 5)} -> {4}) + +(t 'direct-app m:mz + ((lambda (x) x) 3) + :: {((lambda (x) x) 3)} -> {3}) + +; (m:mz "((lambda (x) x) (begin (+ 3 4) (+ 4 5)))" +; `((before-after ((begin (hilite (+ 3 4)) (+ 4 5))) +; ((begin (hilite 7) (+ 4 5)))) +; (before-after ((hilite (begin 7 (+ 4 5)))) ((hilite (+ 4 5)))) +; (before-after ((hilite (+ 4 5))) ((hilite 9))) +; (finished-stepping))) + +(t 'curried m:mz + ((lambda (a) (lambda (b) (+ a b))) 14) + :: {((lambda (a) (lambda (b) (+ a b))) 14)} + -> {(lambda (b) (+ 14 b))}) + +(t 'case-lambda m:mz + ((case-lambda ((a) 3) ((b c) (+ b c))) 5 6) + :: {((case-lambda ((a) 3) ((b c) (+ b c))) 5 6)} + -> {(+ 5 6)} + -> {11}) + +;; not really a part of base mzscheme anymore +#;(t '2armed-if m:mz + (if 3 4) + :: {(if 3 4)} -> {4}) + +;(m:mz "((call-with-current-continuation call-with-current-continuation) (call-with-current-continuation call-with-current-continuation))" +; `((before-after (((hilite ,h-p) (call-with-current-continuation call-with-current-continuation))) ((call-with-current-continuation call-with-current-continuation)) +; (((hilite ,h-p) (call-with-current-continuation call-with-current-continuation))) ((lambda args ...))) +; (before-after (((lambda args ...) (hilite ,h-p))) ((call-with-current-continuation call-with-current-continuation)) +; (((lambda args ...) (hilite ,h-p))) ((lambda args ...))))) + +;(m:mz '(begin (define g 3) g) +; `((before-after ((hilite ,h-p)) (g) +; ((hilite ,h-p)) 3))) + +;(syntax-object->datum (cadr (annotate-expr test2 'mzscheme 0 (lambda (x) x)))) + + + (t 'simple-if m:upto-int/lam (if true false true) :: {(if true false true)} -> {false}) @@ -1416,69 +1469,7 @@ -> (define (f x) (local ((define-struct a (b c))) x)) {(define-struct a_1 (b c))} {1}) - ;; oh dear heavens; putting these tests early on seems to "mess up" the namespace - ;; so that test~object can't be seen by the teaching-language tests. This is almost - ;; certainly the stepper test framework doing something stupid. - - #;(t 'mz1 m:mz - (for-each (lambda (x) x) '(1 2 3)) - :: {(for-each (lambda (x) x) `(1 2 3))} -> (... {1} ...) - :: ... -> (... {2} ...) - :: ... -> (... {3} ...) - :: ... -> {(void)}) - -(t 'mz-app m:mz - (+ 3 4) - :: {(+ 3 4)} -> {7}) - -(t 'mz-app2 m:mz - ((lambda (x) (+ x 3)) 4) - :: {((lambda (x) (+ x 3)) 4)} -> {(+ 4 3)} -> {7}) - -(t 'mz-if m:mz - (if 3 4 5) - :: {(if 3 4 5)} -> {4}) - -(t 'direct-app m:mz - ((lambda (x) x) 3) - :: {((lambda (x) x) 3)} -> {3}) - -; (m:mz "((lambda (x) x) (begin (+ 3 4) (+ 4 5)))" -; `((before-after ((begin (hilite (+ 3 4)) (+ 4 5))) -; ((begin (hilite 7) (+ 4 5)))) -; (before-after ((hilite (begin 7 (+ 4 5)))) ((hilite (+ 4 5)))) -; (before-after ((hilite (+ 4 5))) ((hilite 9))) -; (finished-stepping))) - -(t 'curried m:mz - ((lambda (a) (lambda (b) (+ a b))) 14) - :: {((lambda (a) (lambda (b) (+ a b))) 14)} - -> {(lambda (b) (+ 14 b))}) - -(t 'case-lambda m:mz - ((case-lambda ((a) 3) ((b c) (+ b c))) 5 6) - :: {((case-lambda ((a) 3) ((b c) (+ b c))) 5 6)} - -> {(+ 5 6)} - -> {11}) - -;; not really a part of base mzscheme anymore -#;(t '2armed-if m:mz - (if 3 4) - :: {(if 3 4)} -> {4}) - -;(m:mz "((call-with-current-continuation call-with-current-continuation) (call-with-current-continuation call-with-current-continuation))" -; `((before-after (((hilite ,h-p) (call-with-current-continuation call-with-current-continuation))) ((call-with-current-continuation call-with-current-continuation)) -; (((hilite ,h-p) (call-with-current-continuation call-with-current-continuation))) ((lambda args ...))) -; (before-after (((lambda args ...) (hilite ,h-p))) ((call-with-current-continuation call-with-current-continuation)) -; (((lambda args ...) (hilite ,h-p))) ((lambda args ...))))) - -;(m:mz '(begin (define g 3) g) -; `((before-after ((hilite ,h-p)) (g) -; ((hilite ,h-p)) 3))) - -;(syntax-object->datum (cadr (annotate-expr test2 'mzscheme 0 (lambda (x) x)))) - - + ;; run whatever tests are enabled (intended for interactive use): (define (ggg) (parameterize (#;[disable-stepper-error-handling #t] @@ -1488,10 +1479,4 @@ #;(run-tests '(check-expect forward-ref check-within check-within-bad check-error check-error-bad)) #;(run-tests '(teachpack-universe)) (run-all-tests) - #;(run-test 'simple-if))) - - - - - - + #;(run-tests '(cond1)))) From c05b501f1be3f12b0b4a8f68f44ff02859da37d3 Mon Sep 17 00:00:00 2001 From: John Clements Date: Tue, 19 Oct 2010 17:45:43 -0700 Subject: [PATCH 022/746] may have fixed cond in stepper tests (cherry picked from commit 60dabc8ad710f6c81bf169b9cb5a900e2656113e) --- collects/stepper/private/annotate.rkt | 61 ++++++++++++----------- collects/stepper/private/macro-unwind.rkt | 4 +- collects/stepper/private/reconstruct.rkt | 3 +- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/collects/stepper/private/annotate.rkt b/collects/stepper/private/annotate.rkt index 984685dced..cf3e89998c 100644 --- a/collects/stepper/private/annotate.rkt +++ b/collects/stepper/private/annotate.rkt @@ -146,36 +146,37 @@ [rewritten - (kernel:kernel-syntax-case stx #f - - ; cond : - [(if test (begin then) else-stx) - (let ([origin (syntax-property stx 'origin)] - [rebuild-if - (lambda (new-cond-test) - (let* ([new-then (recur-regular (syntax then))] - [rebuilt (stepper-syntax-property - (rebuild-stx `(if ,(recur-regular (syntax test)) - ,new-then - ,(recur-in-cond (syntax else-stx) new-cond-test)) - stx) - 'stepper-hint - 'comes-from-cond)]) - ; move the stepper-else mark to the if, if it's present: - (if (stepper-syntax-property (syntax test) 'stepper-else) - (stepper-syntax-property rebuilt 'stepper-else #t) - rebuilt)))]) - (cond [(cond-test stx) ; continuing an existing 'cond' - (rebuild-if cond-test)] - [(and origin (pair? origin) (eq? (syntax-e (car origin)) 'cond)) ; starting a new 'cond' - (rebuild-if (lambda (test-stx) - (and (eq? (syntax-source stx) (syntax-source test-stx)) - (eq? (syntax-position stx) (syntax-position test-stx)))))] - [else ; not from a 'cond' at all. - (rebuild-stx `(if ,@(map recur-regular (list (syntax test) (syntax (begin then)) (syntax else-stx)))) stx)]))] - [(begin body) ; else clauses of conds; ALWAYS AN ERROR CALL - (cond-test stx) - (stepper-syntax-property stx 'stepper-skip-completely #t)] + (kernel:kernel-syntax-case + stx + #f + ; cond : + [(#%if test (#%let () then) else-stx) + (let ([origin (syntax-property stx 'origin)] + [rebuild-if + (lambda (new-cond-test) + (let* ([new-then (recur-regular (syntax then))] + [rebuilt (stepper-syntax-property + (rebuild-stx `(if ,(recur-regular (syntax test)) + ,new-then + ,(recur-in-cond (syntax else-stx) new-cond-test)) + stx) + 'stepper-hint + 'comes-from-cond)]) + ; move the stepper-else mark to the if, if it's present: + (if (stepper-syntax-property (syntax test) 'stepper-else) + (stepper-syntax-property rebuilt 'stepper-else #t) + rebuilt)))]) + (cond [(cond-test stx) ; continuing an existing 'cond' + (rebuild-if cond-test)] + [(and origin (pair? origin) (eq? (syntax-e (car origin)) 'cond)) ; starting a new 'cond' + (rebuild-if (lambda (test-stx) + (and (eq? (syntax-source stx) (syntax-source test-stx)) + (eq? (syntax-position stx) (syntax-position test-stx)))))] + [else ; not from a 'cond' at all. + (rebuild-stx `(if ,@(map recur-regular (list (syntax test) (syntax (begin then)) (syntax else-stx)))) stx)]))] + [(begin body) ; else clauses of conds; ALWAYS AN ERROR CALL + (cond-test stx) + (stepper-syntax-property stx 'stepper-skip-completely #t)] ; wrapper on a local. This is necessary because teach.ss expands local into a trivial let wrapping a bunch of ; internal defines, and therefore the letrec-values on which I want to hang the 'stepper-hint doesn't yet diff --git a/collects/stepper/private/macro-unwind.rkt b/collects/stepper/private/macro-unwind.rkt index abc58e0144..f22d813b51 100644 --- a/collects/stepper/private/macro-unwind.rkt +++ b/collects/stepper/private/macro-unwind.rkt @@ -244,7 +244,7 @@ (syntax-property stx 'user-source)) (eq? user-position (syntax-property stx 'user-position))) - (syntax-case stx (if begin) + (syntax-case stx (if begin let-values) ;; the else clause disappears when it's a ;; language-inserted else clause [(if test result) @@ -254,7 +254,7 @@ (loop (syntax else-clause)))] ;; else clause appears momentarily in 'before,' even ;; though it's a 'skip-completely' - [(begin . rest) null] + [(let-values () . rest) null] [else-stx (error 'unwind-cond "expected an if, got: ~.s" diff --git a/collects/stepper/private/reconstruct.rkt b/collects/stepper/private/reconstruct.rkt index 927f6d9e5c..45bfada54f 100644 --- a/collects/stepper/private/reconstruct.rkt +++ b/collects/stepper/private/reconstruct.rkt @@ -13,8 +13,7 @@ "model-settings.ss" "shared.ss" "my-macros.ss" - (for-syntax scheme/base) - #;(file "/Users/clements/clements/scheme-scraps/eli-debug.ss")) + (for-syntax scheme/base)) (provide/contract [reconstruct-completed (syntax? From 0ed9334cc1c09f20c1656794865cba0730b0383d Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 19 Oct 2010 21:06:32 -0400 Subject: [PATCH 023/746] Fix rendering in local build mode -- make it create file:// urls when insisting on an absolute url (currently happens only in the tr pages). (cherry picked from commit 1e2d4b816946b9ab94c572ac5bae53d688bc4ed8) --- collects/meta/web/html/resource.rkt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/collects/meta/web/html/resource.rkt b/collects/meta/web/html/resource.rkt index 0a95328d43..54632f4eaa 100644 --- a/collects/meta/web/html/resource.rkt +++ b/collects/meta/web/html/resource.rkt @@ -47,10 +47,10 @@ (define cached-roots '(#f . #f)) (define (current-url-roots) - ;; takes in a (listof (list prefix-string url-string . flags)), and produces - ;; an alist with lists of strings for the keys; the prefix-strings are split - ;; on "/"s, and the url-strings can be anything at all actually (they are put - ;; as-is before the path with a "/" between them). + ;; takes `url-roots', a (listof (list prefix-string url-string . flags)), and + ;; produces an alist with lists of strings for the keys; the prefix-strings + ;; are split on "/"s, and the url-strings can be anything at all actually + ;; (they are put as-is before the path with a "/" between them). (let ([roots (url-roots)]) (unless (eq? roots (car cached-roots)) (set! cached-roots @@ -86,7 +86,7 @@ ;; find shared prefix [(and (pair? t) (pair? c) (equal? (car t) (car c))) (loop (cdr t) (cdr c) (cons (car t) pfx))] - ;; done + ;; done with the shared prefix, deal with the root now ;; no roots => always use a relative path (useful for debugging) [(not roots) `(,@(map (lambda (_) "..") c) ,@t ,file*)] ;; share a root => use a relative path unless its an absolute root @@ -197,7 +197,13 @@ (printf " ~a\n" path) (renderer filename)))))) (define (url) (relativize filename dirpathlist (rendered-dirpath))) - (define absolute-url (delay (relativize filename dirpathlist ""))) + (define absolute-url + (delay (let ([url (relativize filename dirpathlist '())]) + (if (url-roots) + url + ;; we're in local build mode, and insist on an absolute url, + ;; so construct a `file://' result + (list* "file://" (current-directory) url))))) (add-renderer path render) (make-keyword-procedure (lambda (kws kvs . args) (keyword-apply referrer kws kvs (url) args)) From c8b04e77b26041a3b5476cb52bd93fb609da8b98 Mon Sep 17 00:00:00 2001 From: John Clements Date: Tue, 19 Oct 2010 23:28:45 -0700 Subject: [PATCH 024/746] copied 'mzlib/convert-prop attachment from outer layer to inner layer. (cherry picked from commit 70898379c5df85d8c67db0aa95370f9a984664a9) --- collects/tests/stepper/automatic-tests.rkt | 2 +- collects/tests/stepper/test-engine.rkt | 12 +++++++++--- collects/tests/stepper/through-tests.rkt | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/collects/tests/stepper/automatic-tests.rkt b/collects/tests/stepper/automatic-tests.rkt index b7327a177d..45cd396d46 100644 --- a/collects/tests/stepper/automatic-tests.rkt +++ b/collects/tests/stepper/automatic-tests.rkt @@ -8,7 +8,7 @@ [current-output-port (open-output-string)] [current-namespace (make-base-namespace)]) ;; make sure the tests' print-convert sees the teaching languages' properties - (namespace-attach-module outer-namespace 'mzlib/pconvert-prop (current-namespace)) + #;(namespace-attach-module outer-namespace 'mzlib/pconvert-prop (current-namespace)) (namespace-require 'test-engine/racket-tests) (if (run-all-tests-except '(bad-and bad-cons check-error begin-let-bug prims qq-splice time set! local-set! lazy1 lazy2 lazy3 local-struct/i local-struct/ilam)) diff --git a/collects/tests/stepper/test-engine.rkt b/collects/tests/stepper/test-engine.rkt index 8757dbca38..b8720a4655 100644 --- a/collects/tests/stepper/test-engine.rkt +++ b/collects/tests/stepper/test-engine.rkt @@ -176,12 +176,18 @@ (disable-stepper-error-handling)))) (error-display-handler current-error-display-handler))) +(define-namespace-anchor n-anchor) + ;; call-iter-on-each : (-> syntax?) (syntax? (-> 'a) -> 'a) -> void/c ;; call the given iter on each syntax in turn (iter bounces control ;; back to us by calling the followup-thunk). (define (call-iter-on-each stx-thunk iter) - (parameterize ([current-namespace (make-base-empty-namespace)]) - (namespace-require 'racket/base) + (let ([ns (make-base-namespace)]) + ;; gets structures to print correctly. Copied from fix in command-line tests. + (namespace-attach-module (namespace-anchor->empty-namespace n-anchor) + 'mzlib/pconvert-prop + ns) + (parameterize ([current-namespace ns]) (namespace-require 'test-engine/racket-tests) ;; make the test engine happy by adding a binding for test~object: (namespace-set-variable-value! 'test~object #f) @@ -190,7 +196,7 @@ [followup-thunk (if (eof-object? next) void iter-loop)] [expanded (expand next)]) ;;(printf "~v\n" expanded) - (iter expanded followup-thunk))))) + (iter expanded followup-thunk)))))) (define (warn error-box who fmt . args) diff --git a/collects/tests/stepper/through-tests.rkt b/collects/tests/stepper/through-tests.rkt index 9f1b29a3ca..193a007b98 100755 --- a/collects/tests/stepper/through-tests.rkt +++ b/collects/tests/stepper/through-tests.rkt @@ -1478,5 +1478,5 @@ #;[show-all-steps #t]) #;(run-tests '(check-expect forward-ref check-within check-within-bad check-error check-error-bad)) #;(run-tests '(teachpack-universe)) - (run-all-tests) - #;(run-tests '(cond1)))) + #;(run-all-tests) + (run-tests '(check-expect)))) From 3b23f247152230fb1feb7d79696478c9ef2dc600 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 20 Oct 2010 14:31:52 -0400 Subject: [PATCH 025/746] Fix opt-lambda:. Merge to 5.0.2. (cherry picked from commit a15236ea4f1ba84c9351632e9469e1cd34b5375b) --- collects/tests/typed-scheme/succeed/opt-lambda.rkt | 9 +++++++++ collects/typed-scheme/private/prims.rkt | 1 + 2 files changed, 10 insertions(+) create mode 100644 collects/tests/typed-scheme/succeed/opt-lambda.rkt diff --git a/collects/tests/typed-scheme/succeed/opt-lambda.rkt b/collects/tests/typed-scheme/succeed/opt-lambda.rkt new file mode 100644 index 0000000000..5a55dd7bbb --- /dev/null +++ b/collects/tests/typed-scheme/succeed/opt-lambda.rkt @@ -0,0 +1,9 @@ +#lang typed/racket + +(: opt (case-lambda ( -> Void) + (Integer -> Void))) +(define opt + (opt-lambda: ((n : Integer 0)) + (display n))) +(opt) +(opt 1) diff --git a/collects/typed-scheme/private/prims.rkt b/collects/typed-scheme/private/prims.rkt index 92e9247fd2..2f0a636b76 100644 --- a/collects/typed-scheme/private/prims.rkt +++ b/collects/typed-scheme/private/prims.rkt @@ -34,6 +34,7 @@ This file defines two sorts of primitives. All of them are provided into any mod "base-types.rkt" "base-types-extra.rkt" racket/flonum ; for for/flvector and for*/flvector + mzlib/etc (for-syntax syntax/parse syntax/private/util From 724313c766b6aff92858a6d2699f0bd61a016e6b Mon Sep 17 00:00:00 2001 From: John Clements Date: Wed, 20 Oct 2010 12:03:22 -0700 Subject: [PATCH 026/746] back to old style, not sure why (cherry picked from commit dfe6f78d805a99a79465c3d0fcf1653f41283b23) --- collects/test-engine/racket-tests.rkt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/collects/test-engine/racket-tests.rkt b/collects/test-engine/racket-tests.rkt index 9a9ca79375..a90d46e1cc 100644 --- a/collects/test-engine/racket-tests.rkt +++ b/collects/test-engine/racket-tests.rkt @@ -106,7 +106,14 @@ #'test-engine)))))))) 'stepper-skipto (append skipto/third ;; let - skipto/third skipto/third ;; unless (it expands into (if (let-values () ...)) + skipto/third skipto/second + ;; something funny going on here; I can't see how Mike's + ;; fix could ever have worked. Possibly related: this + ;; file is still written in the mzscheme language? + ;; ... no, that doesn't seem to pan out. + ;; okay, I really don't understand why, but it appears + ;; that in this context, 'when' is still expanding + ;; into a begin, rather than a (let-values () ...) skipto/cdr skipto/third ;; application of insert-test '(syntax-e cdr cdr syntax-e car) ;; lambda ))) From eb76f9fbc2f6d2972bdaecb8f4df95c62d1d39bf Mon Sep 17 00:00:00 2001 From: John Clements Date: Wed, 20 Oct 2010 12:03:59 -0700 Subject: [PATCH 027/746] frightening bug, #%if was capturing everything (cherry picked from commit 34fbc9a06f2a9b53fa4095e88841e283ee0147c5) --- collects/stepper/private/annotate.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/stepper/private/annotate.rkt b/collects/stepper/private/annotate.rkt index cf3e89998c..6c61372cd9 100644 --- a/collects/stepper/private/annotate.rkt +++ b/collects/stepper/private/annotate.rkt @@ -150,7 +150,7 @@ stx #f ; cond : - [(#%if test (#%let () then) else-stx) + [(if test (let-values () then) else-stx) (let ([origin (syntax-property stx 'origin)] [rebuild-if (lambda (new-cond-test) From a3ed757fa9557447f0ef94dab5b8df7432668d2b Mon Sep 17 00:00:00 2001 From: John Clements Date: Wed, 20 Oct 2010 12:04:52 -0700 Subject: [PATCH 028/746] cosmetic changes only (cherry picked from commit d18f43a48802601fb65aacde1c2a1ce0b5362257) --- collects/tests/stepper/automatic-tests.rkt | 4 +++- collects/tests/stepper/through-tests.rkt | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/collects/tests/stepper/automatic-tests.rkt b/collects/tests/stepper/automatic-tests.rkt index 45cd396d46..e7804b8eee 100644 --- a/collects/tests/stepper/automatic-tests.rkt +++ b/collects/tests/stepper/automatic-tests.rkt @@ -5,7 +5,9 @@ (let ((outer-namespace (current-namespace))) (parameterize ([display-only-errors #t] - [current-output-port (open-output-string)] + ;; display-only-errors is insufficient, because the evals + ;; actually cause output. So we just eat stdout. + [current-output-port (open-output-string)] [current-namespace (make-base-namespace)]) ;; make sure the tests' print-convert sees the teaching languages' properties #;(namespace-attach-module outer-namespace 'mzlib/pconvert-prop (current-namespace)) diff --git a/collects/tests/stepper/through-tests.rkt b/collects/tests/stepper/through-tests.rkt index 193a007b98..0b0a76a67c 100755 --- a/collects/tests/stepper/through-tests.rkt +++ b/collects/tests/stepper/through-tests.rkt @@ -23,7 +23,10 @@ [(list name models string expected-steps) (when (assq name list-of-tests) (error 'add-test "name ~v is already in the list of tests" name)) - (set! list-of-tests (append list-of-tests (list (list name (list models string expected-steps)))))])) + (set! list-of-tests + (append list-of-tests + (list (list name + (list models string expected-steps)))))])) (define (t1 name models string expected-steps) (add-test (list name models string expected-steps))) @@ -1460,23 +1463,27 @@ (t 'local-struct/i m:intermediate (define (f x) (local ((define-struct a (b c))) x)) (f 1) :: (define (f x) (local ((define-struct a (b c))) x)) {(f 1)} - -> (define (f x) (local ((define-struct a (b c))) x)) {(define-struct a_1 (b c))} {1}) + -> (define (f x) (local ((define-struct a (b c))) x)) + {(define-struct a_1 (b c))} {1}) (t 'local-struct/ilam m:intermediate-lambda (define (f x) (local ((define-struct a (b c))) x)) (f 1) :: (define (f x) (local ((define-struct a (b c))) x)) {(f 1)} - -> (define (f x) (local ((define-struct a (b c))) x)) {((lambda (x) (local ((define-struct a (b c))) x)) 1)} - -> (define (f x) (local ((define-struct a (b c))) x)) {(define-struct a_1 (b c))} {1}) + -> (define (f x) (local ((define-struct a (b c))) x)) + {((lambda (x) (local ((define-struct a (b c))) x)) 1)} + -> (define (f x) (local ((define-struct a (b c))) x)) + {(define-struct a_1 (b c))} {1}) ;; run whatever tests are enabled (intended for interactive use): (define (ggg) - (parameterize (#;[disable-stepper-error-handling #t] + (parameterize ([disable-stepper-error-handling #t] #;[display-only-errors #t] #;[store-steps #f] #;[show-all-steps #t]) - #;(run-tests '(check-expect forward-ref check-within check-within-bad check-error check-error-bad)) + #;(run-tests '(check-expect forward-ref check-within check-within-bad + check-error check-error-bad)) #;(run-tests '(teachpack-universe)) #;(run-all-tests) (run-tests '(check-expect)))) From 2c3c077d4573798220e91ab5c75112c4e5d402c5 Mon Sep 17 00:00:00 2001 From: Casey Klein Date: Wed, 20 Oct 2010 17:13:01 -0700 Subject: [PATCH 029/746] Revert "adjusted define-metafunction/extension so that it recompiles the old cases in the new language" This reverts commit 99d85159b69da057b83e1f2d17eaf75ad7f08e9d. Signed-off-by: Casey Klein --- collects/redex/private/reduction-semantics.rkt | 15 +++------------ collects/redex/tests/tl-test.rkt | 12 ------------ 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/collects/redex/private/reduction-semantics.rkt b/collects/redex/private/reduction-semantics.rkt index 288603e6e3..579698fe5c 100644 --- a/collects/redex/private/reduction-semantics.rkt +++ b/collects/redex/private/reduction-semantics.rkt @@ -1521,16 +1521,8 @@ (syntax->list stuffs))) (syntax->list extras)))) -(define (build-metafunction lang cases parent-cases/wrong-lang wrap dom-contract-pat codom-contract-pat name relation?) - (let ([parent-cases (map (λ (parent-case) - (make-metafunc-case - (compile-pattern lang (metafunc-case-lhs-pat parent-case) #t) - (metafunc-case-rhs parent-case) - (metafunc-case-lhs-pat parent-case) - (metafunc-case-src-loc parent-case) - (metafunc-case-id parent-case))) - parent-cases/wrong-lang)] - [dom-compiled-pattern (and dom-contract-pat (compile-pattern lang dom-contract-pat #f))] +(define (build-metafunction lang cases parent-cases wrap dom-contract-pat codom-contract-pat name relation?) + (let ([dom-compiled-pattern (and dom-contract-pat (compile-pattern lang dom-contract-pat #f))] [codom-compiled-pattern (compile-pattern lang codom-contract-pat #f)]) (values (wrap @@ -1554,7 +1546,6 @@ (metafunc-proc-cases r))) (cover-case id c)))) (relation-coverage))))] - [all-cases (append cases parent-cases)] [metafunc (λ (exp) (let ([cache-ref (hash-ref cache exp not-in-cache)]) @@ -1565,7 +1556,7 @@ (redex-error name "~s is not in my domain" `(,name ,@exp)))) - (let loop ([cases all-cases] + (let loop ([cases (append cases parent-cases)] [num (- (length parent-cases))]) (cond [(null? cases) diff --git a/collects/redex/tests/tl-test.rkt b/collects/redex/tests/tl-test.rkt index 52543da215..1d22c55a3d 100644 --- a/collects/redex/tests/tl-test.rkt +++ b/collects/redex/tests/tl-test.rkt @@ -531,18 +531,6 @@ (test (term (g 11 17)) 11) (test (term (h 11 17)) 11)) - (let () - (define-language L - (v 1)) - (define-extended-language M - L - (v .... 2)) - (define-metafunction L - [(f v) v]) - (define-metafunction/extension f M - [(g 17) 17]) - (test (term (g 2)) 2)) - (let () (define-metafunction empty-language [(f any) 1]) From 6dcdcc283fe611c34776fb9d57c20364d67e32fc Mon Sep 17 00:00:00 2001 From: Casey Klein Date: Thu, 21 Oct 2010 07:41:26 -0700 Subject: [PATCH 030/746] Deletes ill-formed, commented-out Redex test. Signed-off-by: Casey Klein --- collects/redex/tests/tl-test.rkt | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/collects/redex/tests/tl-test.rkt b/collects/redex/tests/tl-test.rkt index 1d22c55a3d..4d3dc05416 100644 --- a/collects/redex/tests/tl-test.rkt +++ b/collects/redex/tests/tl-test.rkt @@ -537,25 +537,6 @@ (define-metafunction/extension f empty-language [(g any) 2]) (test (term (g 0)) 2)) - - #: - (let () - (define-language L - (v 1 (v))) - (define-metafunction L - f : v -> v - [(f (v)) - any_1 - (where any_1 (f v))]) - - (define-extended-language M - L - (v .... 2)) - (define-metafunction/extension f M - g : v -> v - [(g 2) 2]) - - (term (g (2)))) (let () (define-metafunction empty-language From fad24a782f3c348b51256799671534fdd9fcbcfa Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 3 Aug 2010 21:36:51 -0400 Subject: [PATCH 031/746] v5.0.1 stuff (cherry picked from commit 5f5810cfea5fb6e447a9f4af68be87952b0d78ce) --- collects/meta/web/download/data.rkt | 3 ++- collects/meta/web/download/installers.txt | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/collects/meta/web/download/data.rkt b/collects/meta/web/download/data.rkt index 05f69dd6b7..6f6a88b851 100644 --- a/collects/meta/web/download/data.rkt +++ b/collects/meta/web/download/data.rkt @@ -1,7 +1,8 @@ #lang racket/base (define -versions+dates- - '(["5.0" "June 2010"] + '(["5.0.1" "August 2010"] + ["5.0" "June 2010"] ["4.2.5" "April 2010"] ["4.2.4" "January 2010"] ["4.2.3" "December 2009"] diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index e625f0010d..b78963ef8f 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -1,3 +1,25 @@ +8.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-debian.sh +8.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-f12.sh +8.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-ubuntu-jaunty.sh +9.2M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-osx-mac.dmg +6.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-win32.exe +8.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-darwin.sh +9.2M 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-osx-mac.dmg +9.0M 5.0.1/racket-textual/racket-textual-5.0.1-bin-x86_64-linux-f7.sh +4.9M 5.0.1/racket-textual/racket-textual-5.0.1-src-mac.dmg +4.8M 5.0.1/racket-textual/racket-textual-5.0.1-src-unix.tgz +6.8M 5.0.1/racket-textual/racket-textual-5.0.1-src-win.zip +47M 5.0.1/racket/racket-5.0.1-bin-i386-linux-debian.sh +47M 5.0.1/racket/racket-5.0.1-bin-i386-linux-f12.sh +47M 5.0.1/racket/racket-5.0.1-bin-i386-linux-ubuntu-jaunty.sh +48M 5.0.1/racket/racket-5.0.1-bin-i386-osx-mac.dmg +29M 5.0.1/racket/racket-5.0.1-bin-i386-win32.exe +46M 5.0.1/racket/racket-5.0.1-bin-ppc-darwin.sh +48M 5.0.1/racket/racket-5.0.1-bin-ppc-osx-mac.dmg +47M 5.0.1/racket/racket-5.0.1-bin-x86_64-linux-f7.sh +16M 5.0.1/racket/racket-5.0.1-src-mac.dmg +16M 5.0.1/racket/racket-5.0.1-src-unix.tgz +20M 5.0.1/racket/racket-5.0.1-src-win.zip 8.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-debian.sh 8.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-f12.sh 8.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-ubuntu-jaunty.sh From 3504ba170e478ffd03c99a48282bbb9c58cbcaca Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 21 Oct 2010 16:31:58 -0400 Subject: [PATCH 032/746] "/proj/scheme/" renamed to "/proj/racket/" at CCS. (cherry picked from commit 6d6492e9e3daaf37d95dfe9b23ab0e25314aeaae) --- collects/meta/web/www/people.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/meta/web/www/people.rkt b/collects/meta/web/www/people.rkt index 509d6de09a..8ed487f2ef 100644 --- a/collects/meta/web/www/people.rkt +++ b/collects/meta/web/www/people.rkt @@ -6,8 +6,8 @@ (place ; ------------------------------------------------------------------- 'neu "Northeastern University" #:location "Boston, MA" - #:url "http://www.ccs.neu.edu/scheme/" - #:pubs "http://www.ccs.neu.edu/scheme/pubs/" + #:url "http://www.ccs.neu.edu/racket/" + #:pubs "http://www.ccs.neu.edu/racket/pubs/" (person 'matthias "Matthias Felleisen" #:url "http://www.ccs.neu.edu/home/matthias/") (person 'eli "Eli Barzilay" From 49754fa3dd793241b3ce858442c580a41d6322d8 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 20 Oct 2010 22:56:17 -0400 Subject: [PATCH 033/746] Reformat, minor tweaks, reorganize part on sequence operations into a new section. (cherry picked from commit 655b066a9339f5fbe8f583c3b325974634f99338) --- .../scribblings/reference/sequences.scrbl | 848 +++++++++--------- 1 file changed, 429 insertions(+), 419 deletions(-) diff --git a/collects/scribblings/reference/sequences.scrbl b/collects/scribblings/reference/sequences.scrbl index 58e813473c..bd11e88f71 100644 --- a/collects/scribblings/reference/sequences.scrbl +++ b/collects/scribblings/reference/sequences.scrbl @@ -2,34 +2,34 @@ @(require "mz.ss" (for-syntax racket/base) scribble/scheme - (for-label racket/generator + (for-label racket/generator racket/mpair)) @(define generator-eval - (lambda () - (let ([the-eval (make-base-eval)]) - (the-eval '(require racket/generator)) - the-eval))) + (let ([the-eval (make-base-eval)]) + (the-eval '(require racket/generator)) + the-eval)) @(define (info-on-seq where what) - @margin-note{See @secref[where] for information on using @|what| as sequences.}) + @margin-note{See @secref[where] for information on using @|what| as + sequences.}) @title[#:tag "sequences"]{Sequences} @guideintro["sequences"]{sequences} -A @deftech{sequence} encapsulates an ordered stream of values. The +A @deftech{sequence} encapsulates an ordered stream of values. The elements of a sequence can be extracted with one of the @scheme[for] syntactic forms or with the procedures returned by @scheme[sequence-generate]. -The sequence datatype overlaps with many other datatypes. Among +The sequence datatype overlaps with many other datatypes. Among built-in datatypes, the sequence datatype includes the following: @itemize[ @item{strings (see @secref["strings"])} - + @item{byte strings (see @secref["bytestrings"])} @item{lists (see @secref["pairs"])} @@ -48,300 +48,216 @@ built-in datatypes, the sequence datatype includes the following: ] -In addition, @scheme[make-do-sequence] creates a sequence given a -thunk that returns procedures to implement a generator, and the -@scheme[prop:sequence] property can be associated with a structure -type. +In addition, @scheme[make-do-sequence] creates a sequence given a thunk +that returns procedures to implement a generator, and the +@scheme[prop:sequence] property can be associated with a structure type. For most sequence types, extracting elements from a sequence has no side-effect on the original sequence value; for example, extracting the -sequence of elements from a list does not change the list. For other +sequence of elements from a list does not change the list. For other sequence types, each extraction implies a side effect; for example, -extracting the sequence of bytes from a port cause the bytes to be -read from the port. +extracting the sequence of bytes from a port cause the bytes to be read +from the port. -Individual elements of a sequence typically correspond to single -values, but an element may also correspond to multiple values. For -example, a hash table generates two values---a key and its value---for -each element in the sequence. +Individual elements of a sequence typically correspond to single values, +but an element may also correspond to multiple values. For example, a +hash table generates two values---a key and its value---for each element +in the sequence. +@; ---------------------------------------------------------------------- @section{Sequence Predicate and Constructors} -@defproc[(sequence? [v any/c]) boolean?]{ Return @scheme[#t] if -@scheme[v] can be used as a sequence, @scheme[#f] otherwise.} +@defproc[(sequence? [v any/c]) boolean?]{ + Return @scheme[#t] if @scheme[v] can be used as a sequence, + @scheme[#f] otherwise.} -@defthing[empty-seqn sequence?]{ A sequence with no elements. } - -@defproc[(seqn->list [s sequence?]) list?]{ Returns a list whose -elements are the elements of the @scheme[s], which must be a one-valued sequence. -If @scheme[s] is infinite, this function does not terminate. } - -@defproc[(seqn-cons [v any/c] - ... - [s sequence?]) - sequence?]{ -Returns a sequence whose first element is @scheme[(values v ...)] and whose -remaining elements are the same as @scheme[s]. -} - -@defproc[(seqn-first [s sequence?]) - (values any/c ...)]{ -Returns the first element of @scheme[s].} - -@defproc[(seqn-rest [s sequence?]) - sequence?]{ -Returns a sequence equivalent to @scheme[s], except the first element is omitted.} - -@defproc[(seqn-length [s sequence?]) - exact-nonnegative-integer?]{ -Returns the number of elements of @scheme[s]. If @scheme[s] is infinite, this -function does not terminate. } - -@defproc[(seqn-ref [s sequence?] [i exact-nonnegative-integer?]) - (values any/c ...)]{ -Returns the @scheme[i]th element of @scheme[s].} - -@defproc[(seqn-tail [s sequence?] [i exact-nonnegative-integer?]) - sequence?]{ -Returns a sequence equivalent to @scheme[s], except the first @scheme[i] elements are omitted.} - -@defproc[(seqn-append [s sequence?] ...) - sequence?]{ -Returns a sequence that contains all elements of each sequence in the order they appear in the original sequences. The -new sequence is constructed lazily. } - -@defproc[(seqn-map [f procedure?] - [s sequence?]) - sequence?]{ -Returns a sequence that contains @scheme[f] applied to each element of @scheme[s]. The new sequence is constructed lazily. } - -@defproc[(seqn-andmap [f (-> any/c ... boolean?)] - [s sequence?]) - boolean?]{ -Returns @scheme[#t] if @scheme[f] returns a true result on every element of @scheme[s]. If @scheme[s] is infinite and @scheme[f] never -returns a false result, this function does not terminate. } - -@defproc[(seqn-ormap [f (-> any/c ... boolean?)] - [s sequence?]) - boolean?]{ -Returns @scheme[#t] if @scheme[f] returns a true result on some element of @scheme[s]. If @scheme[s] is infinite and @scheme[f] never -returns a true result, this function does not terminate. } - -@defproc[(seqn-for-each [f (-> any/c ... any)] - [s sequence?]) - (void)]{ -Applies @scheme[f] to each element of @scheme[s]. If @scheme[s] is infinite, this function does not terminate. } - -@defproc[(seqn-fold [f (-> any/c any/c ... any/c)] - [i any/c] - [s sequence?]) - (void)]{ -Folds @scheme[f] over each element of @scheme[s] with @scheme[i] as the initial accumulator. If @scheme[s] is infinite, this function does not terminate. } - -@defproc[(seqn-filter [f (-> any/c ... boolean?)] - [s sequence?]) - sequence?]{ -Returns a sequence whose elements are the elements of @scheme[s] for which @scheme[f] returns a true result. Although the new sequence is constructed -lazily, if @scheme[s] has an infinite number of elements where @scheme[f] returns a false result in between two elements where @scheme[f] returns a true result -then operations on this sequence will not terminate during that infinite sub-sequence. } - -@defproc[(seqn-add-between [s sequence?] [e any/c]) - sequence?]{ -Returns a sequence whose elements are the elements of @scheme[s] except in between each is @scheme[e]. The new sequence is constructed lazily. } - -@defproc[(seqn-count [f procedure?] [s sequence?]) - exact-nonnegative-integer?]{ -Returns the number of elements in @scheme[s] for which @scheme[f] returns a true result. If @scheme[s] is infinite, this function does not terminate. } - @defproc*[([(in-range [end number?]) sequence?] [(in-range [start number?] [end number?] [step number? 1]) sequence?])]{ -Returns a sequence whose elements are numbers. The single-argument -case @scheme[(in-range end)] is equivalent to @scheme[(in-range 0 end -1)]. The first number in the sequence is @scheme[start], and each -successive element is generated by adding @scheme[step] to the -previous element. The sequence stops before an element that would be -greater or equal to @scheme[end] if @scheme[step] is non-negative, or -less or equal to @scheme[end] if @scheme[step] is negative. -@speed[in-range "number"]} + Returns a sequence whose elements are numbers. The single-argument + case @scheme[(in-range end)] is equivalent to @scheme[(in-range 0 end + 1)]. The first number in the sequence is @scheme[start], and each + successive element is generated by adding @scheme[step] to the + previous element. The sequence stops before an element that would be + greater or equal to @scheme[end] if @scheme[step] is non-negative, or + less or equal to @scheme[end] if @scheme[step] is negative. + @speed[in-range "number"]} @defproc[(in-naturals [start exact-nonnegative-integer? 0]) sequence?]{ -Returns an infinite sequence of exact integers starting with -@scheme[start], where each element is one more than the preceding -element. @speed[in-naturals "integer"]} + Returns an infinite sequence of exact integers starting with + @scheme[start], where each element is one more than the preceding + element. @speed[in-naturals "integer"]} @defproc[(in-list [lst list?]) sequence?]{ -Returns a sequence equivalent to @scheme[lst]. -@info-on-seq["pairs" "lists"] -@speed[in-list "list"]} + Returns a sequence equivalent to @scheme[lst]. + @info-on-seq["pairs" "lists"] + @speed[in-list "list"]} @defproc[(in-mlist [mlst mlist?]) sequence?]{ -Returns a sequence equivalent to @scheme[mlst]. -@info-on-seq["mpairs" "mutable lists"] -@speed[in-mlist "mutable list"]} + Returns a sequence equivalent to @scheme[mlst]. + @info-on-seq["mpairs" "mutable lists"] + @speed[in-mlist "mutable list"]} @defproc[(in-vector [vec vector?] - [start exact-nonnegative-integer? 0] - [stop (or/c exact-nonnegative-integer? #f) #f] - [step (and/c exact-integer? (not/c zero?)) 1]) - sequence?]{ - -Returns a sequence equivalent to @scheme[vec] when no optional -arguments are supplied. - -@info-on-seq["vectors" "vectors"] - -The optional arguments @scheme[start], @scheme[stop], and -@scheme[step] are analogous to @scheme[in-range], except that a -@scheme[#f] value for @scheme[stop] is equivalent to -@scheme[(vector-length vec)]. That is, the first element in the -sequence is @scheme[(vector-ref vec start)], and each successive -element is generated by adding @scheme[step] to index of the previous -element. The sequence stops before an index that would be greater or -equal to @scheme[end] if @scheme[step] is non-negative, or less or -equal to @scheme[end] if @scheme[step] is negative. - -If @scheme[start] is less than @scheme[stop] and @scheme[step] is -negative, then the @exnraise[exn:fail:contract:mismatch]. Similarly, -if @scheme[start] is more than @scheme[stop] and @scheme[step] is -positive, then the @exnraise[exn:fail:contract:mismatch]. The -@scheme[start] and @scheme[stop] values are @emph{not} checked against -the size of @scheme[vec], so access can fail when an element is -demanded from the sequence. - -@speed[in-vector "vector"]} - -@defproc[(in-string [str string?] - [start exact-nonnegative-integer? 0] - [stop (or/c exact-nonnegative-integer? #f) #f] + [start exact-nonnegative-integer? 0] + [stop (or/c exact-nonnegative-integer? #f) #f] [step (and/c exact-integer? (not/c zero?)) 1]) sequence?]{ -Returns a sequence equivalent to @scheme[str] when no optional -arguments are supplied. + Returns a sequence equivalent to @scheme[vec] when no optional + arguments are supplied. -@info-on-seq["strings" "strings"] + @info-on-seq["vectors" "vectors"] -The optional arguments @scheme[start], @scheme[stop], and -@scheme[step] are as in @scheme[in-vector]. + The optional arguments @scheme[start], @scheme[stop], and + @scheme[step] are analogous to @scheme[in-range], except that a + @scheme[#f] value for @scheme[stop] is equivalent to + @scheme[(vector-length vec)]. That is, the first element in the + sequence is @scheme[(vector-ref vec start)], and each successive + element is generated by adding @scheme[step] to index of the previous + element. The sequence stops before an index that would be greater or + equal to @scheme[end] if @scheme[step] is non-negative, or less or + equal to @scheme[end] if @scheme[step] is negative. -@speed[in-string "string"]} + If @scheme[start] is less than @scheme[stop] and @scheme[step] is + negative, then the @exnraise[exn:fail:contract:mismatch]. Similarly, + if @scheme[start] is more than @scheme[stop] and @scheme[step] is + positive, then the @exnraise[exn:fail:contract:mismatch]. The + @scheme[start] and @scheme[stop] values are @emph{not} checked against + the size of @scheme[vec], so access can fail when an element is + demanded from the sequence. + + @speed[in-vector "vector"]} + +@defproc[(in-string [str string?] + [start exact-nonnegative-integer? 0] + [stop (or/c exact-nonnegative-integer? #f) #f] + [step (and/c exact-integer? (not/c zero?)) 1]) + sequence?]{ + Returns a sequence equivalent to @scheme[str] when no optional + arguments are supplied. + + @info-on-seq["strings" "strings"] + + The optional arguments @scheme[start], @scheme[stop], and + @scheme[step] are as in @scheme[in-vector]. + + @speed[in-string "string"]} @defproc[(in-bytes [bstr bytes?] - [start exact-nonnegative-integer? 0] - [stop (or/c exact-nonnegative-integer? #f) #f] + [start exact-nonnegative-integer? 0] + [stop (or/c exact-nonnegative-integer? #f) #f] [step (and/c exact-integer? (not/c zero?)) 1]) sequence?]{ -Returns a sequence equivalent to @scheme[bstr] when no optional -arguments are supplied. + Returns a sequence equivalent to @scheme[bstr] when no optional + arguments are supplied. -@info-on-seq["bytestrings" "byte strings"] + @info-on-seq["bytestrings" "byte strings"] -The optional arguments @scheme[start], @scheme[stop], and -@scheme[step] are as in @scheme[in-vector]. + The optional arguments @scheme[start], @scheme[stop], and + @scheme[step] are as in @scheme[in-vector]. -@speed[in-bytes "byte string"]} + @speed[in-bytes "byte string"]} -@defproc[(in-port [r (input-port? . -> . any/c) read] - [in input-port? (current-input-port)]) - sequence?]{ -Returns a sequence whose elements are produced by calling @scheme[r] -on @scheme[in] until it produces @scheme[eof].} +@defproc[(in-port [r (input-port? . -> . any/c) read] + [in input-port? (current-input-port)]) + sequence?]{ + Returns a sequence whose elements are produced by calling @scheme[r] + on @scheme[in] until it produces @scheme[eof].} @defproc[(in-input-port-bytes [in input-port?]) sequence?]{ -Returns a sequence equivalent to @scheme[(in-port read-byte in)].} + Returns a sequence equivalent to @scheme[(in-port read-byte in)].} -@defproc[(in-input-port-chars [in input-port?]) sequence?]{ Returns a -sequence whose elements are read as characters form @scheme[in] -(equivalent to @scheme[(in-port read-char in)]).} +@defproc[(in-input-port-chars [in input-port?]) sequence?]{ + Returns a sequence whose elements are read as characters form + @scheme[in] (equivalent to @scheme[(in-port read-char in)]).} @defproc[(in-lines [in input-port? (current-input-port)] [mode (or/c 'linefeed 'return 'return-linefeed 'any 'any-one) 'any]) sequence?]{ - -Returns a sequence equivalent to @scheme[(in-port (lambda (p) -(read-line p mode)) in)]. Note that the default mode is @scheme['any], -whereas the default mode of @scheme[read-line] is -@scheme['linefeed]. } + Returns a sequence equivalent to + @scheme[(in-port (lambda (p) (read-line p mode)) in)]. Note that the + default mode is @scheme['any], whereas the default mode of + @scheme[read-line] is @scheme['linefeed].} @defproc[(in-bytes-lines [in input-port? (current-input-port)] [mode (or/c 'linefeed 'return 'return-linefeed 'any 'any-one) 'any]) sequence?]{ + Returns a sequence equivalent to + @scheme[(in-port (lambda (p) (read-bytes-line p mode)) in)]. Note + that the default mode is @scheme['any], whereas the default mode of + @scheme[read-bytes-line] is @scheme['linefeed].} -Returns a sequence equivalent to @scheme[(in-port (lambda (p) -(read-bytes-line p mode)) in)]. Note that the default mode is @scheme['any], -whereas the default mode of @scheme[read-bytes-line] is -@scheme['linefeed]. } - @defproc[(in-hash [hash hash?]) sequence?]{ -Returns a sequence equivalent to @scheme[hash]. + Returns a sequence equivalent to @scheme[hash]. -@info-on-seq["hashtables" "hash tables"]} + @info-on-seq["hashtables" "hash tables"]} @defproc[(in-hash-keys [hash hash?]) sequence?]{ -Returns a sequence whose elements are the keys of @scheme[hash].} + Returns a sequence whose elements are the keys of @scheme[hash].} @defproc[(in-hash-values [hash hash?]) sequence?]{ -Returns a sequence whose elements are the values of @scheme[hash].} + Returns a sequence whose elements are the values of @scheme[hash].} @defproc[(in-hash-pairs [hash hash?]) sequence?]{ -Returns a sequence whose elements are pairs, each containing a key and -its value from @scheme[hash] (as opposed to using @scheme[hash] directly -as a sequence to get the key and value as separate values for each -element).} + Returns a sequence whose elements are pairs, each containing a key and + its value from @scheme[hash] (as opposed to using @scheme[hash] + directly as a sequence to get the key and value as separate values for + each element).} @defproc[(in-directory [dir (or/c #f path-string?) #f]) sequence?]{ - -Return a sequence that produces all of the paths for files, -directories, and links with @racket[dir]. If @racket[dir] is not -@racket[#f], then every produced path starts with @racket[dir] as its -prefix. If @racket[dir] is @racket[#f], then paths in and relative to -the current directory are produced.} + Return a sequence that produces all of the paths for files, + directories, and links with @racket[dir]. If @racket[dir] is not + @racket[#f], then every produced path starts with @racket[dir] as its + prefix. If @racket[dir] is @racket[#f], then paths in and relative to + the current directory are produced.} @defproc[(in-producer [producer procedure?] [stop any/c] [args any/c] ...) sequence?]{ -Returns a sequence that contains values from sequential calls to -@scheme[producer]. @scheme[stop] identifies the value that marks the -end of the sequence --- this value is not included in the sequence. -@scheme[stop] can be a predicate or a value that is tested against the -results with @scheme[eq?]. Note that you must use a predicate function -if the stop value is itself a function, or if the @scheme[producer] -returns multiple values.} + Returns a sequence that contains values from sequential calls to + @scheme[producer]. @scheme[stop] identifies the value that marks the + end of the sequence --- this value is not included in the sequence. + @scheme[stop] can be a predicate or a value that is tested against the + results with @scheme[eq?]. Note that you must use a predicate + function if the stop value is itself a function, or if the + @scheme[producer] returns multiple values.} @defproc[(in-value [v any/c]) sequence?]{ -Returns a sequence that produces a single value: @scheme[v]. This form -is mostly useful for @scheme[let]-like bindings in forms such as -@scheme[for*/list].} + Returns a sequence that produces a single value: @scheme[v]. This + form is mostly useful for @scheme[let]-like bindings in forms such as + @scheme[for*/list].} -@defproc[(in-indexed [seq sequence?]) sequence?]{Returns a sequence -where each element has two values: the value produced by @scheme[seq], -and a non-negative exact integer starting with @scheme[0]. The -elements of @scheme[seq] must be single-valued.} +@defproc[(in-indexed [seq sequence?]) sequence?]{ + Returns a sequence where each element has two values: the value + produced by @scheme[seq], and a non-negative exact integer starting + with @scheme[0]. The elements of @scheme[seq] must be single-valued.} -@defproc[(in-sequences [seq sequence?] ...) sequence?]{Returns a -sequence that is made of all input sequences, one after the other. The -elements of each @scheme[seq] must all have the same number of -values.} +@defproc[(in-sequences [seq sequence?] ...) sequence?]{ + Returns a sequence that is made of all input sequences, one after the + other. The elements of each @scheme[seq] must all have the same + number of values.} -@defproc[(in-cycle [seq sequence?] ...) sequence?]{Similar to -@scheme[in-sequences], but the sequences are repeated in an infinite -cycle.} +@defproc[(in-cycle [seq sequence?] ...) sequence?]{ + Similar to @scheme[in-sequences], but the sequences are repeated in an + infinite cycle.} -@defproc[(in-parallel [seq sequence?] ...) sequence?]{Returns a -sequence where each element has as many values as the number of -supplied @scheme[seq]s; the values, in order, are the values of each -@scheme[seq]. The elements of each @scheme[seq] must be -single-valued.} +@defproc[(in-parallel [seq sequence?] ...) sequence?]{ + Returns a sequence where each element has as many values as the number + of supplied @scheme[seq]s; the values, in order, are the values of + each @scheme[seq]. The elements of each @scheme[seq] must be + single-valued.} @defproc[(stop-before [seq sequence?] [pred (any/c . -> . any)]) -sequence?]{ Returns a sequence that contains the elements of -@scheme[seq] (which must be single-valued), but only until the last -element for which applying @scheme[pred] to the element produces -@scheme[#t], after which the sequence ends.} + sequence?]{ + Returns a sequence that contains the elements of @scheme[seq] (which + must be single-valued), but only until the last element for which + applying @scheme[pred] to the element produces @scheme[#t], after + which the sequence ends.} @defproc[(stop-after [seq sequence?] [pred (any/c . -> . any)]) -sequence?]{ Returns a sequence that contains the elements of -@scheme[seq] (which must be single-valued), but only until the element -(inclusive) for which applying @scheme[pred] to the element produces -@scheme[#t], after which the sequence ends.} + sequence?]{ + Returns a sequence that contains the elements of @scheme[seq] (which + must be single-valued), but only until the element (inclusive) for + which applying @scheme[pred] to the element produces @scheme[#t], + after which the sequence ends.} @defproc[(make-do-sequence [thunk (-> (values (any/c . -> . any) (any/c . -> . any/c) @@ -350,220 +266,314 @@ sequence?]{ Returns a sequence that contains the elements of (() () #:rest list? . ->* . any/c) ((any/c) () #:rest list? . ->* . any/c)))]) sequence?]{ + Returns a sequence whose elements are generated by the procedures and + initial value returned by the thunk. The generator is defined in terms + of a @defterm{position}, which is initialized to the third result of + the thunk, and the @defterm{element}, which may consist of multiple + values. -Returns a sequence whose elements are generated by the procedures and -initial value returned by the thunk. The generator is defined in terms -of a @defterm{position}, which is initialized to the third result of -the thunk, and the @defterm{element}, which may consist of multiple -values. + The @scheme[thunk] results define the generated elements as follows: + @itemize[ + @item{The first result is a @scheme[_pos->element] procedure that takes + the current position and returns the value(s) for the current + element.} + @item{The second result is a @scheme[_next-pos] procedure that takes + the current position and returns the next position.} + @item{The third result is the initial position.} + @item{The fourth result takes the current position and returns a + true result if the sequence includes the value(s) for the current + position, and false if the sequence should end instead of + including the value(s).} + @item{The fifth result is like the fourth result, but it takes the + current element value(s) instead of the current position.} + @item{The sixth result is like the fourth result, but it takes both + the current position and the current element values(s) and + determines a sequence end after the current element is already + included in the sequence.}] -The @scheme[thunk] results define the generated elements as follows: - -@itemize[ - - @item{The first result is a @scheme[_pos->element] procedure that takes - the current position and returns the value(s) for the current element.} - - @item{The second result is a @scheme[_next-pos] procedure that takes - the current position and returns the next position.} - - @item{The third result is the initial position.} - - @item{The fourth result takes the current position and returns a true - result if the sequence includes the value(s) for the current - position, and false if the sequence should end instead of - including the value(s).} - - @item{The fifth result is like the fourth result, but it takes the - current element value(s) instead of the current position.} - - @item{The sixth result is like the fourth result, but it takes both - the current position and the current element values(s) and - determines a sequence end after the current element is already - included in the sequence.} - -] - -Each of the procedures listed above is called only once per position. -Among the last three procedures, as soon as one of the procedures -returns @scheme[#f], the sequence ends, and none are called -again. Typically, one of the functions determines the end condition, -and the other two functions always return @scheme[#t].} + Each of the procedures listed above is called only once per position. + Among the last three procedures, as soon as one of the procedures + returns @scheme[#f], the sequence ends, and none are called again. + Typically, one of the functions determines the end condition, and the + other two functions always return @scheme[#t].} @defthing[prop:sequence struct-type-property?]{ -Associates a procedure to a structure type that takes an instance of -the structure and returns a sequence. If @scheme[v] is an instance of -a structure type with this property, then @scheme[(sequence? v)] -produces @scheme[#t]. + Associates a procedure to a structure type that takes an instance of + the structure and returns a sequence. If @scheme[v] is an instance of + a structure type with this property, then @scheme[(sequence? v)] + produces @scheme[#t]. -@let-syntax[([car (make-element-id-transformer (lambda (id) #'@schemeidfont{car}))]) - @examples[ - (define-struct train (car next) - #:property prop:sequence (lambda (t) - (make-do-sequence - (lambda () - (values train-car - train-next - t - (lambda (t) t) - (lambda (v) #t) - (lambda (t v) #t)))))) - (for/list ([c (make-train 'engine - (make-train 'boxcar - (make-train 'caboose - #f)))]) - c) - ]]} + @let-syntax[([car (make-element-id-transformer + (lambda (id) #'@schemeidfont{car}))]) + @examples[ + (define-struct train (car next) + #:property prop:sequence (lambda (t) + (make-do-sequence + (lambda () + (values train-car + train-next + t + (lambda (t) t) + (lambda (v) #t) + (lambda (t v) #t)))))) + (for/list ([c (make-train 'engine + (make-train 'boxcar + (make-train 'caboose + #f)))]) + c)]]} +@; ---------------------------------------------------------------------- +@section{Additional Sequence Operations} + +@defthing[empty-seqn sequence?]{ + A sequence with no elements.} + +@defproc[(seqn->list [s sequence?]) list?]{ + Returns a list whose elements are the elements of the @scheme[s], + which must be a one-valued sequence. If @scheme[s] is infinite, this + function does not terminate.} + +@defproc[(seqn-cons [v any/c] + ... + [s sequence?]) + sequence?]{ + Returns a sequence whose first element is @scheme[(values v ...)] and whose + remaining elements are the same as @scheme[s].} + +@defproc[(seqn-first [s sequence?]) + (values any/c ...)]{ + Returns the first element of @scheme[s].} + +@defproc[(seqn-rest [s sequence?]) + sequence?]{ + Returns a sequence equivalent to @scheme[s], except the first element + is omitted.} + +@defproc[(seqn-length [s sequence?]) + exact-nonnegative-integer?]{ + Returns the number of elements of @scheme[s]. If @scheme[s] is + infinite, this function does not terminate.} + +@defproc[(seqn-ref [s sequence?] [i exact-nonnegative-integer?]) + (values any/c ...)]{ + Returns the @scheme[i]th element of @scheme[s].} + +@defproc[(seqn-tail [s sequence?] [i exact-nonnegative-integer?]) + sequence?]{ + Returns a sequence equivalent to @scheme[s], except the first + @scheme[i] elements are omitted.} + +@defproc[(seqn-append [s sequence?] ...) + sequence?]{ + Returns a sequence that contains all elements of each sequence in the + order they appear in the original sequences. The new sequence is + constructed lazily.} + +@defproc[(seqn-map [f procedure?] + [s sequence?]) + sequence?]{ + Returns a sequence that contains @scheme[f] applied to each element of + @scheme[s]. The new sequence is constructed lazily.} + +@defproc[(seqn-andmap [f (-> any/c ... boolean?)] + [s sequence?]) + boolean?]{ + Returns @scheme[#t] if @scheme[f] returns a true result on every + element of @scheme[s]. If @scheme[s] is infinite and @scheme[f] never + returns a false result, this function does not terminate.} + +@defproc[(seqn-ormap [f (-> any/c ... boolean?)] + [s sequence?]) + boolean?]{ + Returns @scheme[#t] if @scheme[f] returns a true result on some + element of @scheme[s]. If @scheme[s] is infinite and @scheme[f] never + returns a true result, this function does not terminate.} + +@defproc[(seqn-for-each [f (-> any/c ... any)] + [s sequence?]) + (void)]{ + Applies @scheme[f] to each element of @scheme[s]. If @scheme[s] is + infinite, this function does not terminate.} + +@defproc[(seqn-fold [f (-> any/c any/c ... any/c)] + [i any/c] + [s sequence?]) + (void)]{ + Folds @scheme[f] over each element of @scheme[s] with @scheme[i] as + the initial accumulator. If @scheme[s] is infinite, this function + does not terminate.} + +@defproc[(seqn-filter [f (-> any/c ... boolean?)] + [s sequence?]) + sequence?]{ + Returns a sequence whose elements are the elements of @scheme[s] for + which @scheme[f] returns a true result. Although the new sequence is + constructed lazily, if @scheme[s] has an infinite number of elements + where @scheme[f] returns a false result in between two elements where + @scheme[f] returns a true result then operations on this sequence will + not terminate during that infinite sub-sequence.} + +@defproc[(seqn-add-between [s sequence?] [e any/c]) + sequence?]{ + Returns a sequence whose elements are the elements of @scheme[s] + except in between each is @scheme[e]. The new sequence is constructed + lazily.} + +@defproc[(seqn-count [f procedure?] [s sequence?]) + exact-nonnegative-integer?]{ + Returns the number of elements in @scheme[s] for which @scheme[f] + returns a true result. If @scheme[s] is infinite, this function does + not terminate.} + +@; ---------------------------------------------------------------------- @section{Sequence Generators} -@defproc[(sequence-generate [seq sequence?]) (values (-> boolean?) - (-> any))]{ -Returns two thunks to extract elements from the sequence. The first -returns @scheme[#t] if more values are available for the sequence. The -second returns the next element (which may be multiple values) from the -sequence; if no more elements are available, the -@exnraise[exn:fail:contract].} +@defproc[(sequence-generate [seq sequence?]) + (values (-> boolean?) (-> any))]{ + Returns two thunks to extract elements from the sequence. The first + returns @scheme[#t] if more values are available for the sequence. + The second returns the next element (which may be multiple values) + from the sequence; if no more elements are available, the + @exnraise[exn:fail:contract].} +@; ---------------------------------------------------------------------- @section{Iterator Generators} @defmodule[racket/generator] -@defform[(generator () body ...)]{ Creates a function that returns a -value through @scheme[yield], each time it is invoked. When -the generator runs out of values to yield, the last value it computed -will be returned for future invocations of the generator. Generators -can be safely nested. -Note: The first form must be @scheme[()]. In the future, the -@scheme[()] position will hold argument names that are used for the -initial generator call. +@defform[(generator () body ...)]{ + Creates a function that returns a value through @scheme[yield], each + time it is invoked. When the generator runs out of values to yield, + the last value it computed will be returned for future invocations of + the generator. Generators can be safely nested. -@examples[#:eval (generator-eval) -(define g (generator () - (let loop ([x '(a b c)]) - (if (null? x) - 0 - (begin - (yield (car x)) - (loop (cdr x))))))) -(g) -(g) -(g) -(g) -(g) -] + Note: The first form must be @scheme[()]. In the future, the + @scheme[()] position will hold argument names that are used for the + initial generator call. -To use an existing generator as a sequence, you should use @scheme[in-producer] -with a stop-value known to the generator. + @examples[#:eval generator-eval + (define g (generator () + (let loop ([x '(a b c)]) + (if (null? x) + 0 + (begin + (yield (car x)) + (loop (cdr x))))))) + (g) + (g) + (g) + (g) + (g)] -@examples[#:eval (generator-eval) -(define my-stop-value (gensym)) -(define my-generator (generator () - (let loop ([x '(a b c)]) - (if (null? x) - my-stop-value - (begin - (yield (car x)) - (loop (cdr x))))))) + To use an existing generator as a sequence, you should use + @scheme[in-producer] with a stop-value known for the generator. -(for/list ([i (in-producer my-generator my-stop-value)]) - i) -]} + @examples[#:eval generator-eval + (define my-stop-value (gensym)) + (define my-generator (generator () + (let loop ([x '(a b c)]) + (if (null? x) + my-stop-value + (begin + (yield (car x)) + (loop (cdr x))))))) -@defform[(infinite-generator body ...)]{ Creates a function similar to -@scheme[generator] but when the last @scheme[body] is executed the function -will re-execute all the bodies in a loop. + (for/list ([i (in-producer my-generator my-stop-value)]) + i)]} -@examples[#:eval (generator-eval) -(define welcome - (infinite-generator - (yield 'hello) - (yield 'goodbye))) -(welcome) -(welcome) -(welcome) -(welcome) -]} +@defform[(infinite-generator body ...)]{ + Creates a function similar to @scheme[generator] but when the last + @scheme[body] is executed the function will re-execute all the bodies + in a loop. -@defproc[(in-generator [expr any?] ...) sequence?]{ Returns a generator -that can be used as a sequence. The @scheme[in-generator] procedure takes care of the -case when @scheme[expr] stops producing values, so when the @scheme[expr] -completes, the generator will end. + @examples[#:eval generator-eval + (define welcome + (infinite-generator + (yield 'hello) + (yield 'goodbye))) + (welcome) + (welcome) + (welcome) + (welcome)]} -@examples[#:eval (generator-eval) -(for/list ([i (in-generator - (let loop ([x '(a b c)]) - (when (not (null? x)) - (yield (car x)) - (loop (cdr x)))))]) - i) -]} +@defproc[(in-generator [expr any?] ...) sequence?]{ + Returns a generator that can be used as a sequence. The + @scheme[in-generator] procedure takes care of the case when + @scheme[expr] stops producing values, so when the @scheme[expr] + completes, the generator will end. -@defform[(yield expr ...)]{ Saves the point of execution inside a generator -and returns a value. @scheme[yield] can accept any number of arguments and will -return them using @scheme[values]. + @examples[#:eval generator-eval + (for/list ([i (in-generator + (let loop ([x '(a b c)]) + (when (not (null? x)) + (yield (car x)) + (loop (cdr x)))))]) + i)]} -Values can be passed back to the generator after invoking @scheme[yield] by passing -the arguments to the generator instance. Note that a value cannot be passed back -to the generator until after the first @scheme[yield] has been invoked. +@defform[(yield expr ...)]{ + Saves the point of execution inside a generator and returns a value. + @scheme[yield] can accept any number of arguments and will return them + using @scheme[values]. -@examples[#:eval (generator-eval) -(define my-generator (generator () (yield 1) (yield 2 3 4))) -(my-generator) -(my-generator) -] + Values can be passed back to the generator after invoking + @scheme[yield] by passing the arguments to the generator instance. + Note that a value cannot be passed back to the generator until after + the first @scheme[yield] has been invoked. -@examples[#:eval (generator-eval) -(define pass-values-generator - (generator () - (let* ([from-user (yield 2)] - [from-user-again (yield (add1 from-user))]) - (yield from-user-again)))) + @examples[#:eval generator-eval + (define my-generator (generator () (yield 1) (yield 2 3 4))) + (my-generator) + (my-generator)] -(pass-values-generator) -(pass-values-generator 5) -(pass-values-generator 12) -]} + @examples[#:eval generator-eval + (define pass-values-generator + (generator () + (let* ([from-user (yield 2)] + [from-user-again (yield (add1 from-user))]) + (yield from-user-again)))) -@defproc[(generator-state [g any?]) symbol?]{ Returns a symbol that describes the state -of the generator. + (pass-values-generator) + (pass-values-generator 5) + (pass-values-generator 12)]} - @itemize[ - @item{@scheme['fresh] - The generator has been freshly created and has not - been invoked yet. Values cannot be passed to a fresh generator.} - @item{@scheme['suspended] - Control within the generator has been suspended due - to a call to @scheme[yield]. The generator can be invoked.} - @item{@scheme['running] - The generator is currently executing. This state can - only be returned if @scheme[generator-state] is invoked inside the generator.} - @item{@scheme['done] - The generator has executed its entire body and will not - call @scheme[yield] anymore.} - ] +@defproc[(generator-state [g any?]) symbol?]{ + Returns a symbol that describes the state of the generator. -@examples[#:eval (generator-eval) -(define my-generator (generator () (yield 1) (yield 2))) -(generator-state my-generator) -(my-generator) -(generator-state my-generator) -(my-generator) -(generator-state my-generator) -(my-generator) -(generator-state my-generator) + @itemize[ + @item{@scheme['fresh] --- The generator has been freshly created and + has not been invoked yet. Values cannot be passed to a fresh + generator.} + @item{@scheme['suspended] --- Control within the generator has been + suspended due to a call to @scheme[yield]. The generator can + be invoked.} + @item{@scheme['running] --- The generator is currently executing. + This state can only be returned if @scheme[generator-state] is + invoked inside the generator.} + @item{@scheme['done] --- The generator has executed its entire body + and will not call @scheme[yield] anymore.}] -(define introspective-generator (generator () ((yield 1)))) -(introspective-generator) -(introspective-generator - (lambda () (generator-state introspective-generator))) -(generator-state introspective-generator) -(introspective-generator) -]} + @examples[#:eval generator-eval + (define my-generator (generator () (yield 1) (yield 2))) + (generator-state my-generator) + (my-generator) + (generator-state my-generator) + (my-generator) + (generator-state my-generator) + (my-generator) + (generator-state my-generator) + + (define introspective-generator (generator () ((yield 1)))) + (introspective-generator) + (introspective-generator + (lambda () (generator-state introspective-generator))) + (generator-state introspective-generator) + (introspective-generator)]} @defproc[(sequence->generator [s sequence?]) (-> any?)]{ - -Returns a generator that returns elements from the sequence, @scheme[s], -each time the generator is invoked.} + Returns a generator that returns elements from the sequence, + @scheme[s], each time the generator is invoked.} @defproc[(sequence->repeated-generator [s sequence?]) (-> any?)]{ - -Returns a generator that returns elements from the sequence, @scheme[s], -similar to @scheme[sequence->generator] but looping over the values in -the sequence when no more values are left.} + Returns a generator that returns elements from the sequence, + @scheme[s], similar to @scheme[sequence->generator] but looping over + the values in the sequence when no more values are left.} From 8be4a76a616a45f2a4b69ddc30692f5f63230d9e Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 21 Oct 2010 16:52:48 -0400 Subject: [PATCH 034/746] Rename `seqn-*' to `stream-*'. Later this will grow, to include a few kinds of streams in a unified way, and possibly change the sequence protocol to a point where these functions are not causing such big runtime penalties. (cherry picked from commit 2f5265854a02605a46386809d8a9dd96f6b0c9bc) --- collects/racket/private/sequence.rkt | 102 ++++++------- .../scribblings/reference/sequences.scrbl | 52 +++---- collects/tests/racket/for.rktl | 143 +++++++++--------- collects/tests/racket/stress/sequence.rkt | 58 +++---- 4 files changed, 180 insertions(+), 175 deletions(-) diff --git a/collects/racket/private/sequence.rkt b/collects/racket/private/sequence.rkt index fdfdd3677b..425ce1fdf0 100644 --- a/collects/racket/private/sequence.rkt +++ b/collects/racket/private/sequence.rkt @@ -1,7 +1,7 @@ (module sequence "pre-base.rkt" (require "list.rkt") - (define empty-seqn + (define empty-stream (make-do-sequence (λ () (values @@ -12,10 +12,10 @@ (λ (val) #t) (λ (pos val) #t))))) - (define (seqn->list s) + (define (stream->list s) (for/list ([v s]) v)) - (define-syntax-rule (-seqn-cons vs s) + (define-syntax-rule (-stream-cons vs s) (make-do-sequence (λ () (define-values (more? next) (sequence-generate s)) @@ -30,31 +30,31 @@ (or (zero? pos) (more?))) (λ _ #t) (λ _ #t))))) - (define seqn-cons + (define stream-cons (case-lambda [() - (error 'seqn-cons "expects a sequence to extend, but received no arguments")] + (error 'stream-cons "expects a sequence to extend, but received no arguments")] [(s) - (-seqn-cons (values) s)] + (-stream-cons (values) s)] [(v s) - (-seqn-cons (values v) s)] + (-stream-cons (values v) s)] [vs*s ; XXX double reverse is bad but moving split-at causes a problem I can't figure (define s*vs (reverse vs*s)) - (-seqn-cons (apply values (reverse (cdr s*vs))) (car s*vs))])) + (-stream-cons (apply values (reverse (cdr s*vs))) (car s*vs))])) - (define (seqn-first s) + (define (stream-first s) (define-values (more? next) (sequence-generate s)) (unless (more?) - (error 'seqn-first "expects a sequence with at least one element")) + (error 'stream-first "expects a sequence with at least one element")) (next)) - (define (seqn-rest s) + (define (stream-rest s) (make-do-sequence (λ () (define-values (more? next) (sequence-generate s)) (unless (more?) - (error 'seqn-rest "expects a sequence with at least one element")) + (error 'stream-rest "expects a sequence with at least one element")) (next) (values (λ (pos) (next)) @@ -64,16 +64,16 @@ (λ _ #t) (λ _ #t))))) - (define (seqn-length s) + (define (stream-length s) (define-values (more? next) (sequence-generate s)) (let loop ([i 0]) (if (more?) (begin (next) (loop (add1 i))) i))) - (define (seqn-ref s i) + (define (stream-ref s i) (unless (and (exact-integer? i) (i . >= . 0)) - (error 'seqn-ref "expects an exact non-negative index, but got ~e" i)) + (error 'stream-ref "expects an exact non-negative index, but got ~e" i)) (define-values (more? next) (sequence-generate s)) (let loop ([n i]) (cond @@ -83,18 +83,18 @@ (next) (loop (sub1 n))] [else - (error 'seqn-ref "expects a sequence with at least ~e element(s)" i)]))) + (error 'stream-ref "expects a sequence with at least ~e element(s)" i)]))) - (define (seqn-tail s i) + (define (stream-tail s i) (unless (and (exact-integer? i) (i . >= . 0)) - (error 'seqn-tail "expects an exact non-negative index, but got ~e" i)) + (error 'stream-tail "expects an exact non-negative index, but got ~e" i)) (make-do-sequence (λ () (define-values (more? next) (sequence-generate s)) (let loop ([n i]) (unless (zero? n) (unless (more?) - (error 'seqn-tail "expects a sequence with at least ~e element(s)" i)) + (error 'stream-tail "expects a sequence with at least ~e element(s)" i)) (next) (loop (sub1 n)))) (values @@ -105,7 +105,7 @@ (λ _ #t) (λ _ #t))))) - (define (-seqn-append s0 l) + (define (-stream-append s0 l) (if (null? l) s0 (make-do-sequence @@ -133,14 +133,14 @@ (λ _ #t) (λ _ #t)))))) - (define (seqn-append . l) + (define (stream-append . l) (unless (andmap sequence? l) - (error 'seqn-append "expects only sequence arguments, given ~e" l)) - (-seqn-append empty-seqn l)) + (error 'stream-append "expects only sequence arguments, given ~e" l)) + (-stream-append empty-stream l)) - (define (seqn-map f s) + (define (stream-map f s) (unless (procedure? f) - (error 'seqn-map "expects a procedure as the first argument, given ~e" f)) + (error 'stream-map "expects a procedure as the first argument, given ~e" f)) (make-do-sequence (λ () (define-values (more? next) (sequence-generate s)) @@ -152,37 +152,37 @@ (λ _ #t) (λ _ #t))))) - (define (seqn-andmap f s) + (define (stream-andmap f s) (define-values (more? next) (sequence-generate s)) (let loop () (if (more?) (and (call-with-values next f) (loop)) #t))) - (define (seqn-ormap f s) + (define (stream-ormap f s) (define-values (more? next) (sequence-generate s)) (let loop () (if (more?) (or (call-with-values next f) (loop)) #f))) - (define (seqn-for-each f s) + (define (stream-for-each f s) (define-values (more? next) (sequence-generate s)) (let loop () (when (more?) (call-with-values next f) (loop)))) - (define (seqn-fold f i s) + (define (stream-fold f i s) (define-values (more? next) (sequence-generate s)) (let loop ([i i]) (if (more?) (loop (call-with-values next (λ e (apply f i e)))) i))) - (define (seqn-filter f s) + (define (stream-filter f s) (unless (procedure? f) - (error 'seqn-filter "expects a procedure as the first argument, given ~e" f)) + (error 'stream-filter "expects a procedure as the first argument, given ~e" f)) (make-do-sequence (λ () (define-values (more? next) (sequence-generate s)) @@ -204,7 +204,7 @@ (λ _ #t) (λ _ #t))))) - (define (seqn-add-between s e) + (define (stream-add-between s e) (make-do-sequence (λ () (define-values (more? next) (sequence-generate s)) @@ -222,9 +222,9 @@ (λ _ #t) (λ _ #t))))) - (define (seqn-count f s) + (define (stream-count f s) (unless (procedure? f) - (error 'seqn-count "expects a procedure as the first argument, given ~e" f)) + (error 'stream-count "expects a procedure as the first argument, given ~e" f)) (define-values (more? next) (sequence-generate s)) (let loop ([n 0]) (if (more?) @@ -233,20 +233,20 @@ (loop n)) n))) - (provide empty-seqn - seqn->list - seqn-cons - seqn-first - seqn-rest - seqn-length - seqn-ref - seqn-tail - seqn-append - seqn-map - seqn-andmap - seqn-ormap - seqn-for-each - seqn-fold - seqn-filter - seqn-add-between - seqn-count)) \ No newline at end of file + (provide empty-stream + stream->list + stream-cons + stream-first + stream-rest + stream-length + stream-ref + stream-tail + stream-append + stream-map + stream-andmap + stream-ormap + stream-for-each + stream-fold + stream-filter + stream-add-between + stream-count)) diff --git a/collects/scribblings/reference/sequences.scrbl b/collects/scribblings/reference/sequences.scrbl index bd11e88f71..fadcc00919 100644 --- a/collects/scribblings/reference/sequences.scrbl +++ b/collects/scribblings/reference/sequences.scrbl @@ -326,86 +326,86 @@ in the sequence. @; ---------------------------------------------------------------------- @section{Additional Sequence Operations} -@defthing[empty-seqn sequence?]{ +@defthing[empty-stream sequence?]{ A sequence with no elements.} -@defproc[(seqn->list [s sequence?]) list?]{ +@defproc[(stream->list [s sequence?]) list?]{ Returns a list whose elements are the elements of the @scheme[s], which must be a one-valued sequence. If @scheme[s] is infinite, this function does not terminate.} -@defproc[(seqn-cons [v any/c] - ... - [s sequence?]) +@defproc[(stream-cons [v any/c] + ... + [s sequence?]) sequence?]{ Returns a sequence whose first element is @scheme[(values v ...)] and whose remaining elements are the same as @scheme[s].} -@defproc[(seqn-first [s sequence?]) +@defproc[(stream-first [s sequence?]) (values any/c ...)]{ Returns the first element of @scheme[s].} -@defproc[(seqn-rest [s sequence?]) +@defproc[(stream-rest [s sequence?]) sequence?]{ Returns a sequence equivalent to @scheme[s], except the first element is omitted.} -@defproc[(seqn-length [s sequence?]) +@defproc[(stream-length [s sequence?]) exact-nonnegative-integer?]{ Returns the number of elements of @scheme[s]. If @scheme[s] is infinite, this function does not terminate.} -@defproc[(seqn-ref [s sequence?] [i exact-nonnegative-integer?]) +@defproc[(stream-ref [s sequence?] [i exact-nonnegative-integer?]) (values any/c ...)]{ Returns the @scheme[i]th element of @scheme[s].} -@defproc[(seqn-tail [s sequence?] [i exact-nonnegative-integer?]) +@defproc[(stream-tail [s sequence?] [i exact-nonnegative-integer?]) sequence?]{ Returns a sequence equivalent to @scheme[s], except the first @scheme[i] elements are omitted.} -@defproc[(seqn-append [s sequence?] ...) +@defproc[(stream-append [s sequence?] ...) sequence?]{ Returns a sequence that contains all elements of each sequence in the order they appear in the original sequences. The new sequence is constructed lazily.} -@defproc[(seqn-map [f procedure?] - [s sequence?]) +@defproc[(stream-map [f procedure?] + [s sequence?]) sequence?]{ Returns a sequence that contains @scheme[f] applied to each element of @scheme[s]. The new sequence is constructed lazily.} -@defproc[(seqn-andmap [f (-> any/c ... boolean?)] - [s sequence?]) +@defproc[(stream-andmap [f (-> any/c ... boolean?)] + [s sequence?]) boolean?]{ Returns @scheme[#t] if @scheme[f] returns a true result on every element of @scheme[s]. If @scheme[s] is infinite and @scheme[f] never returns a false result, this function does not terminate.} -@defproc[(seqn-ormap [f (-> any/c ... boolean?)] - [s sequence?]) +@defproc[(stream-ormap [f (-> any/c ... boolean?)] + [s sequence?]) boolean?]{ Returns @scheme[#t] if @scheme[f] returns a true result on some element of @scheme[s]. If @scheme[s] is infinite and @scheme[f] never returns a true result, this function does not terminate.} -@defproc[(seqn-for-each [f (-> any/c ... any)] - [s sequence?]) +@defproc[(stream-for-each [f (-> any/c ... any)] + [s sequence?]) (void)]{ Applies @scheme[f] to each element of @scheme[s]. If @scheme[s] is infinite, this function does not terminate.} -@defproc[(seqn-fold [f (-> any/c any/c ... any/c)] - [i any/c] - [s sequence?]) +@defproc[(stream-fold [f (-> any/c any/c ... any/c)] + [i any/c] + [s sequence?]) (void)]{ Folds @scheme[f] over each element of @scheme[s] with @scheme[i] as the initial accumulator. If @scheme[s] is infinite, this function does not terminate.} -@defproc[(seqn-filter [f (-> any/c ... boolean?)] - [s sequence?]) +@defproc[(stream-filter [f (-> any/c ... boolean?)] + [s sequence?]) sequence?]{ Returns a sequence whose elements are the elements of @scheme[s] for which @scheme[f] returns a true result. Although the new sequence is @@ -414,13 +414,13 @@ in the sequence. @scheme[f] returns a true result then operations on this sequence will not terminate during that infinite sub-sequence.} -@defproc[(seqn-add-between [s sequence?] [e any/c]) +@defproc[(stream-add-between [s sequence?] [e any/c]) sequence?]{ Returns a sequence whose elements are the elements of @scheme[s] except in between each is @scheme[e]. The new sequence is constructed lazily.} -@defproc[(seqn-count [f procedure?] [s sequence?]) +@defproc[(stream-count [f procedure?] [s sequence?]) exact-nonnegative-integer?]{ Returns the number of elements in @scheme[s] for which @scheme[f] returns a true result. If @scheme[s] is infinite, this function does diff --git a/collects/tests/racket/for.rktl b/collects/tests/racket/for.rktl index d03c478227..36d10bb1e0 100644 --- a/collects/tests/racket/for.rktl +++ b/collects/tests/racket/for.rktl @@ -352,105 +352,110 @@ ;; New operators (require racket/private/sequence) -(test '(0 1 2) 'seqn->list (seqn->list (in-range 3))) -(arity-test seqn->list 1 1) -(err/rt-test (seqn->list 1)) +(test '(0 1 2) 'stream->list (stream->list (in-range 3))) +(arity-test stream->list 1 1) +(err/rt-test (stream->list 1)) -(test '() 'empty-seqn (seqn->list empty-seqn)) +(test '() 'empty-stream (stream->list empty-stream)) ; XXX How do I check rest arity? -(test '(0 1 2) 'seqn-cons (seqn->list (seqn-cons 0 (in-range 1 3)))) -(test '((0 1)) 'seqn-cons - (for/list ([(a b) (seqn-cons 0 1 empty-seqn)]) +(test '(0 1 2) 'stream-cons (stream->list (stream-cons 0 (in-range 1 3)))) +(test '((0 1)) 'stream-cons + (for/list ([(a b) (stream-cons 0 1 empty-stream)]) (list a b))) -(arity-test seqn-first 1 1) -(err/rt-test (seqn-first 1)) -(test 0 'seqn-first (seqn-first (in-naturals))) +(arity-test stream-first 1 1) +(err/rt-test (stream-first 1)) +(test 0 'stream-first (stream-first (in-naturals))) (test #t - 'seqn-first + 'stream-first (equal? (list 0 1) (call-with-values (λ () - (seqn-first (seqn-cons 0 1 empty-seqn))) + (stream-first (stream-cons 0 1 empty-stream))) (λ args args)))) -(arity-test seqn-rest 1 1) -(test '(1 2) 'seqn-rest (seqn->list (seqn-rest (in-range 3)))) +(arity-test stream-rest 1 1) +(test '(1 2) 'stream-rest (stream->list (stream-rest (in-range 3)))) -(arity-test seqn-length 1 1) -(err/rt-test (seqn-length 1)) -(test 3 'seqn-length (seqn-length (in-range 3))) -(test 3 'seqn-length (seqn-length #hasheq((1 . 'a) (2 . 'b) (3 . 'c)))) +(arity-test stream-length 1 1) +(err/rt-test (stream-length 1)) +(test 3 'stream-length (stream-length (in-range 3))) +(test 3 'stream-length (stream-length #hasheq((1 . 'a) (2 . 'b) (3 . 'c)))) -(arity-test seqn-ref 2 2) -(err/rt-test (seqn-ref 2 0)) -(err/rt-test (seqn-ref (in-naturals) -1) exn:fail?) -(err/rt-test (seqn-ref (in-naturals) 1.0) exn:fail?) -(test 0 'seqn-ref (seqn-ref (in-naturals) 0)) -(test 1 'seqn-ref (seqn-ref (in-naturals) 1)) -(test 25 'seqn-ref (seqn-ref (in-naturals) 25)) +(arity-test stream-ref 2 2) +(err/rt-test (stream-ref 2 0)) +(err/rt-test (stream-ref (in-naturals) -1) exn:fail?) +(err/rt-test (stream-ref (in-naturals) 1.0) exn:fail?) +(test 0 'stream-ref (stream-ref (in-naturals) 0)) +(test 1 'stream-ref (stream-ref (in-naturals) 1)) +(test 25 'stream-ref (stream-ref (in-naturals) 25)) -(arity-test seqn-tail 2 2) -(err/rt-test (seqn-tail (in-naturals) -1) exn:fail?) -(err/rt-test (seqn-tail (in-naturals) 1.0) exn:fail?) -(test 4 'seqn-ref (seqn-ref (seqn-tail (in-naturals) 4) 0)) -(test 5 'seqn-ref (seqn-ref (seqn-tail (in-naturals) 4) 1)) -(test 29 'seqn-ref (seqn-ref (seqn-tail (in-naturals) 4) 25)) +(arity-test stream-tail 2 2) +(err/rt-test (stream-tail (in-naturals) -1) exn:fail?) +(err/rt-test (stream-tail (in-naturals) 1.0) exn:fail?) +(test 4 'stream-ref (stream-ref (stream-tail (in-naturals) 4) 0)) +(test 5 'stream-ref (stream-ref (stream-tail (in-naturals) 4) 1)) +(test 29 'stream-ref (stream-ref (stream-tail (in-naturals) 4) 25)) ; XXX Check for rest -(err/rt-test (seqn-append 1) exn:fail?) -(err/rt-test (seqn-append (in-naturals) 1) exn:fail?) -(test '() 'seqn-append (seqn->list (seqn-append))) -(test 5 'seqn-append (seqn-ref (seqn-append (in-naturals)) 5)) -(test 5 'seqn-append (seqn-ref (seqn-append (in-range 3) (in-range 3 10)) 5)) +(err/rt-test (stream-append 1) exn:fail?) +(err/rt-test (stream-append (in-naturals) 1) exn:fail?) +(test '() 'stream-append (stream->list (stream-append))) +(test 5 'stream-append (stream-ref (stream-append (in-naturals)) 5)) +(test 5 'stream-append + (stream-ref (stream-append (in-range 3) (in-range 3 10)) 5)) -(arity-test seqn-map 2 2) -(err/rt-test (seqn-map 2 (in-naturals)) exn:fail?) -(test '(1 2 3) 'seqn-map (seqn->list (seqn-map add1 (in-range 3)))) -(test 3 'seqn-map (seqn-ref (seqn-map add1 (in-naturals)) 2)) +(arity-test stream-map 2 2) +(err/rt-test (stream-map 2 (in-naturals)) exn:fail?) +(test '(1 2 3) 'stream-map (stream->list (stream-map add1 (in-range 3)))) +(test 3 'stream-map (stream-ref (stream-map add1 (in-naturals)) 2)) -(arity-test seqn-andmap 2 2) -(err/rt-test (seqn-andmap 2 (in-naturals))) -(test #t 'seqn-andmap (seqn-andmap even? (seqn-cons 2 empty-seqn))) -(test #f 'seqn-andmap (seqn-andmap even? (in-naturals))) +(arity-test stream-andmap 2 2) +(err/rt-test (stream-andmap 2 (in-naturals))) +(test #t 'stream-andmap (stream-andmap even? (stream-cons 2 empty-stream))) +(test #f 'stream-andmap (stream-andmap even? (in-naturals))) -(arity-test seqn-ormap 2 2) -(err/rt-test (seqn-ormap 2 (in-naturals))) -(test #t 'seqn-ormap (seqn-ormap even? (seqn-cons 2 empty-seqn))) -(test #f 'seqn-ormap (seqn-ormap even? (seqn-cons 1 empty-seqn))) -(test #t 'seqn-ormap (seqn-ormap even? (in-naturals))) +(arity-test stream-ormap 2 2) +(err/rt-test (stream-ormap 2 (in-naturals))) +(test #t 'stream-ormap (stream-ormap even? (stream-cons 2 empty-stream))) +(test #f 'stream-ormap (stream-ormap even? (stream-cons 1 empty-stream))) +(test #t 'stream-ormap (stream-ormap even? (in-naturals))) -(arity-test seqn-for-each 2 2) -(err/rt-test (seqn-for-each 2 (in-naturals))) +(arity-test stream-for-each 2 2) +(err/rt-test (stream-for-each 2 (in-naturals))) (test (vector 0 1 2) - 'seqn-for-each + 'stream-for-each (let ([v (vector #f #f #f)]) - (seqn-for-each (λ (i) (vector-set! v i i)) (in-range 3)) + (stream-for-each (λ (i) (vector-set! v i i)) (in-range 3)) v)) -(arity-test seqn-fold 3 3) -(err/rt-test (seqn-fold 2 (in-naturals) 0)) -(test 6 'seqn-fold (seqn-fold + 0 (in-range 4))) +(arity-test stream-fold 3 3) +(err/rt-test (stream-fold 2 (in-naturals) 0)) +(test 6 'stream-fold (stream-fold + 0 (in-range 4))) -(arity-test seqn-filter 2 2) -(err/rt-test (seqn-filter 2 (in-naturals)) exn:fail?) -(test 4 'seqn-filter (seqn-ref (seqn-filter even? (in-naturals)) 2)) +(arity-test stream-filter 2 2) +(err/rt-test (stream-filter 2 (in-naturals)) exn:fail?) +(test 4 'stream-filter (stream-ref (stream-filter even? (in-naturals)) 2)) -(arity-test seqn-add-between 2 2) -(test 0 'seqn-add-between (seqn-ref (seqn-add-between (in-naturals) #t) 0)) -(test #t 'seqn-add-between (seqn-ref (seqn-add-between (in-naturals) #t) 1)) -(test 1 'seqn-add-between (seqn-ref (seqn-add-between (in-naturals) #t) 2)) -(test #t 'seqn-add-between (seqn-ref (seqn-add-between (in-naturals) #t) 3)) +(arity-test stream-add-between 2 2) +(test 0 'stream-add-between + (stream-ref (stream-add-between (in-naturals) #t) 0)) +(test #t 'stream-add-between + (stream-ref (stream-add-between (in-naturals) #t) 1)) +(test 1 'stream-add-between + (stream-ref (stream-add-between (in-naturals) #t) 2)) +(test #t 'stream-add-between + (stream-ref (stream-add-between (in-naturals) #t) 3)) -(arity-test seqn-count 2 2) -(test 0 'seqn-count (seqn-count even? empty-seqn)) -(test 1 'seqn-count (seqn-count even? (in-range 1))) -(test 5 'seqn-count (seqn-count even? (in-range 10))) +(arity-test stream-count 2 2) +(test 0 'stream-count (stream-count even? empty-stream)) +(test 1 'stream-count (stream-count even? (in-range 1))) +(test 5 'stream-count (stream-count even? (in-range 10))) (let* ([r (random 100)] [a (if (even? r) (/ r 2) (ceiling (/ r 2)))]) - (test a 'seqn-count (seqn-count even? (in-range r)))) + (test a 'stream-count (stream-count even? (in-range r)))) (report-errs) diff --git a/collects/tests/racket/stress/sequence.rkt b/collects/tests/racket/stress/sequence.rkt index 229c57220a..ebbca86f48 100644 --- a/collects/tests/racket/stress/sequence.rkt +++ b/collects/tests/racket/stress/sequence.rkt @@ -1,12 +1,13 @@ #lang racket (require tests/stress) -; seqn-first -; This ignores the greater flexiblity of seqn-first to have more than single-valued sequences +;; stream-first +;; This ignores the greater flexiblity of stream-first to have more than +;; single-valued sequences (stress 200 - ["seqn-first" - (seqn-first (in-naturals))] + ["stream-first" + (stream-first (in-naturals))] ["for/or (val)" (define s (in-naturals)) (for/or ([n s]) @@ -15,12 +16,12 @@ (for/or ([n (in-naturals)]) n)]) -; seqn-length -; The for/fold must be rewritten slightly differently for multi-valued +;; stream-length +;; The for/fold must be rewritten slightly differently for multi-valued (stress 20 - ["seqn-length" - (seqn-length (in-range 2000))] + ["stream-length" + (stream-length (in-range 2000))] ["for/fold (val)" (define s (in-range 2000)) (for/fold ([len 0]) @@ -31,12 +32,12 @@ ([i (in-range 2000)]) (add1 len))]) -; seqn-ref -; Ditto +;; stream-ref +;; Ditto (stress 20 - ["seqn-ref" - (seqn-ref (in-range 2000) 200)] + ["stream-ref" + (stream-ref (in-range 2000) 200)] ["for/or val" (define s (in-range 2000)) (for/or ([e s] @@ -49,12 +50,12 @@ #:when (i . = . 199)) e)]) -; seqn-andmap -; ditto +;; stream-andmap +;; ditto (stress 20 - ["seqn-andmap" - (seqn-andmap number? (in-range 2000))] + ["stream-andmap" + (stream-andmap number? (in-range 2000))] ["for/and val" (define s (in-range 2000)) (for/and ([e s]) @@ -63,12 +64,12 @@ (for/and ([e (in-range 2000)]) (number? e))]) -; seqn-ormap -; ditto +;; stream-ormap +;; ditto (stress 20 - ["seqn-ormap" - (seqn-ormap string? (in-range 2000))] + ["stream-ormap" + (stream-ormap string? (in-range 2000))] ["for/and val" (define s (in-range 2000)) (for/or ([e s]) @@ -77,12 +78,12 @@ (for/or ([e (in-range 2000)]) (string? e))]) -; seqn-fold -; The for/fold must be rewritten slightly differently for multi-valued +;; stream-fold +;; The for/fold must be rewritten slightly differently for multi-valued (stress 20 - ["seqn-fold" - (seqn-fold + 0 (in-range 2000))] + ["stream-fold" + (stream-fold + 0 (in-range 2000))] ["for/fold (val)" (define s (in-range 2000)) (for/fold ([sum 0]) @@ -93,12 +94,12 @@ ([i (in-range 2000)]) (+ i sum))]) -; seqn-count -; The for/fold must be rewritten slightly differently for multi-valued +;; stream-count +;; The for/fold must be rewritten slightly differently for multi-valued (stress 20 - ["seqn-count" - (seqn-count even? (in-range 2000))] + ["stream-count" + (stream-count even? (in-range 2000))] ["for/fold (val)" (define s (in-range 2000)) (for/fold ([num 0]) @@ -110,4 +111,3 @@ ([i (in-range 2000)] #:when (even? i)) (add1 num))]) - From ddf8fadf182f7824be10918268b45d6cb7f11f5b Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 21 Oct 2010 19:48:00 -0400 Subject: [PATCH 035/746] Rename `sequence' library to `stream', move from `racket/base' to `racket'. (cherry picked from commit 9e302a7106f5cbfe3e08c2d6ae17775ce70ac8f6) --- collects/racket/main.rkt | 2 ++ collects/racket/private/base.rkt | 7 ++----- .../racket/{private/sequence.rkt => stream.rkt} | 4 ++-- collects/scribblings/reference/pairs.scrbl | 15 ++++++++++----- collects/scribblings/reference/sequences.scrbl | 12 +++++++----- 5 files changed, 23 insertions(+), 17 deletions(-) rename collects/racket/{private/sequence.rkt => stream.rkt} (99%) diff --git a/collects/racket/main.rkt b/collects/racket/main.rkt index b83e18b372..dbd5f73fc9 100644 --- a/collects/racket/main.rkt +++ b/collects/racket/main.rkt @@ -23,6 +23,7 @@ racket/cmdline racket/promise racket/bool + racket/stream racket/local racket/system (for-syntax racket/base)) @@ -50,6 +51,7 @@ racket/cmdline racket/promise racket/bool + racket/stream racket/local racket/system) (for-syntax (all-from-out racket/base))) diff --git a/collects/racket/private/base.rkt b/collects/racket/private/base.rkt index 34b54f8c04..a1e784a333 100644 --- a/collects/racket/private/base.rkt +++ b/collects/racket/private/base.rkt @@ -1,7 +1,6 @@ (module base "pre-base.rkt" - - (#%require "sequence.rkt" - "hash.rkt" + + (#%require "hash.rkt" "list.rkt" "string.rkt" "stxcase-scheme.rkt" @@ -23,7 +22,6 @@ regexp-replace* new-apply-proc) struct - (all-from "sequence.rkt") (all-from "hash.rkt") (all-from "list.rkt") (all-from-except "string.rkt" @@ -43,4 +41,3 @@ (rename -with-output-to-file with-output-to-file) call-with-input-file* call-with-output-file*)) - diff --git a/collects/racket/private/sequence.rkt b/collects/racket/stream.rkt similarity index 99% rename from collects/racket/private/sequence.rkt rename to collects/racket/stream.rkt index 425ce1fdf0..188adc85d2 100644 --- a/collects/racket/private/sequence.rkt +++ b/collects/racket/stream.rkt @@ -1,5 +1,5 @@ -(module sequence "pre-base.rkt" - (require "list.rkt") +(module stream "private/pre-base.rkt" + (require "private/list.rkt") (define empty-stream (make-do-sequence diff --git a/collects/scribblings/reference/pairs.scrbl b/collects/scribblings/reference/pairs.scrbl index 28abda429d..ad003860ae 100644 --- a/collects/scribblings/reference/pairs.scrbl +++ b/collects/scribblings/reference/pairs.scrbl @@ -668,29 +668,34 @@ Like @scheme[assoc], but finds an element using the predicate @(interaction-eval #:eval list-eval (require racket/list (only-in racket/function negate))) -@defthing[empty null?]{The empty list. +@defthing[empty null?]{ +The empty list. @mz-examples[#:eval list-eval empty (eq? empty null) ]} -@defproc[(cons? [v any/c]) boolean?]{The same as @scheme[(pair? v)]. +@defproc[(cons? [v any/c]) boolean?]{ +The same as @scheme[(pair? v)]. @mz-examples[#:eval list-eval (cons? '(1 2)) ]} -@defproc[(empty? [v any/c]) boolean?]{The same as @scheme[(null? v)]. +@defproc[(empty? [v any/c]) boolean?]{ +The same as @scheme[(null? v)]. @mz-examples[#:eval list-eval (empty? '(1 2)) (empty? '()) ]} -@defproc[(first [lst list?]) any/c]{The same as @scheme[(car lst)], but only for lists (that are not empty). +@defproc[(first [lst list?]) any/c]{ +The same as @scheme[(car lst)], but only for lists (that are not empty). @mz-examples[#:eval list-eval (first '(1 2 3 4 5 6 7 8 9 10)) ]} -@defproc[(rest [lst list?]) list?]{The same as @scheme[(cdr lst)], but only for lists (that are not empty). +@defproc[(rest [lst list?]) list?]{ +The same as @scheme[(cdr lst)], but only for lists (that are not empty). @mz-examples[#:eval list-eval (rest '(1 2 3 4 5 6 7 8 9 10)) diff --git a/collects/scribblings/reference/sequences.scrbl b/collects/scribblings/reference/sequences.scrbl index fadcc00919..603271f5c1 100644 --- a/collects/scribblings/reference/sequences.scrbl +++ b/collects/scribblings/reference/sequences.scrbl @@ -5,11 +5,6 @@ (for-label racket/generator racket/mpair)) -@(define generator-eval - (let ([the-eval (make-base-eval)]) - (the-eval '(require racket/generator)) - the-eval)) - @(define (info-on-seq where what) @margin-note{See @secref[where] for information on using @|what| as sequences.}) @@ -326,6 +321,8 @@ in the sequence. @; ---------------------------------------------------------------------- @section{Additional Sequence Operations} +@note-lib[racket/stream] + @defthing[empty-stream sequence?]{ A sequence with no elements.} @@ -441,6 +438,11 @@ in the sequence. @section{Iterator Generators} @defmodule[racket/generator] +@(define generator-eval + (let ([the-eval (make-base-eval)]) + (the-eval '(require racket/generator)) + the-eval)) + @defform[(generator () body ...)]{ Creates a function that returns a value through @scheme[yield], each time it is invoked. When the generator runs out of values to yield, From 750676a78c06891677a1e84c37ec6ececcd71df6 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 21 Oct 2010 20:25:37 -0400 Subject: [PATCH 036/746] Fix require in test suite (cherry picked from commit aebf9e77eff197049f5201785d3a37877a79aa2a) --- collects/tests/racket/for.rktl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/tests/racket/for.rktl b/collects/tests/racket/for.rktl index 36d10bb1e0..378936c9e8 100644 --- a/collects/tests/racket/for.rktl +++ b/collects/tests/racket/for.rktl @@ -350,7 +350,7 @@ (maker) (maker) (maker)))) ;; New operators -(require racket/private/sequence) +(require racket/stream) (test '(0 1 2) 'stream->list (stream->list (in-range 3))) (arity-test stream->list 1 1) From b845c05e7db6e805806fd0a93792126b9d5da41f Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 21 Oct 2010 20:50:57 -0400 Subject: [PATCH 037/746] Another "/proj/scheme/" -> "/proj/racket" change. (cherry picked from commit f51fd94412c009957db4c61f18801d3c900748f8) --- collects/meta/build/build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index d642f1457c..5282ae073a 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -76,7 +76,7 @@ defbuild() { # required). Warning: an `eval "foo=\"bar\""' is used to assign values. msets "/machines/D" "workdir=/var/tmp" "moveto=" "copytobak=" \ "configure_args=" "LDFLAGS=" "ext_lib_paths=" "renice=" -# defbuild "ccs-solaris" "sparc-solaris" "moveto=/proj/scheme" \ +# defbuild "ccs-solaris" "sparc-solaris" "moveto=/proj/racket" \ # "ext_lib_paths=/arch/unix/packages/openssl-0.9.7e" defbuild "pitcairn" "i386-win32" \ "workdir=f:" # no "/..." path (that can get interpreted as a flag) @@ -90,7 +90,7 @@ defbuild "macintel" "i386-osx-mac" \ "configure_args=--enable-sdk=/Developer/SDKs/MacOSX10.4u.sdk" # defbuild "galaga" "i386-linux-ubuntu-hardy" defbuild "champlain" "i386-linux-f12" -defbuild "ccs-linux" "i386-linux-ubuntu-jaunty" "moveto=/proj/scheme" +defbuild "ccs-linux" "i386-linux-ubuntu-jaunty" "moveto=/proj/racket" # defbuild "punge" "i386-linux-ubuntu-jaunty" "renice=20" # defbuild "bjorn" "i386-linux-gcc2" # defbuild "chicago" "i386-linux-debian" From b7ccf8d91ece9d6729bdb99b4100173d3f3514c7 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 22 Oct 2010 14:43:58 -0500 Subject: [PATCH 038/746] fixed an (apparently VERY old) problem with lights out and the built-in boards please merge to release branch (cherry picked from commit 4f236386a97684fb622e96452564d0abec6acd14) --- collects/games/lights-out/board.rkt | 18 ++-- collects/games/lights-out/boards.rkt | 129 ++++++++++++++------------- 2 files changed, 79 insertions(+), 68 deletions(-) diff --git a/collects/games/lights-out/board.rkt b/collects/games/lights-out/board.rkt index 46f922b707..bda7a8b7ba 100644 --- a/collects/games/lights-out/board.rkt +++ b/collects/games/lights-out/board.rkt @@ -51,11 +51,14 @@ 6)] [button-panel (make-object horizontal-panel% dialog)] [cancel? #t] - [ok (make-object button% "OK" - button-panel - (lambda x - (set! cancel? #f) - (send dialog show #f)))] + [ok (new button% + [label "OK"] + [parent button-panel] + [style '(border)] + [callback + (lambda x + (set! cancel? #f) + (send dialog show #f))])] [cancel (make-object button% "Cancel" button-panel (lambda x @@ -76,9 +79,12 @@ (send random-slider get-value) (lambda (x) (make-vector (send random-slider get-value) 'o)))] [(prebuilt) - (board-board (list-ref boards (send prebuilt get-selection)))])))) + (to-vectors (board-board (list-ref boards (send prebuilt get-selection))))])))) (new-board))) + (define (to-vectors lsts) + (apply vector (map (λ (x) (apply vector x)) lsts))) + '(define (build-vector n f) (list->vector (let loop ([n n]) diff --git a/collects/games/lights-out/boards.rkt b/collects/games/lights-out/boards.rkt index 1c727ef721..7886fc1ebb 100644 --- a/collects/games/lights-out/boards.rkt +++ b/collects/games/lights-out/boards.rkt @@ -1,64 +1,69 @@ -(module boards mzscheme - (provide boards - (struct board (name board))) +#lang racket/base +(require racket/vector) - (define-struct board (name board)) +(provide boards + (struct-out board)) - (define boards - (list - (make-board - "1" - #(#(o o o o o) - #(o o o o o) - #(x o x o x) - #(o o o o o) - #(o o o o o))) - (make-board - "2" - #(#(x o x o x) - #(x o x o x) - #(o o o o o) - #(x o x o x) - #(x o x o x))) - (make-board - "3" - #(#(o x o x o) - #(x x o x x) - #(x x o x x) - #(x x o x x) - #(o x o x o))) - (make-board - "4" - #(#(o o o o o) - #(x x o x x) - #(o o o o o) - #(x o o o x) - #(x x o x x))) - (make-board - "5" - #(#(x x x x o) - #(x x x o x) - #(x x x o x) - #(o o o x x) - #(x x o x x))) - (make-board - "6" - #(#(o o o o o) - #(o o o o o) - #(x o x o x) - #(x o x o x) - #(o x x x o))) - (make-board - "7" - #(#(x x x x o) - #(x o o o x) - #(x o o o x) - #(x o o o x) - #(x x x x o))) - (make-board - "Diagonal" - #(#(o o o o x) - #(o o o x o) - #(o o x o o) - #(o x o o o) - #(x o o o o)))))) +(define-struct board (name board)) + +(define (build-board name vec) + (make-board name (vector-map vector-copy vec))) + +(define boards + (list + (make-board + "1" + '((o o o o o) + (o o o o o) + (x o x o x) + (o o o o o) + (o o o o o))) + (make-board + "2" + '((x o x o x) + (x o x o x) + (o o o o o) + (x o x o x) + (x o x o x))) + (make-board + "3" + '((o x o x o) + (x x o x x) + (x x o x x) + (x x o x x) + (o x o x o))) + (make-board + "4" + '((o o o o o) + (x x o x x) + (o o o o o) + (x o o o x) + (x x o x x))) + (make-board + "5" + '((x x x x o) + (x x x o x) + (x x x o x) + (o o o x x) + (x x o x x))) + (make-board + "6" + '((o o o o o) + (o o o o o) + (x o x o x) + (x o x o x) + (o x x x o))) + (make-board + "7" + '((x x x x o) + (x o o o x) + (x o o o x) + (x o o o x) + (x x x x o))) + (make-board + "Diagonal" + '((o o o o x) + (o o o x o) + (o o x o o) + (o x o o o) + (x o o o o))))) From 14222dc0e46f8cf84f9bf7933169e061bc660cc9 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 22 Oct 2010 14:47:55 -0500 Subject: [PATCH 039/746] rleease notes. please merge to release branch. (cherry picked from commit aa056efb7487806953bbb623e0b0cb23a3c77e24) --- doc/release-notes/drracket/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes/drracket/HISTORY.txt b/doc/release-notes/drracket/HISTORY.txt index 93a6c473df..e2fe0a551d 100644 --- a/doc/release-notes/drracket/HISTORY.txt +++ b/doc/release-notes/drracket/HISTORY.txt @@ -1,3 +1,7 @@ +------------------------------ + Version 5.0.2 +------------------------------ + . Added image->color-list and color-list->bitmap to 2htdp/image From c0f1013b51c172b7be29d45dc5284b4baf8697e0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 22 Oct 2010 14:07:12 -0600 Subject: [PATCH 040/746] adjust release notes for 5.0.2 Merge to 5.0.2 (cherry picked from commit 0b73790ac0097cad30281471833f61df25184463) --- doc/release-notes/gracket/HISTORY.txt | 6 ++++++ doc/release-notes/racket/HISTORY.txt | 21 ++++++--------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/doc/release-notes/gracket/HISTORY.txt b/doc/release-notes/gracket/HISTORY.txt index ccd6fb4f81..51602102b3 100644 --- a/doc/release-notes/gracket/HISTORY.txt +++ b/doc/release-notes/gracket/HISTORY.txt @@ -1,3 +1,9 @@ +Version 5.0.2, October 2010 + +Minor bug fixes + +---------------------------------------------------------------------- + Version 5.0.1, July 2010 Minor bug fixes diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index 77a95f3de8..0f6925afc5 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,6 +1,8 @@ -Version 5.0.1.8 +Version 5.0.2, October 2010 Changed body of `when', `unless', `cond' clauses, `case' clauses, and `match' clauses to be internal-definition contexts +Added ->i to the contract library, improved ->*, adding #:pre and + #:post, as well as making the optional arguments clause optional. Added #true and #false, and changed #t/#T and #f/#F to require a delimiter afterward Added print-boolean-long-form @@ -9,25 +11,14 @@ Added read-accept-lang, which is set to #t when Added flonum? Changed continuation-marks to accept a #f argument to produce an empty set of marks - -Version 5.0.1.7 Added fxvectors Added unsafe-{s,u}16-{ref,set!} - -Version 5.0.1.6 Added prop:proxy-of - -Version 5.0.1.5 Added proxies to go with chaperones, and renamed chaperone property - as proxy property - -Version 5.0.1.3 -Added ->i to the contract library, improved ->*, adding #:pre and - #:post, as well as making the optional arguments clause optional. - -Version 5.0.1.2 + as proxy property; beware that the word "proxy" will change in + a future version, perhaps to "impersonator" Added collection-file-path and collection splicing at the file -level + level Version 5.0.1, July 2010 Continuation barriers now block only downward continuation jumps From 199895e52fdf2e224a0f98a239addf722997179e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 22 Oct 2010 19:43:21 -0600 Subject: [PATCH 041/746] fix PPC JIT `vector-length' Merge to 5.0.2 (cherry picked from commit 93ba544c60b80693bb7d0db3cc8393e44a57b3dc) --- src/racket/src/jit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index e1952071ec..8d32ea8229 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -7051,7 +7051,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in (void)jit_calli(bad_fxvector_length_code); else { (void)jit_calli(bad_vector_length_code); - jit_retval(JIT_R0); + /* can return with updated R0 */ } /* bad_vector_length_code may unpack a proxied object */ @@ -8725,7 +8725,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int mz_rs_sync(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); mz_prepare(0); - mz_finish(scheme_current_future); + (void)mz_finish(scheme_current_future); jit_retval(JIT_R0); return 1; } else if (!for_branch) { From 617daddbd738792e8e02c5cba4a39bdc3ac496cb Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 22 Oct 2010 21:19:18 -0600 Subject: [PATCH 042/746] fix bogus reordering of floating-point args in unboxing mode Merge to 5.0.2 Closes PR 11272 (cherry picked from commit c512dbd6d3029c81b5c9e4c203c600837a0bfda6) --- collects/tests/racket/unsafe.rktl | 18 ++++++++++++++++++ src/racket/src/jit.c | 24 +++++++++++++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/collects/tests/racket/unsafe.rktl b/collects/tests/racket/unsafe.rktl index c7cf655afe..f95df45a6e 100644 --- a/collects/tests/racket/unsafe.rktl +++ b/collects/tests/racket/unsafe.rktl @@ -370,4 +370,22 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; A regression test to check that unsafe-fl/ doesn't +;; reorder its arguments when it isn't safe to do so, where the +;; unsafeness of the reordering has to do with safe-for-space +;; clearing of a variable that is used multiple times. + +(let () + (define weird #f) + (set! weird + (lambda (get-M) + (let* ([M (get-M)] + [N1 (unsafe-fl/ M (unsafe-fllog M))]) + (get-M) ; triggers safe-for-space clearing of M + N1))) + + (test 15388.0 floor (* 1000.0 (weird (lambda () 64.0))))) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (report-errs) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index 8d32ea8229..8e93bd77f9 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -2613,7 +2613,8 @@ static int is_constant_and_avoids_r1(Scheme_Object *obj) return (t >= _scheme_compiled_values_types_); } -static int is_relatively_constant_and_avoids_r1(Scheme_Object *obj, Scheme_Object *wrt) +static int is_relatively_constant_and_avoids_r1_maybe_fp(Scheme_Object *obj, Scheme_Object *wrt, + int fp_ok) { Scheme_Type t; @@ -2622,9 +2623,10 @@ static int is_relatively_constant_and_avoids_r1(Scheme_Object *obj, Scheme_Objec t = SCHEME_TYPE(obj); if (SAME_TYPE(t, scheme_local_type)) { - /* Must have clearing, other-clears, or flonum flag set */ + /* Must have clearing, other-clears, or flonum flag set, + otherwise is_constant_and_avoids_r1() would have returned 1. */ if (SCHEME_GET_LOCAL_FLAGS(obj) == SCHEME_LOCAL_FLONUM) - return 0; + return fp_ok; else { Scheme_Type t2 = SCHEME_TYPE(wrt); if (t2 == scheme_local_type) { @@ -2638,6 +2640,18 @@ static int is_relatively_constant_and_avoids_r1(Scheme_Object *obj, Scheme_Objec return 0; } +static int is_relatively_constant_and_avoids_r1(Scheme_Object *obj, Scheme_Object *wrt) +{ + return is_relatively_constant_and_avoids_r1_maybe_fp(obj, wrt, 0); +} + +static int can_reorder_unboxing(Scheme_Object *rand, Scheme_Object *rand2) +{ + /* Can we reorder `rand' and `rand2', given that we want floating-point + results (so it's ok for `rand' to be a floating-point local)? */ + return is_relatively_constant_and_avoids_r1_maybe_fp(rand, rand2, 1); +} + /*========================================================================*/ /* branch info */ /*========================================================================*/ @@ -4778,7 +4792,7 @@ static int can_fast_double(int arith, int cmp, int two_args) #ifdef CAN_INLINE_ALLOC # ifdef JIT_USE_FP_OPS -#define DECL_FP_GLUE(op) static void call_ ## op(void) { save_fp = scheme_double_ ## op(save_fp); } +#define DECL_FP_GLUE(op) static void call_ ## op(void) XFORM_SKIP_PROC { save_fp = scheme_double_ ## op(save_fp); } DECL_FP_GLUE(sin) DECL_FP_GLUE(cos) DECL_FP_GLUE(tan) @@ -5279,7 +5293,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj if (!args_unboxed && rand) scheme_signal_error("internal error: invalid mode"); - if (inlined_flonum1 && !inlined_flonum2) { + if (inlined_flonum1 && !inlined_flonum2 && can_reorder_unboxing(rand, rand2)) { GC_CAN_IGNORE Scheme_Object *tmp; reversed = !reversed; cmp = -cmp; From 2da74632feb5001487488a037996ca6bba982fe7 Mon Sep 17 00:00:00 2001 From: Kevin Tew Date: Fri, 22 Oct 2010 21:21:38 -0600 Subject: [PATCH 043/746] cpuid assembly fix Merge to 5.0.2 (cherry picked from commit c1f2dea1ed9206617b0be9d157c282b638f917ad) --- src/racket/src/future.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/racket/src/future.c b/src/racket/src/future.c index 12900981b5..0b069eb862 100644 --- a/src/racket/src/future.c +++ b/src/racket/src/future.c @@ -546,14 +546,24 @@ void scheme_future_block_until_gc() } # else { +# if defined(i386) || defined(__i386__) +# define MZ_PUSH_EBX "pushl %%ebx" +# define MZ_POP_EBX "popl %%ebx" +# endif +# if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) +# define MZ_PUSH_EBX "pushq %%rbx" +# define MZ_POP_EBX "popq %%rbx" +# endif int _eax, _ebx, _ecx, _edx, op = 0; /* we can't always use EBX, so save and restore it: */ - asm ("pushl %%ebx \n\t" + asm (MZ_PUSH_EBX "\n\t" "cpuid \n\t" "movl %%ebx, %1 \n\t" - "popl %%ebx" + MZ_POP_EBX : "=a" (_eax), "=r" (_ebx), "=c" (_ecx), "=d" (_edx) : "a" (op)); } +# undef MZ_PUSH_EBX +# undef MZ_POP_EBX # endif #endif } From dbddb4a5aee2d224f38db9cbffcd5a288e5170cd Mon Sep 17 00:00:00 2001 From: John Clements Date: Sat, 23 Oct 2010 17:37:39 -0700 Subject: [PATCH 044/746] Updated HISTORY.txt Merge to 5.0.2 (cherry picked from commit f1be08bf1cadaba2b92855b3bea87803e5194e17) --- doc/release-notes/stepper/HISTORY.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/release-notes/stepper/HISTORY.txt b/doc/release-notes/stepper/HISTORY.txt index 109ba9ec59..e3f0cf543e 100644 --- a/doc/release-notes/stepper/HISTORY.txt +++ b/doc/release-notes/stepper/HISTORY.txt @@ -1,5 +1,8 @@ Stepper ------- +Changes for v5.0.2: + +Bug fixes, Big Bang working again. Define-struct in local not working. Changes for v5.0.1: From 48752d84f7af4d4d22227ccba6be59e30e2ef1ef Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 25 Oct 2010 02:42:16 -0400 Subject: [PATCH 045/746] Organize dist-specs; remove bogus collection. Merge to 5.0.2. (cherry picked from commit 91f9f0c2d3d8b8e49b0faab04d167595d40c71ec) --- collects/meta/dist-specs.rkt | 4 +++- collects/mz/private/y.rkt | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 collects/mz/private/y.rkt diff --git a/collects/meta/dist-specs.rkt b/collects/meta/dist-specs.rkt index abade6fcca..31e3ead677 100644 --- a/collects/meta/dist-specs.rkt +++ b/collects/meta/dist-specs.rkt @@ -660,8 +660,10 @@ plt-extras :+= (package: "deinprogramm/") (collects: "teachpack/deinprogramm/") (doc: "DMdA-lib") -;; -------------------- unstable +;; -------------------- data mz-extras :+= (package: "data") + +;; -------------------- unstable mz-extras :+= (- (package: "unstable") ;; should "gui" mean DrRacket or GRacket? It's not ;; obvious that "framework" is only in DrRacket. diff --git a/collects/mz/private/y.rkt b/collects/mz/private/y.rkt deleted file mode 100644 index 1f210949bb..0000000000 --- a/collects/mz/private/y.rkt +++ /dev/null @@ -1,3 +0,0 @@ -#lang racket -(provide y) -(define y 1) From e7a2a3b062bca761a1005aed7ed90171e8223c23 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 25 Oct 2010 06:36:35 -0600 Subject: [PATCH 046/746] fix typo in CPP macro Merge to 5.0.2 (cherry picked from commit 802e27eb85346c77aefdd1bf363414411045c22b) --- src/racket/src/jit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index 8e93bd77f9..451de6772f 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -1872,9 +1872,9 @@ static Scheme_Object *make_two_element_ivector(Scheme_Object *a, Scheme_Object * #ifdef MZ_USE_LWC # ifdef JIT_RUNSTACK_BASE -# define SAVE_RS_BASE_REG(x) jit_stxi_p((int)&((Scheme_Current_LWC *)0x0)->runstack_base_end, JIT_R0, JIT_RUNSTACK_BASE) +# define SAVE_RS_BASE_REG() jit_stxi_p((int)&((Scheme_Current_LWC *)0x0)->runstack_base_end, JIT_R0, JIT_RUNSTACK_BASE) # else -# define SAVE_RS_BASE_REG(x) (void)0 +# define SAVE_RS_BASE_REG() (void)0 # endif # define adjust_lwc_return_address(pc) ((jit_insn *)((char *)(pc) - jit_return_pop_insn_len())) # define mz_finish_lwe(d, refr) (mz_tl_ldi_p(JIT_R0, tl_scheme_current_lwc), \ From 6f2f04b97992a444ee67ba5bcc7199b85860f191 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 25 Oct 2010 10:51:35 -0600 Subject: [PATCH 047/746] swap `vector*-ref' and `vector-ref', etc. Merge to 5.0.2 (cherry picked from commit 5d8e000d6d37cb9a032f4bcf4d82c63d8e51bae1) --- collects/racket/match/compiler.rkt | 6 ++-- collects/racket/private/for.rkt | 6 ++-- collects/racket/vector.rkt | 28 ++++++++-------- collects/scribblings/reference/unsafe.scrbl | 28 ++++++++-------- .../racket/benchmarks/shootout/nbody-vec.rkt | 16 +++++----- collects/tests/racket/unsafe.rktl | 18 +++++------ collects/typed-scheme/optimizer/box.rkt | 4 +-- collects/typed-scheme/optimizer/sequence.rkt | 4 +-- collects/typed-scheme/optimizer/vector.rkt | 6 ++-- doc/release-notes/racket/HISTORY.txt | 1 + src/racket/src/jit.c | 32 +++++++++---------- src/racket/src/list.c | 8 ++--- 12 files changed, 79 insertions(+), 78 deletions(-) diff --git a/collects/racket/match/compiler.rkt b/collects/racket/match/compiler.rkt index 533d877405..88e9d87861 100644 --- a/collects/racket/match/compiler.rkt +++ b/collects/racket/match/compiler.rkt @@ -105,10 +105,10 @@ esc)] [(n ...) ns]) #`[(#,arity) - (let ([tmps (unsafe-vector*-ref #,x n)] ...) + (let ([tmps (unsafe-vector-ref #,x n)] ...) body)]))))])]) #`[(vector? #,x) - (case (unsafe-vector*-length #,x) + (case (unsafe-vector-length #,x) clauses ... [else (#,esc)])])] ;; it's a structure @@ -117,7 +117,7 @@ (let* ([s (Row-first-pat (car rows))] [accs (Struct-accessors s)] [accs (if (Struct-complete? s) - (build-list (length accs) (λ (i) #`(λ (x) (unsafe-struct*-ref x #,i)))) + (build-list (length accs) (λ (i) #`(λ (x) (unsafe-struct-ref x #,i)))) accs)] [pred (Struct-pred s)]) (compile-con-pat accs pred Struct-ps))] diff --git a/collects/racket/private/for.rkt b/collects/racket/private/for.rkt index 654425ab3a..d07264c571 100644 --- a/collects/racket/private/for.rkt +++ b/collects/racket/private/for.rkt @@ -420,7 +420,7 @@ (define (:vector-gen v start stop step) (values ;; pos->element - (lambda (i) (unsafe-vector*-ref v i)) + (lambda (i) (unsafe-vector-ref v i)) ;; next-pos ;; Minor optimisation. I assume add1 is faster than \x.x+1 (if (= step 1) add1 (lambda (i) (+ i step))) @@ -1236,9 +1236,9 @@ (define-sequence-syntax *in-vector (lambda () #'in-vector) (vector-like-gen #'vector? - #'unsafe-vector*-length + #'unsafe-vector-length #'in-vector - #'unsafe-vector*-ref)) + #'unsafe-vector-ref)) (define-sequence-syntax *in-string (lambda () #'in-string) diff --git a/collects/racket/vector.rkt b/collects/racket/vector.rkt index 9d9ea1e6da..0262688cd6 100644 --- a/collects/racket/vector.rkt +++ b/collects/racket/vector.rkt @@ -59,9 +59,9 @@ ;; length is passed to save the computation (define (vector-map/update f target length vs) (for ([i (in-range length)]) - (unsafe-vector*-set! + (unsafe-vector-set! target i - (apply f (map (lambda (vec) (unsafe-vector*-ref vec i)) vs))))) + (apply f (map (lambda (vec) (unsafe-vector-ref vec i)) vs))))) ;; check that `v' is a vector ;; that `v' and all the `vs' have the same length @@ -77,12 +77,12 @@ 0 f)) (unless (vector? v) (raise-type-error name "vector" 1 v)) - (let ([len (unsafe-vector*-length v)]) + (let ([len (unsafe-vector-length v)]) (for ([e (in-list vs)] [i (in-naturals 2)]) (unless (vector? e) (raise-type-error name "vector" e i)) - (unless (= len (unsafe-vector*-length e)) + (unless (= len (unsafe-vector-length e)) (raise (make-exn:fail:contract (format "~e: all vectors must have same size; ~a" @@ -138,8 +138,8 @@ ([i (in-range len)] #:when (apply f - (unsafe-vector*-ref v i) - (map (lambda (v) (unsafe-vector*-ref v i)) vs))) + (unsafe-vector-ref v i) + (map (lambda (v) (unsafe-vector-ref v i)) vs))) (add1 c)) (error 'vector-count "all vectors must have same size"))) (for/fold ([cnt 0]) ([i (in-vector v)] #:when (f i)) @@ -150,7 +150,7 @@ (raise-type-error name "vector" v)) (unless (exact-nonnegative-integer? n) (raise-type-error name "non-negative exact integer" n)) - (let ([len (unsafe-vector*-length v)]) + (let ([len (unsafe-vector-length v)]) (unless (<= 0 n len) (raise-mismatch-error name @@ -186,14 +186,14 @@ (let* ([vs (cons v vs)] [lens (for/list ([e (in-list vs)] [i (in-naturals)]) (if (vector? e) - (unsafe-vector*-length e) + (unsafe-vector-length e) (raise-type-error 'vector-append "vector" e i)))] [new-v (make-vector (apply + lens))]) (let loop ([start 0] [lens lens] [vs vs]) (when (pair? lens) (let ([len (car lens)] [v (car vs)]) (for ([i (in-range len)]) - (unsafe-vector*-set! new-v (+ i start) (unsafe-vector*-ref v i))) + (unsafe-vector-set! new-v (+ i start) (unsafe-vector-ref v i))) (loop (+ start len) (cdr lens) (cdr vs))))) new-v)) @@ -203,13 +203,13 @@ (procedure-arity-includes? f 1)) (raise-type-error name "procedure (arity 1)" f)) (unless (and (vector? xs) - (< 0 (unsafe-vector*-length xs))) + (< 0 (unsafe-vector-length xs))) (raise-type-error name "non-empty vector" xs)) - (let ([init-min-var (f (unsafe-vector*-ref xs 0))]) + (let ([init-min-var (f (unsafe-vector-ref xs 0))]) (unless (real? init-min-var) (raise-type-error name "procedure that returns real numbers" f)) (let-values ([(min* min-var*) - (for/fold ([min (unsafe-vector*-ref xs 0)] + (for/fold ([min (unsafe-vector-ref xs 0)] [min-var init-min-var]) ([e (in-vector xs 1)]) (let ([new-min (f e)]) @@ -228,11 +228,11 @@ (define (name val vec) (unless (vector? vec) (raise-type-error 'name "vector" 1 vec)) - (let ([sz (unsafe-vector*-length vec)]) + (let ([sz (unsafe-vector-length vec)]) (let loop ([k 0]) (cond [(= k sz) #f] [(cmp val - (unsafe-vector*-ref vec k)) + (unsafe-vector-ref vec k)) k] [else (loop (unsafe-fx+ 1 k))]))))) diff --git a/collects/scribblings/reference/unsafe.scrbl b/collects/scribblings/reference/unsafe.scrbl index 17d83d1738..285e6722b7 100644 --- a/collects/scribblings/reference/unsafe.scrbl +++ b/collects/scribblings/reference/unsafe.scrbl @@ -192,22 +192,22 @@ Unsafe variants of @scheme[car], @scheme[cdr], @scheme[mcar], @deftogether[( -@defproc[(unsafe-unbox [v (and/c box? (not/c chaperone?))]) any/c] -@defproc[(unsafe-set-box! [v (and/c box? (not/c chaperone?))] [val any/c]) void?] -@defproc[(unsafe-unbox* [b box?]) fixnum?] -@defproc[(unsafe-set-box*! [b box?] [k fixnum?]) void?] +@defproc[(unsafe-unbox [b box?]) fixnum?] +@defproc[(unsafe-set-box! [b box?] [k fixnum?]) void?] +@defproc[(unsafe-unbox* [v (and/c box? (not/c chaperone?))]) any/c] +@defproc[(unsafe-set-box*! [v (and/c box? (not/c chaperone?))] [val any/c]) void?] )]{ Unsafe versions of @scheme[unbox] and @scheme[set-box!].} @deftogether[( -@defproc[(unsafe-vector-length [v (and/c vector? (not/c chaperone?))]) fixnum?] -@defproc[(unsafe-vector-ref [v (and/c vector? (not/c chaperone?))] [k fixnum?]) any/c] -@defproc[(unsafe-vector-set! [v (and/c vector? (not/c chaperone?))] [k fixnum?] [val any/c]) void?] -@defproc[(unsafe-vector*-length [v vector?]) fixnum?] -@defproc[(unsafe-vector*-ref [v vector?] [k fixnum?]) any/c] -@defproc[(unsafe-vector*-set! [v vector?] [k fixnum?] [val any/c]) void?] +@defproc[(unsafe-vector-length [v vector?]) fixnum?] +@defproc[(unsafe-vector-ref [v vector?] [k fixnum?]) any/c] +@defproc[(unsafe-vector-set! [v vector?] [k fixnum?] [val any/c]) void?] +@defproc[(unsafe-vector*-length [v (and/c vector? (not/c chaperone?))]) fixnum?] +@defproc[(unsafe-vector*-ref [v (and/c vector? (not/c chaperone?))] [k fixnum?]) any/c] +@defproc[(unsafe-vector*-set! [v (and/c vector? (not/c chaperone?))] [k fixnum?] [val any/c]) void?] )]{ Unsafe versions of @scheme[vector-length], @scheme[vector-ref], and @@ -282,10 +282,10 @@ Unsafe versions of @scheme[u16vector-ref] and @deftogether[( -@defproc[(unsafe-struct-ref [v (not/c chaperone?)] [k fixnum?]) any/c] -@defproc[(unsafe-struct-set! [v (not/c chaperone?)] [k fixnum?] [val any/c]) void?] -@defproc[(unsafe-struct*-ref [v any/c] [k fixnum?]) any/c] -@defproc[(unsafe-struct*-set! [v any/c] [k fixnum?] [val any/c]) void?] +@defproc[(unsafe-struct-ref [v any/c] [k fixnum?]) any/c] +@defproc[(unsafe-struct-set! [v any/c] [k fixnum?] [val any/c]) void?] +@defproc[(unsafe-struct*-ref [v (not/c chaperone?)] [k fixnum?]) any/c] +@defproc[(unsafe-struct*-set! [v (not/c chaperone?)] [k fixnum?] [val any/c]) void?] )]{ Unsafe field access and update for an instance of a structure diff --git a/collects/tests/racket/benchmarks/shootout/nbody-vec.rkt b/collects/tests/racket/benchmarks/shootout/nbody-vec.rkt index c0cacef496..f8775bdcae 100644 --- a/collects/tests/racket/benchmarks/shootout/nbody-vec.rkt +++ b/collects/tests/racket/benchmarks/shootout/nbody-vec.rkt @@ -94,10 +94,10 @@ Correct output N = 1000 is (let loop-i ([i 0] [px 0.0] [py 0.0] [pz 0.0]) (if (unsafe-fx= i *system-size*) (begin - (set-body-vx! (unsafe-vector-ref *system* 0) (fl/ (fl- 0.0 px) +solar-mass+)) - (set-body-vy! (unsafe-vector-ref *system* 0) (fl/ (fl- 0.0 py) +solar-mass+)) - (set-body-vz! (unsafe-vector-ref *system* 0) (fl/ (fl- 0.0 pz) +solar-mass+))) - (let ([i1 (unsafe-vector-ref *system* i)]) + (set-body-vx! (unsafe-vector*-ref *system* 0) (fl/ (fl- 0.0 px) +solar-mass+)) + (set-body-vy! (unsafe-vector*-ref *system* 0) (fl/ (fl- 0.0 py) +solar-mass+)) + (set-body-vz! (unsafe-vector*-ref *system* 0) (fl/ (fl- 0.0 pz) +solar-mass+))) + (let ([i1 (unsafe-vector*-ref *system* i)]) (loop-i (unsafe-fx+ i 1) (fl+ px (fl* (body-vx i1) (body-mass i1))) (fl+ py (fl* (body-vy i1) (body-mass i1))) @@ -108,7 +108,7 @@ Correct output N = 1000 is (let loop-o ([o 0] [e 0.0]) (if (unsafe-fx= o *system-size*) e - (let* ([o1 (unsafe-vector-ref *system* o)] + (let* ([o1 (unsafe-vector*-ref *system* o)] [e (fl+ e (fl* (fl* 0.5 (body-mass o1)) (fl+ (fl+ (fl* (body-vx o1) (body-vx o1)) (fl* (body-vy o1) (body-vy o1))) @@ -116,7 +116,7 @@ Correct output N = 1000 is (let loop-i ([i (unsafe-fx+ o 1)] [e e]) (if (unsafe-fx= i *system-size*) (loop-o (unsafe-fx+ o 1) e) - (let* ([i1 (unsafe-vector-ref *system* i)] + (let* ([i1 (unsafe-vector*-ref *system* i)] [dx (fl- (body-x o1) (body-x i1))] [dy (fl- (body-y o1) (body-y i1))] [dz (fl- (body-z o1) (body-z i1))] @@ -128,13 +128,13 @@ Correct output N = 1000 is (define (advance) (let loop-o ([o 0]) (unless (unsafe-fx= o *system-size*) - (let* ([o1 (unsafe-vector-ref *system* o)]) + (let* ([o1 (unsafe-vector*-ref *system* o)]) (let loop-i ([i (unsafe-fx+ o 1)] [vx (body-vx o1)] [vy (body-vy o1)] [vz (body-vz o1)]) (if (unsafe-fx< i *system-size*) - (let* ([i1 (unsafe-vector-ref *system* i)] + (let* ([i1 (unsafe-vector*-ref *system* i)] [dx (fl- (body-x o1) (body-x i1))] [dy (fl- (body-y o1) (body-y i1))] [dz (fl- (body-z o1) (body-z i1))] diff --git a/collects/tests/racket/unsafe.rktl b/collects/tests/racket/unsafe.rktl index f95df45a6e..84e9c82ff0 100644 --- a/collects/tests/racket/unsafe.rktl +++ b/collects/tests/racket/unsafe.rktl @@ -231,9 +231,9 @@ #:pre (lambda () (set-box! b 12)) #:post (lambda (x) (list x (unbox b))) #:literal-ok? #f))) - (test-un 3 'unsafe-unbox* (chaperone-box (box 3) - (lambda (b v) v) - (lambda (b v) v))) + (test-un 3 'unsafe-unbox (chaperone-box (box 3) + (lambda (b v) v) + (lambda (b v) v))) (for ([star (list values (add-star "vector"))]) (test-bin 5 (star 'unsafe-vector-ref) #(1 5 7) 1) @@ -243,13 +243,13 @@ #:pre (lambda () (vector-set! v 2 0)) #:post (lambda (x) (list x (vector-ref v 2))) #:literal-ok? #f))) - (test-bin 5 'unsafe-vector*-ref (chaperone-vector #(1 5 7) - (lambda (v i x) x) - (lambda (v i x) x)) + (test-bin 5 'unsafe-vector-ref (chaperone-vector #(1 5 7) + (lambda (v i x) x) + (lambda (v i x) x)) 1) - (test-un 3 'unsafe-vector*-length (chaperone-vector #(1 5 7) - (lambda (v i x) x) - (lambda (v i x) x))) + (test-un 3 'unsafe-vector-length (chaperone-vector #(1 5 7) + (lambda (v i x) x) + (lambda (v i x) x))) (test-bin 53 'unsafe-bytes-ref #"157" 1) (test-un 3 'unsafe-bytes-length #"157") diff --git a/collects/typed-scheme/optimizer/box.rkt b/collects/typed-scheme/optimizer/box.rkt index 7ad707e75b..8642c36863 100644 --- a/collects/typed-scheme/optimizer/box.rkt +++ b/collects/typed-scheme/optimizer/box.rkt @@ -21,8 +21,8 @@ (define-syntax-class box-op #:commit ;; we need the * versions of these unsafe operations to be chaperone-safe - (pattern (~literal unbox) #:with unsafe #'unsafe-unbox*) - (pattern (~literal set-box!) #:with unsafe #'unsafe-set-box*!)) + (pattern (~literal unbox) #:with unsafe #'unsafe-unbox) + (pattern (~literal set-box!) #:with unsafe #'unsafe-set-box!)) (define-syntax-class box-opt-expr #:commit diff --git a/collects/typed-scheme/optimizer/sequence.rkt b/collects/typed-scheme/optimizer/sequence.rkt index f050e91eb2..2ca9599092 100644 --- a/collects/typed-scheme/optimizer/sequence.rkt +++ b/collects/typed-scheme/optimizer/sequence.rkt @@ -51,8 +51,8 @@ #:with opt (begin (log-optimization "in-vector" #'op) #'(let* ((i v*.opt) - (len (unsafe-vector*-length i))) - (values (lambda (x) (unsafe-vector*-ref i x)) + (len (unsafe-vector-length i))) + (values (lambda (x) (unsafe-vector-ref i x)) (lambda (x) (unsafe-fx+ 1 x)) 0 (lambda (x) (unsafe-fx< x len)) diff --git a/collects/typed-scheme/optimizer/vector.rkt b/collects/typed-scheme/optimizer/vector.rkt index 6e3195d9ae..776a796f44 100644 --- a/collects/typed-scheme/optimizer/vector.rkt +++ b/collects/typed-scheme/optimizer/vector.rkt @@ -14,8 +14,8 @@ (define-syntax-class vector-op #:commit ;; we need the * versions of these unsafe operations to be chaperone-safe - (pattern (~literal vector-ref) #:with unsafe #'unsafe-vector*-ref) - (pattern (~literal vector-set!) #:with unsafe #'unsafe-vector*-set!)) + (pattern (~literal vector-ref) #:with unsafe #'unsafe-vector-ref) + (pattern (~literal vector-set!) #:with unsafe #'unsafe-vector-set!)) (define-syntax-class vector-expr #:commit @@ -43,7 +43,7 @@ (pattern (#%plain-app (~and op (~literal vector-length)) v:expr) #:with opt (begin (log-optimization "vector-length" #'op) - #`(unsafe-vector*-length #,((optimize) #'v)))) + #`(unsafe-vector-length #,((optimize) #'v)))) ;; same for flvector-length (pattern (#%plain-app (~and op (~literal flvector-length)) v:expr) #:with opt diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index 0f6925afc5..723f53f340 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,6 +1,7 @@ Version 5.0.2, October 2010 Changed body of `when', `unless', `cond' clauses, `case' clauses, and `match' clauses to be internal-definition contexts +Swapped unsafe-vector*-ref with unsafe-vector-ref, etc. Added ->i to the contract library, improved ->*, adding #:pre and #:post, as well as making the optional arguments clause optional. Added #true and #false, and changed #t/#T and #f/#F to diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index 451de6772f..bdc3e3f7fb 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -7025,10 +7025,10 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in GC_CAN_IGNORE jit_insn *reffail, *ref; int unsafe = 0, for_fl = 0, for_fx = 0, can_chaperone = 0; - if (IS_NAMED_PRIM(rator, "unsafe-vector-length") + if (IS_NAMED_PRIM(rator, "unsafe-vector*-length") || IS_NAMED_PRIM(rator, "unsafe-fxvector-length")) { unsafe = 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-vector*-length")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-vector-length")) { unsafe = 1; can_chaperone = 1; } else if (IS_NAMED_PRIM(rator, "flvector-length")) { @@ -7151,7 +7151,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in __END_TINY_JUMPS__(1); return 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-unbox")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-unbox*")) { LOG_IT(("inlined unbox\n")); mz_runstack_skipped(jitter, 1); @@ -7164,7 +7164,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in (void)jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_BOX_VAL(0x0)); return 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-unbox*")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-unbox")) { GC_CAN_IGNORE jit_insn *ref, *ref2; LOG_IT(("inlined unbox\n")); @@ -8215,7 +8215,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i which = 0; for_fx = 1; can_chaperone = 0; - } else if (IS_NAMED_PRIM(rator, "unsafe-vector-ref")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-vector*-ref")) { which = 0; unsafe = 1; can_chaperone = 0; @@ -8224,7 +8224,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i unsafe = 1; can_chaperone = 0; for_fx = 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-vector*-ref")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-vector-ref")) { which = 0; unsafe = 1; } else if (IS_NAMED_PRIM(rator, "flvector-ref")) { @@ -8236,13 +8236,13 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jitter->unbox = 0; } can_chaperone = 0; - } else if (IS_NAMED_PRIM(rator, "unsafe-struct-ref")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-struct*-ref")) { which = 0; unsafe = 1; base_offset = ((int)&((Scheme_Structure *)0x0)->slots); can_chaperone = 0; for_struct = 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-struct*-ref")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-struct-ref")) { which = 0; unsafe = 1; base_offset = ((int)&((Scheme_Structure *)0x0)->slots); @@ -8482,13 +8482,13 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i return 1; } else if (IS_NAMED_PRIM(rator, "set-box!") - || IS_NAMED_PRIM(rator, "unsafe-set-box*!")) { + || IS_NAMED_PRIM(rator, "unsafe-set-box!")) { GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *reffail; int unsafe; LOG_IT(("inlined set-box!\n")); - unsafe = IS_NAMED_PRIM(rator, "unsafe-set-box*!"); + unsafe = IS_NAMED_PRIM(rator, "unsafe-set-box!"); generate_two_args(app->rand1, app->rand2, jitter, 1, 2); CHECK_LIMIT(); @@ -8522,8 +8522,8 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i (void)jit_movi_p(JIT_R0, scheme_void); return 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-set-box!")) { - LOG_IT(("inlined unsafe-set-box!\n")); + } else if (IS_NAMED_PRIM(rator, "unsafe-set-box*!")) { + LOG_IT(("inlined unsafe-set-box*!\n")); generate_two_args(app->rand1, app->rand2, jitter, 1, 2); CHECK_LIMIT(); @@ -8766,7 +8766,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } else if (IS_NAMED_PRIM(rator, "fxvector-set!")) { which = 0; for_fx = 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-vector-set!")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-vector*-set!")) { which = 0; unsafe = 1; can_chaperone = 0; @@ -8775,19 +8775,19 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int unsafe = 1; can_chaperone = 0; for_fx = 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-vector*-set!")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-vector-set!")) { which = 0; unsafe = 1; } else if (IS_NAMED_PRIM(rator, "flvector-set!")) { which = 3; base_offset = ((int)&SCHEME_FLVEC_ELS(0x0)); - } else if (IS_NAMED_PRIM(rator, "unsafe-struct-set!")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-struct*-set!")) { which = 0; unsafe = 1; base_offset = ((int)&((Scheme_Structure *)0x0)->slots); can_chaperone = 0; for_struct = 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-struct*-set!")) { + } else if (IS_NAMED_PRIM(rator, "unsafe-struct-set!")) { which = 0; unsafe = 1; base_offset = ((int)&((Scheme_Structure *)0x0)->slots); diff --git a/src/racket/src/list.c b/src/racket/src/list.c index d91e8fff7f..6e4095334e 100644 --- a/src/racket/src/list.c +++ b/src/racket/src/list.c @@ -3431,12 +3431,12 @@ static Scheme_Object *unsafe_set_mcdr (int argc, Scheme_Object *argv[]) return scheme_void; } -static Scheme_Object *unsafe_unbox (int argc, Scheme_Object *argv[]) +static Scheme_Object *unsafe_unbox_star (int argc, Scheme_Object *argv[]) { return SCHEME_BOX_VAL(argv[0]); } -static Scheme_Object *unsafe_unbox_star (int argc, Scheme_Object *argv[]) +static Scheme_Object *unsafe_unbox (int argc, Scheme_Object *argv[]) { if (SCHEME_NP_CHAPERONEP(argv[0])) return chaperone_unbox(argv[0]); @@ -3444,13 +3444,13 @@ static Scheme_Object *unsafe_unbox_star (int argc, Scheme_Object *argv[]) return SCHEME_BOX_VAL(argv[0]); } -static Scheme_Object *unsafe_set_box (int argc, Scheme_Object *argv[]) +static Scheme_Object *unsafe_set_box_star (int argc, Scheme_Object *argv[]) { SCHEME_BOX_VAL(argv[0]) = argv[1]; return scheme_void; } -static Scheme_Object *unsafe_set_box_star (int argc, Scheme_Object *argv[]) +static Scheme_Object *unsafe_set_box (int argc, Scheme_Object *argv[]) { if (SCHEME_NP_CHAPERONEP(argv[0])) chaperone_set_box(argv[0], argv[1]); From da7e1bae0c598821e931f7efad1fc824ad5c93fb Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 25 Oct 2010 11:27:16 -0600 Subject: [PATCH 048/746] data/gvector: fixed typo in constructor Merge to 5.0.2 (cherry picked from commit 24297a793fe21083d8b7da1293425e95ebee62e0) --- collects/data/gvector.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/data/gvector.rkt b/collects/data/gvector.rkt index c845311733..07de71a87a 100644 --- a/collects/data/gvector.rkt +++ b/collects/data/gvector.rkt @@ -7,7 +7,7 @@ racket/vector) (define (make-gvector #:capacity [capacity 10]) - (make-gvector (make-vector capacity #f) 0)) + (gvector (make-vector capacity #f) 0)) (define gvector* (let ([gvector From 1b24ca0063fa52b55b6779eb546537332faafb82 Mon Sep 17 00:00:00 2001 From: Casey Klein Date: Mon, 25 Oct 2010 14:26:42 -0500 Subject: [PATCH 049/746] Updates Redex history for v5.0.2 release (merge to release branch) (cherry picked from commit d7b0271691d97080f74c3c84ba475dada76ec1b7) --- doc/release-notes/redex/HISTORY.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/doc/release-notes/redex/HISTORY.txt b/doc/release-notes/redex/HISTORY.txt index 5c9fbac1b6..4b4d6a0577 100644 --- a/doc/release-notes/redex/HISTORY.txt +++ b/doc/release-notes/redex/HISTORY.txt @@ -1,7 +1,17 @@ - * added pretty-print-parameters +v5.0.2 - * added grammar-style and paren-style that give finer-grained control - over the typesetting styles + * added `pretty-print-parameters' to control term pretty-printing + + * added `grammar-style' and `paren-style' typesetting parameters + + * added support for computed reduction rule names + + * added delimited control model to examples + + * added optional #:attempt-size and #:prepare keyword arguments to random + testing forms + + * fixed minor bugs v5.0.1 From 7708164561e025ff7ac1f15544b99398fe80b3d5 Mon Sep 17 00:00:00 2001 From: Casey Klein Date: Mon, 25 Oct 2010 15:18:16 -0500 Subject: [PATCH 050/746] Renames delim-cont tests so that they're not stripped by the distribution script. (Merge to release branch.) (cherry picked from commit f4c4b790496027e98dde415a4b88fb895a7f98de) --- collects/meta/props | 2 +- collects/redex/examples/delim-cont/README.txt | 2 +- collects/redex/examples/delim-cont/{tests.rkt => test.rkt} | 0 collects/redex/tests/run-tests.rkt | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename collects/redex/examples/delim-cont/{tests.rkt => test.rkt} (100%) diff --git a/collects/meta/props b/collects/meta/props index 9cb417b48b..07420c49a7 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -1188,7 +1188,7 @@ path/s is either such a string or a list of them. "collects/redex/examples/church.rkt" drdr:command-line (mzc *) "collects/redex/examples/combinators.rkt" drdr:command-line (mzc *) "collects/redex/examples/compatible-closure.rkt" drdr:command-line (mzc *) -"collects/redex/examples/delim-cont/tests.rkt" drdr:command-line (mzc *) +"collects/redex/examples/delim-cont/test.rkt" drdr:command-line (mzc *) "collects/redex/examples/letrec.rkt" drdr:command-line (mzc *) "collects/redex/examples/omega.rkt" drdr:command-line (mzc *) "collects/redex/examples/r6rs/r6rs-tests.rkt" drdr:command-line (mzc *) diff --git a/collects/redex/examples/delim-cont/README.txt b/collects/redex/examples/delim-cont/README.txt index 4403bc3f2d..ddd8c45792 100644 --- a/collects/redex/examples/delim-cont/README.txt +++ b/collects/redex/examples/delim-cont/README.txt @@ -1,7 +1,7 @@ To run the tests using the model: --------------------------------- - 1. Open "tests.rkt" in DrRacket + 1. Open "test.rkt" in DrRacket 2. Change DrRacket's current language to "Use the langauge declared in the source" diff --git a/collects/redex/examples/delim-cont/tests.rkt b/collects/redex/examples/delim-cont/test.rkt similarity index 100% rename from collects/redex/examples/delim-cont/tests.rkt rename to collects/redex/examples/delim-cont/test.rkt diff --git a/collects/redex/tests/run-tests.rkt b/collects/redex/tests/run-tests.rkt index 672e36f997..6fe9b9bb44 100644 --- a/collects/redex/tests/run-tests.rkt +++ b/collects/redex/tests/run-tests.rkt @@ -31,7 +31,7 @@ ("../examples/beginner.ss" main) "../examples/racket-machine/reduction-test.ss" "../examples/racket-machine/verification-test.ss" - "../examples/delim-cont/tests.rkt" + "../examples/delim-cont/test.rkt" ("../examples/r6rs/r6rs-tests.ss" main)) '()))) From 7dc309037eb4427cdd87b0743f6f42a6c7a26631 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Tue, 26 Oct 2010 19:01:56 -0400 Subject: [PATCH 051/746] record? is working as it used, plus ability to auto-save images so I can write a test case, Closes PR11348 and PR11349 (cherry picked from commit 6457f1e4cc4aefc5e45a84d5168dda90c00dd6e8) --- collects/2htdp/private/syn-aux-aux.rkt | 6 +++- collects/2htdp/private/world.rkt | 49 +++++++++++++------------- collects/2htdp/tests/record.rkt | 40 +++++++++++++++++++++ collects/2htdp/universe.rkt | 5 +-- 4 files changed, 73 insertions(+), 27 deletions(-) create mode 100644 collects/2htdp/tests/record.rkt diff --git a/collects/2htdp/private/syn-aux-aux.rkt b/collects/2htdp/private/syn-aux-aux.rkt index 80a5e5ac66..fbd8face8a 100644 --- a/collects/2htdp/private/syn-aux-aux.rkt +++ b/collects/2htdp/private/syn-aux-aux.rkt @@ -18,7 +18,7 @@ ; ; ; ; ;;; -(provide nat> nat? proc> bool> num> ip> string> symbol>) +(provide nat> nat? proc> bool> num> ip> string> symbol> any>) ;; Any -> Boolean (define (nat? x) @@ -58,3 +58,7 @@ (define (nat> tag x spec) (check-arg tag (nat? x) spec "natural number" x) x) + +;; Symbol X String -> X +(define (any> tag x) + x) diff --git a/collects/2htdp/private/world.rkt b/collects/2htdp/private/world.rkt index b10b5f3ca6..cb31063e18 100644 --- a/collects/2htdp/private/world.rkt +++ b/collects/2htdp/private/world.rkt @@ -51,8 +51,8 @@ (class* object% (start-stop<%>) (inspect #f) (init-field world0) - (init-field name state register check-with on-key on-mouse) - (init on-release on-receive on-draw stop-when record?) + (init-field name state register check-with on-key on-mouse record?) + (init on-release on-receive on-draw stop-when) ;; ----------------------------------------------------------------------- (field @@ -341,9 +341,8 @@ (start!) (let ([w (send world get)]) (cond - [(stop w) (stop! (send world get))] - [(stop-the-world? w) - (stop! (stop-the-world-world (send world get)))])))))) + [(stop w) (stop! w)] + [(stop-the-world? w) (stop! (stop-the-world-world w))])))))) ; (define make-new-world (new-world world%)) @@ -357,7 +356,7 @@ (define aworld% (class world% (super-new) - (inherit-field world0 tick key release mouse rec draw rate width height) + (inherit-field world0 tick key release mouse rec draw rate width height record?) (inherit show callback-stop!) ;; Frame Custodian ->* (-> Void) (-> Void) @@ -365,9 +364,15 @@ ;; whose callbacks runs as a thread in the custodian (define/augment (create-frame frm play-back-custodian) (define p (new horizontal-pane% [parent frm][alignment '(center center)])) + (define (pb) + (parameterize ([current-custodian play-back-custodian]) + (thread (lambda () (play-back))) + (stop))) (define (switch) (send stop-button enable #f) - (send image-button enable #t)) + (if (and (string? record?) (directory-exists? record?)) + (pb) + (send image-button enable #t))) (define (stop) (send image-button enable #f) (send stop-button enable #f)) @@ -377,10 +382,7 @@ (define stop-button (btn break-button:label (b e) (callback-stop! 'stop-images) (switch))) (define image-button - (btn image-button:label (b e) - (parameterize ([current-custodian play-back-custodian]) - (thread (lambda () (play-back))) - (stop)))) + (btn image-button:label (b e) (pb))) (send image-button enable #f) (values switch stop)) @@ -392,10 +394,8 @@ ;; --- new callbacks --- (define-syntax-rule (def/cb ovr (pname name arg ...)) - (begin - ; (ovr pname) - (define/override (pname arg ...) - (when (super pname arg ...) (add-event 'name arg ...))))) + (define/override (pname arg ...) + (when (super pname arg ...) (add-event name arg ...)))) (def/cb augment (ptock tick)) (def/cb augment (pkey key e)) @@ -424,19 +424,20 @@ (send bm save-file (format "i~a.png" (zero-fill imag# digt#)) 'png) (set! bmps (cons bm bmps))) ;; --- choose place - (define img:dir (get-directory "image directory:" #f (current-directory))) + (define img:dir + (or (and (string? record?) (directory-exists? record?) record?) + (get-directory "image directory:" #f (current-directory)))) (when img:dir (parameterize ([current-directory img:dir]) - (define last - (foldr (lambda (event world) - (save-image (draw world)) - (show (text (format "~a/~a created" imag# total) 18 'red)) - (world-transition world event)) - world0 - event-history)) + (define worldN + (let L ([history event-history][world world0]) + (save-image (draw world)) + (if (empty? history) + world + (L (rest history) (world-transition world (first history)))))) (show (text (format "creating ~a" ANIMATED-GIF-FILE) 18 'red)) (create-animated-gif rate (reverse bmps)) - (show (draw last))))))) + (show (draw worldN))))))) ;; Number [Listof (-> bitmap)] -> Void ;; turn the list of thunks into animated gifs diff --git a/collects/2htdp/tests/record.rkt b/collects/2htdp/tests/record.rkt new file mode 100644 index 0000000000..96989555a3 --- /dev/null +++ b/collects/2htdp/tests/record.rkt @@ -0,0 +1,40 @@ +#lang racket + +(require 2htdp/universe) +(require 2htdp/image) + +(define (draw-number n) + (place-image (text (number->string n) 44 'red) + 50 50 + (empty-scene 100 100))) + +;; Nat String -> Nat +;; create n images in ./images directory +;; ASSUME: dir exists +(define (create-n-images n dir) + (parameterize ([current-directory dir]) + (for-each delete-file (directory-list))) + (with-output-to-file (format "./~a/index.html" dir) + (lambda () + (displayln "")) + #:exists 'replace) + (define final-world + (big-bang 0 + (on-tick add1) + (stop-when (curry = (+ n 1))) + (on-draw draw-number) + (record? dir))) + (sleep 1) + (define number-of-png + (parameterize ([current-directory dir]) + (define dlst (directory-list)) + ; (displayln dlst) + (length + (filter (lambda (f) (regexp-match "\\.png" (path->string f))) + dlst)))) + (unless (= (+ n 2) number-of-png) + (error 'record? "(~s, ~s) didn't record proper number of images: ~s" n dir + number-of-png))) + +(create-n-images 3 "images3/") +(create-n-images 0 "images0/") \ No newline at end of file diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index 838941f28f..2ceae80a01 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -94,9 +94,10 @@ [(_ stop? last-picture) #'(list (proc> 'stop-when (f2h stop?) 1) (proc> 'stop-when (f2h last-picture) 1))])] - ;; (U #f Boolean) + ;; (U #f Any) ;; -- should the session be recorded and turned into PNGs and an animated GIF - [record? DEFAULT #'#f (expr-with-check bool> "expected a boolean")] + ;; -- if the value is a string and is the name of a local directory, use it! + [record? DEFAULT #'#f (expr-with-check any> "")] ;; (U #f String) ;; -- name specifies one string [name DEFAULT #'#f (expr-with-check string> "expected a string")] From 7318fc10ce476c159527cf0d0a57253383b2eac6 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Wed, 27 Oct 2010 10:12:37 -0400 Subject: [PATCH 052/746] partial fix for pr11350 (cherry picked from commit f876a854c6211a5b2fc20e3c48d3f491e8b8c3a0) --- collects/2htdp/private/world.rkt | 12 ++++--- collects/2htdp/tests/record-stop-when.rkt | 40 +++++++++++++++++++++++ collects/2htdp/tests/record.rkt | 17 +++++----- 3 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 collects/2htdp/tests/record-stop-when.rkt diff --git a/collects/2htdp/private/world.rkt b/collects/2htdp/private/world.rkt index cb31063e18..3d15a16eda 100644 --- a/collects/2htdp/private/world.rkt +++ b/collects/2htdp/private/world.rkt @@ -226,6 +226,11 @@ ;; Any ... -> Boolean (begin (define/public (name arg ...) + (define (last-draw) + (define draw0 draw) + (dynamic-wind (lambda () (set! draw last-picture)) + (lambda () (pdraw)) + (lambda () (set! draw draw0)))) (queue-callback (lambda () (with-handlers ([exn? (handler #t)]) @@ -245,8 +250,7 @@ (begin (set! nw (stop-the-world-world nw)) (send world set tag nw) - (when last-picture - (set! draw last-picture)) + (when last-picture (last-draw)) (when draw (pdraw)) (callback-stop! 'name) (enable-images-button)) @@ -270,9 +274,7 @@ [else (set! draw# (- draw# 1))])) (when (pstop) - (when last-picture - (set! draw last-picture) - (pdraw)) + (when last-picture (last-draw)) (callback-stop! 'name) (enable-images-button)) changed-world?)))))))) diff --git a/collects/2htdp/tests/record-stop-when.rkt b/collects/2htdp/tests/record-stop-when.rkt new file mode 100644 index 0000000000..de3c676ed9 --- /dev/null +++ b/collects/2htdp/tests/record-stop-when.rkt @@ -0,0 +1,40 @@ +#lang racket + +(require 2htdp/universe 2htdp/image (only-in lang/imageeq image=?)) + +(define (draw-number n) + (place-image (text (number->string n) 44 'red) + 50 50 + (empty-scene 100 100))) + +(define (draw-stop n) + stop) +(define stop (text "STOP" 44 'red)) + +;; -> Nat +;; make the clock tick n times, expected expected-n files in dir +(define (create-n-images) + (define dir "images0") + (unless (directory-exists? dir) + (make-directory dir)) + (parameterize ([current-directory dir]) + (for-each delete-file (directory-list))) + (with-output-to-file (format "./~a/index.html" dir) + (lambda () + (displayln "")) + #:exists 'replace) + (define final-world + (big-bang 0 + (on-tick add1) + (stop-when (curry = 5) draw-stop) + (on-draw draw-number) + (record? dir))) + (sleep 1) + (parameterize ([current-directory dir]) + (define dlst (directory-list)) + (displayln dlst) + (length + (filter (lambda (f) (regexp-match "\\.png" (path->string f))) + dlst)))) + +(create-n-images) diff --git a/collects/2htdp/tests/record.rkt b/collects/2htdp/tests/record.rkt index 96989555a3..f22ca740f2 100644 --- a/collects/2htdp/tests/record.rkt +++ b/collects/2htdp/tests/record.rkt @@ -8,10 +8,11 @@ 50 50 (empty-scene 100 100))) -;; Nat String -> Nat -;; create n images in ./images directory -;; ASSUME: dir exists -(define (create-n-images n dir) +;; Nat Nat String -> Nat +;; make the clock tick n times, expected expected-n files in dir +(define (create-n-images n expected-n dir) + (unless (directory-exists? dir) + (make-directory dir)) (parameterize ([current-directory dir]) (for-each delete-file (directory-list))) (with-output-to-file (format "./~a/index.html" dir) @@ -21,7 +22,7 @@ (define final-world (big-bang 0 (on-tick add1) - (stop-when (curry = (+ n 1))) + (stop-when (curry = n)) (on-draw draw-number) (record? dir))) (sleep 1) @@ -32,9 +33,9 @@ (length (filter (lambda (f) (regexp-match "\\.png" (path->string f))) dlst)))) - (unless (= (+ n 2) number-of-png) + (unless (= expected-n number-of-png) (error 'record? "(~s, ~s) didn't record proper number of images: ~s" n dir number-of-png))) -(create-n-images 3 "images3/") -(create-n-images 0 "images0/") \ No newline at end of file +(create-n-images 3 4 "images3/") +(create-n-images 0 0 "images0/") \ No newline at end of file From 0ac7d8f29aeb1371c0b427f89fe0129099d98370 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Wed, 27 Oct 2010 10:21:14 -0400 Subject: [PATCH 053/746] documented record?, which has a slightly wider interface so that I can write automated tests for the raw functionality (cherry picked from commit 42bceaf900c69791a05725fc875778793ebfaa85) --- .../teachpack/2htdp/scribblings/universe.scrbl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index aaa03c0cc5..a89f8f30aa 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -167,7 +167,7 @@ The design of a world program demands that you come up with a data (to-draw draw-expr width-expr height-expr) (stop-when stop-expr) (stop-when stop-expr last-scene-expr) (check-with world?-expr) - (record? boolean-expr) + (record? r-expr) (state boolean-expr) (on-receive rec-expr) (register IP-expr) @@ -470,12 +470,16 @@ and @scheme[big-bang] will close down all event handling.} @item{ -@defform[(record? boolean-expr) +@defform[(record? r-expr) #:contracts - ([boolean-expr boolean?])]{ - tells DrRacket to record all events and to enable a replay of the entire - interaction. The replay action also generates one png image per scene and - an animated gif for the entire sequence. + ([r-expr any/c])]{ + tells DrRacket to enable a visual replay of the interaction, + unless @scheme[#false]. + The replay action generates one png image per scene and + an animated gif for the entire sequence in the directory of the user's + choice. If @scheme[r-expr] evaluates to the name of an existing + directory/folder (in the local directory/folder), the directory is used to + deposit the images. }} @item{ From 0e2e35708de614f984134479b1305c859245eff8 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Wed, 27 Oct 2010 10:35:11 -0400 Subject: [PATCH 054/746] improved testing for record? (cherry picked from commit f600531e50db6bb2e8cda7807380a4d2ebd269d9) --- collects/2htdp/tests/record-stop-when.rkt | 45 ++++++++++------------- collects/2htdp/tests/xtest | 5 +++ 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/collects/2htdp/tests/record-stop-when.rkt b/collects/2htdp/tests/record-stop-when.rkt index de3c676ed9..cda9803e55 100644 --- a/collects/2htdp/tests/record-stop-when.rkt +++ b/collects/2htdp/tests/record-stop-when.rkt @@ -11,30 +11,23 @@ stop) (define stop (text "STOP" 44 'red)) -;; -> Nat -;; make the clock tick n times, expected expected-n files in dir -(define (create-n-images) - (define dir "images0") - (unless (directory-exists? dir) - (make-directory dir)) - (parameterize ([current-directory dir]) - (for-each delete-file (directory-list))) - (with-output-to-file (format "./~a/index.html" dir) - (lambda () - (displayln "")) - #:exists 'replace) - (define final-world - (big-bang 0 - (on-tick add1) - (stop-when (curry = 5) draw-stop) - (on-draw draw-number) - (record? dir))) - (sleep 1) - (parameterize ([current-directory dir]) - (define dlst (directory-list)) - (displayln dlst) - (length - (filter (lambda (f) (regexp-match "\\.png" (path->string f))) - dlst)))) -(create-n-images) +(define dir "images0") +(unless (directory-exists? dir) + (make-directory dir)) +(parameterize ([current-directory dir]) + (for-each delete-file (directory-list))) +(with-output-to-file (format "./~a/index.html" dir) + (lambda () + (displayln "")) + #:exists 'replace) +(define final-world + (big-bang 0 + (on-tick add1) + (stop-when (curry = 5) draw-stop) + (on-draw draw-number) + (record? dir))) +(sleep 1) +(unless (image=? (bitmap "images0/i1.png") (draw-number 0)) + (printf "this test needs to be revised -- image=? doesn't work\n")) + diff --git a/collects/2htdp/tests/xtest b/collects/2htdp/tests/xtest index 015d6edf30..842230dbcd 100755 --- a/collects/2htdp/tests/xtest +++ b/collects/2htdp/tests/xtest @@ -30,3 +30,8 @@ gracket ufo-rename.rkt echo "--- ufo-rename.rkt ---" echo "" gracket world0-stops.rkt +echo "--- record.rkt ---" echo "" +gracket record.rkt +echo "--- record-stop-when.rkt ---" echo "" +gracket record-stop-when.rkt + From ea0f518a9b742660ca142c6127199ec648304916 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 27 Oct 2010 16:14:03 -0400 Subject: [PATCH 055/746] Fixed a typo in the scribble docs. Merge to 5.0.2. (cherry picked from commit 25749736c9ccf300c1ad338017030614032f5224) --- collects/scriblib/scribblings/figure.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scriblib/scribblings/figure.scrbl b/collects/scriblib/scribblings/figure.scrbl index b3500aef6b..67c84a479f 100644 --- a/collects/scriblib/scribblings/figure.scrbl +++ b/collects/scriblib/scribblings/figure.scrbl @@ -22,7 +22,7 @@ rendering support.} )]{ Creates a figure. The given @scheme[tag] is for use with -@scheme[figure-ref] or @scheme[fFgure-ref]. The @scheme[caption] is an +@scheme[figure-ref] or @scheme[Figure-ref]. The @scheme[caption] is an element. The @scheme[pre-flow] is decoded as a flow. For HTML output, the @scheme[figure*] and @scheme[figure*] functions From 5104ced03a02357efab16eeebc495b5e381701aa Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Wed, 27 Oct 2010 18:32:31 -0400 Subject: [PATCH 056/746] HISTORY pre-release check (cherry picked from commit 41c084c95f95e549961eaf36871422d82e630e44) --- doc/release-notes/teachpack/HISTORY.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/release-notes/teachpack/HISTORY.txt b/doc/release-notes/teachpack/HISTORY.txt index 0afc0df16c..3c864c20f3 100644 --- a/doc/release-notes/teachpack/HISTORY.txt +++ b/doc/release-notes/teachpack/HISTORY.txt @@ -1,3 +1,15 @@ +------------------------------------------------------------------------ +Version 5.0.2. [Wed Oct 27 18:30:26 EDT 2010] + +* fixed stepper-universe interaction (on my side) +* record? allows specification of a directory +* small bug fixes +* small doc fixes + +* batch-io is now in shape to be used (somewhat) in 2e + +* robby added pinholes to his image teachpack + ------------------------------------------------------------------------ Version 5.0.1. [Tue Jul 20 20:52:09 EDT 2010] From 8340ad7111d11393378b562b670b0f3f51b0c038 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 3 Nov 2010 06:44:57 -0600 Subject: [PATCH 057/746] fix JIT bug related to ignored `let' bindings Closes PR 11380 (cherry picked from commit aaafe86dd0cfc1567ee21e4e5dc6480588cb99e0) --- src/racket/src/jit.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index bdc3e3f7fb..e681fdb9df 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -251,6 +251,7 @@ typedef struct { #define mz_RECORD_STATUS(s) (jitter->status_at_ptr = _jit.x.pc, jitter->reg_status = (s)) #define mz_CURRENT_STATUS() ((jitter->status_at_ptr == _jit.x.pc) ? jitter->reg_status : 0) +#define mz_CLEAR_STATUS() (jitter->reg_status = 0) #define mz_RS_R0_HAS_RUNSTACK0 0x1 @@ -9693,6 +9694,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte CHECK_LIMIT(); mz_flostack_restore(jitter, flostack, flostack_pos, !for_branch, 1); FOR_LOG(--jitter->log_depth); + mz_CLEAR_STATUS(); return v; } @@ -9781,6 +9783,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte } jitter->pushed_marks = save_pushed_marks; + mz_CLEAR_STATUS(); END_JIT_DATA(21); } From e36787bdebb7403ea180a140d88cf695d5eaea4c Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 4 Nov 2010 11:21:40 -0400 Subject: [PATCH 058/746] Fixed potential danger with fixnum optimizations. (cherry picked from commit c0a6137c67228933ad94d88409ffd86e30e922ae) --- .../typed-scheme/typecheck/tc-expr-unit.rkt | 17 ++++++++++++++--- collects/typed-scheme/types/abbrev.rkt | 3 +++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/collects/typed-scheme/typecheck/tc-expr-unit.rkt b/collects/typed-scheme/typecheck/tc-expr-unit.rkt index d0788b9a7c..0fd0402a41 100644 --- a/collects/typed-scheme/typecheck/tc-expr-unit.rkt +++ b/collects/typed-scheme/typecheck/tc-expr-unit.rkt @@ -21,6 +21,17 @@ (import tc-if^ tc-lambda^ tc-app^ tc-let^ check-subforms^) (export tc-expr^) +;; Is the number a fixnum on all the platforms Racket supports? +;; This check is done at compile time to typecheck literals. +;; Since a zo file compiled on a 64-bit system can be used on 32-bit +;; systems, we can't use the host fixnum? predicate, or large 64-bit +;; fixnums will typecheck as fixnums but not be actual fixnums on the +;; target system. In combination with fixnum typed optimizations, bad +;; things could happen. +(define (portable-fixnum? n) + (and (exact-integer? n) + (< n (expt 2 31)))) + ;; return the type of a literal value ;; scheme-value -> type (define (tc-literal v-stx [expected #f]) @@ -34,9 +45,9 @@ [i:boolean (-val (syntax-e #'i))] [i:identifier (-val (syntax-e #'i))] [0 -Zero] - [(~var i (3d (conjoin number? fixnum? positive?))) -PositiveFixnum] - [(~var i (3d (conjoin number? fixnum? negative?))) -NegativeFixnum] - [(~var i (3d (conjoin number? fixnum?))) -Fixnum] + [(~var i (3d (conjoin number? portable-fixnum? positive?))) -PositiveFixnum] + [(~var i (3d (conjoin number? portable-fixnum? negative?))) -NegativeFixnum] + [(~var i (3d (conjoin number? portable-fixnum?))) -Fixnum] [(~var i (3d exact-positive-integer?)) -ExactPositiveInteger] [(~var i (3d exact-nonnegative-integer?)) -ExactNonnegativeInteger] [(~var i (3d exact-integer?)) -Integer] diff --git a/collects/typed-scheme/types/abbrev.rkt b/collects/typed-scheme/types/abbrev.rkt index e69967b355..68bbdbfc4d 100644 --- a/collects/typed-scheme/types/abbrev.rkt +++ b/collects/typed-scheme/types/abbrev.rkt @@ -174,6 +174,9 @@ (define -ExactPositiveInteger (make-Base 'Exact-Positive-Integer #'exact-positive-integer?)) +;; We can safely use the fixnum? prediate here, unlike in tc-expr-unit. +;; The fixnum? here will be part of the generated contracts, which run +;; on the target system, so we're safe. (define -PositiveFixnum (make-Base 'Positive-Fixnum #'(and/c number? fixnum? positive?))) (define -NegativeFixnum From b28bdb5bc5c5218b618ff188f1423088f3c25cb2 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 4 Nov 2010 16:03:06 -0400 Subject: [PATCH 059/746] Fixed a fixnum typechecking issue. (cherry picked from commit 4c081c127ab91067c3a69568175d7274b090f986) --- .../typed-scheme/unit-tests/typecheck-tests.rkt | 6 ++++++ collects/typed-scheme/typecheck/tc-expr-unit.rkt | 15 ++++++--------- collects/typed-scheme/types/abbrev.rkt | 9 ++++----- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt b/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt index 5512094393..6c82cc3c2d 100644 --- a/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt +++ b/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt @@ -146,6 +146,12 @@ N] (tc-e/t (if (let ([y 12]) y) 3 4) -PositiveFixnum) (tc-e/t 3 -PositiveFixnum) + (tc-e/t 100 -PositiveFixnum) + (tc-e/t -100 -NegativeFixnum) + (tc-e/t 2147483647 -PositiveFixnum) + (tc-e/t -2147483647 -NegativeFixnum) + (tc-e/t 2147483648 -Pos) + (tc-e/t -2147483648 -Integer) (tc-e/t "foo" -String) (tc-e (+ 3 4) -Pos) [tc-e/t (lambda: () 3) (t:-> -PositiveFixnum : -true-lfilter)] diff --git a/collects/typed-scheme/typecheck/tc-expr-unit.rkt b/collects/typed-scheme/typecheck/tc-expr-unit.rkt index 0fd0402a41..6932cf09f6 100644 --- a/collects/typed-scheme/typecheck/tc-expr-unit.rkt +++ b/collects/typed-scheme/typecheck/tc-expr-unit.rkt @@ -22,15 +22,12 @@ (export tc-expr^) ;; Is the number a fixnum on all the platforms Racket supports? +;; This relies on Racket being compiled only on 32+ bit systems. ;; This check is done at compile time to typecheck literals. -;; Since a zo file compiled on a 64-bit system can be used on 32-bit -;; systems, we can't use the host fixnum? predicate, or large 64-bit -;; fixnums will typecheck as fixnums but not be actual fixnums on the -;; target system. In combination with fixnum typed optimizations, bad -;; things could happen. (define (portable-fixnum? n) (and (exact-integer? n) - (< n (expt 2 31)))) + (< n (expt 2 31)) + (> n (- (expt 2 31))))) ;; return the type of a literal value ;; scheme-value -> type @@ -45,9 +42,9 @@ [i:boolean (-val (syntax-e #'i))] [i:identifier (-val (syntax-e #'i))] [0 -Zero] - [(~var i (3d (conjoin number? portable-fixnum? positive?))) -PositiveFixnum] - [(~var i (3d (conjoin number? portable-fixnum? negative?))) -NegativeFixnum] - [(~var i (3d (conjoin number? portable-fixnum?))) -Fixnum] + [(~var i (3d (conjoin portable-fixnum? positive?))) -PositiveFixnum] + [(~var i (3d (conjoin portable-fixnum? negative?))) -NegativeFixnum] + [(~var i (3d (conjoin portable-fixnum?))) -Fixnum] [(~var i (3d exact-positive-integer?)) -ExactPositiveInteger] [(~var i (3d exact-nonnegative-integer?)) -ExactNonnegativeInteger] [(~var i (3d exact-integer?)) -Integer] diff --git a/collects/typed-scheme/types/abbrev.rkt b/collects/typed-scheme/types/abbrev.rkt index 68bbdbfc4d..fa0711a3ff 100644 --- a/collects/typed-scheme/types/abbrev.rkt +++ b/collects/typed-scheme/types/abbrev.rkt @@ -174,13 +174,12 @@ (define -ExactPositiveInteger (make-Base 'Exact-Positive-Integer #'exact-positive-integer?)) -;; We can safely use the fixnum? prediate here, unlike in tc-expr-unit. -;; The fixnum? here will be part of the generated contracts, which run -;; on the target system, so we're safe. +;; We're generating a reference to fixnum? rather than calling it, so +;; we're safe from fixnum size issues on different platforms. (define -PositiveFixnum - (make-Base 'Positive-Fixnum #'(and/c number? fixnum? positive?))) + (make-Base 'Positive-Fixnum #'(and/c fixnum? positive?))) (define -NegativeFixnum - (make-Base 'Negative-Fixnum #'(and/c number? fixnum? negative?))) + (make-Base 'Negative-Fixnum #'(and/c fixnum? negative?))) (define -Zero (-val 0)) (define -Real (*Un -InexactReal -ExactRational)) From 1652a908c7917b9e08680c9d137906179ee3d312 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 5 Nov 2010 01:33:57 -0400 Subject: [PATCH 060/746] Make the disabled places comment more prominent. (cherry picked from commit 84ec108c32a536c8238ca6861ab6aac7eda33db8) --- collects/scribblings/reference/places.scrbl | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/collects/scribblings/reference/places.scrbl b/collects/scribblings/reference/places.scrbl index aef84adfb3..3e0d1b3e2a 100644 --- a/collects/scribblings/reference/places.scrbl +++ b/collects/scribblings/reference/places.scrbl @@ -22,13 +22,12 @@ hardware threads. @note-lib[racket/place] -@margin-note{Currently, parallel support for @racket[place] is is only enabled if you pass -@DFlag{enable-places} to @exec{configure} when you build Racket (and -that build currently only works with @exec{racket}, not with -@exec{gracket}). When parallel-places support is not enabled, -@racket[place] usage is a syntax error. -Places is only supported on Linux x86/x86_64, and Mac OS X -x86/x86_64 platforms.} +Note: currently, parallel support for @racket[place] is disabled by +default, and using it will raise an exception. Support can only be +enabled if you build Racket yourself, and pass @DFlag{enable-places} to +@exec{configure}. This works only for @exec{racket} (not +@exec{gracket}), and it is supported only on Linux x86/x86_64, and Mac +OS X x86/x86_64 platforms. @defproc[(place [module-path module-path?] [start-proc symbol?]) place?]{ Starts running @racket[start-proc] in parallel. @racket[start-proc] must From 49c1a0d9461e59a976b2d85fd4638d0986219468 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 5 Nov 2010 01:46:01 -0400 Subject: [PATCH 061/746] Clarify comment re `fixnum?' non-use at the syntax level, and add a note to the `fixnum?' documentation. (cherry picked from commit 9a485064ed81366579f2a5c7cebf591de7e07be2) --- collects/scribblings/reference/numbers.scrbl | 5 ++++- collects/typed-scheme/typecheck/tc-expr-unit.rkt | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/collects/scribblings/reference/numbers.scrbl b/collects/scribblings/reference/numbers.scrbl index fda5625b5a..9988202a4d 100644 --- a/collects/scribblings/reference/numbers.scrbl +++ b/collects/scribblings/reference/numbers.scrbl @@ -149,7 +149,10 @@ Returns @racket[(and (real? v) (inexact? v))].} @defproc[(fixnum? [v any/c]) boolean?]{ Return @racket[#t] if @racket[v] is a @techlink{fixnum}, @racket[#f] -otherwise.} +otherwise. + +Note: the result of this function is platform-dependent, so using it in +syntax transformers can lead to platform-dependent bytecode files.} @defproc[(flonum? [v any/c]) boolean?]{ diff --git a/collects/typed-scheme/typecheck/tc-expr-unit.rkt b/collects/typed-scheme/typecheck/tc-expr-unit.rkt index 6932cf09f6..b5153d399e 100644 --- a/collects/typed-scheme/typecheck/tc-expr-unit.rkt +++ b/collects/typed-scheme/typecheck/tc-expr-unit.rkt @@ -21,9 +21,10 @@ (import tc-if^ tc-lambda^ tc-app^ tc-let^ check-subforms^) (export tc-expr^) -;; Is the number a fixnum on all the platforms Racket supports? -;; This relies on Racket being compiled only on 32+ bit systems. -;; This check is done at compile time to typecheck literals. +;; Is the number a fixnum on *all* the platforms Racket supports? This +;; works because Racket compiles only on 32+ bit systems. This check is +;; done at compile time to typecheck literals -- so use it instead of +;; `fixnum?' to avoid creating platform-dependent .zo files. (define (portable-fixnum? n) (and (exact-integer? n) (< n (expt 2 31)) From 0f9db7f9aad7eb6ed80dfb035d7edf4e5e2e20ea Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 6 Nov 2010 21:25:44 -0400 Subject: [PATCH 062/746] Update version number for the v5.0.2 release --- src/racket/src/schvers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index fea4623d18..9821651ac8 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.0.1.900" +#define MZSCHEME_VERSION "5.0.2" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 0 -#define MZSCHEME_VERSION_Z 1 -#define MZSCHEME_VERSION_W 900 +#define MZSCHEME_VERSION_Z 2 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 76680b839c269e3b04f30fcf05ee23d7883da939 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 6 Nov 2010 21:25:52 -0400 Subject: [PATCH 063/746] New Racket version 5.0.2. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index ae7eb2b7d5..2d7d517ac5 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,7 +1,7 @@ Date: Sun, 7 Nov 2010 00:46:22 -0400 Subject: [PATCH 064/746] v5.0.2 stuff (cherry picked from commit c195e2b2013ed16a5733a475f01dd0695267ac10) --- collects/meta/web/download/data.rkt | 3 ++- collects/meta/web/download/installers.txt | 30 ++++++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/collects/meta/web/download/data.rkt b/collects/meta/web/download/data.rkt index 89381ac7fa..2151633931 100644 --- a/collects/meta/web/download/data.rkt +++ b/collects/meta/web/download/data.rkt @@ -1,7 +1,8 @@ #lang racket/base (define -versions+dates- - '(["5.0.1" "August 2010"] + '(["5.0.2" "November 2010"] + ["5.0.1" "August 2010"] ["5.0" "June 2010"] ["4.2.5" "April 2010"] ["4.2.4" "January 2010"] diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index b78963ef8f..51e29f1d75 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -6,8 +6,8 @@ 8.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-darwin.sh 9.2M 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-osx-mac.dmg 9.0M 5.0.1/racket-textual/racket-textual-5.0.1-bin-x86_64-linux-f7.sh -4.9M 5.0.1/racket-textual/racket-textual-5.0.1-src-mac.dmg -4.8M 5.0.1/racket-textual/racket-textual-5.0.1-src-unix.tgz +5.6M 5.0.1/racket-textual/racket-textual-5.0.1-src-mac.dmg +5.5M 5.0.1/racket-textual/racket-textual-5.0.1-src-unix.tgz 6.8M 5.0.1/racket-textual/racket-textual-5.0.1-src-win.zip 47M 5.0.1/racket/racket-5.0.1-bin-i386-linux-debian.sh 47M 5.0.1/racket/racket-5.0.1-bin-i386-linux-f12.sh @@ -17,9 +17,31 @@ 46M 5.0.1/racket/racket-5.0.1-bin-ppc-darwin.sh 48M 5.0.1/racket/racket-5.0.1-bin-ppc-osx-mac.dmg 47M 5.0.1/racket/racket-5.0.1-bin-x86_64-linux-f7.sh -16M 5.0.1/racket/racket-5.0.1-src-mac.dmg -16M 5.0.1/racket/racket-5.0.1-src-unix.tgz +17M 5.0.1/racket/racket-5.0.1-src-mac.dmg +17M 5.0.1/racket/racket-5.0.1-src-unix.tgz 20M 5.0.1/racket/racket-5.0.1-src-win.zip +9.4M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-debian.sh +9.4M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-f12.sh +9.4M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-ubuntu-jaunty.sh +9.6M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-osx-mac.dmg +7.2M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-win32.exe +9.3M 5.0.2/racket-textual/racket-textual-5.0.2-bin-ppc-darwin.sh +9.6M 5.0.2/racket-textual/racket-textual-5.0.2-bin-ppc-osx-mac.dmg +9.5M 5.0.2/racket-textual/racket-textual-5.0.2-bin-x86_64-linux-f7.sh +5.7M 5.0.2/racket-textual/racket-textual-5.0.2-src-mac.dmg +5.6M 5.0.2/racket-textual/racket-textual-5.0.2-src-unix.tgz +7.0M 5.0.2/racket-textual/racket-textual-5.0.2-src-win.zip +48M 5.0.2/racket/racket-5.0.2-bin-i386-linux-debian.sh +48M 5.0.2/racket/racket-5.0.2-bin-i386-linux-f12.sh +48M 5.0.2/racket/racket-5.0.2-bin-i386-linux-ubuntu-jaunty.sh +50M 5.0.2/racket/racket-5.0.2-bin-i386-osx-mac.dmg +30M 5.0.2/racket/racket-5.0.2-bin-i386-win32.exe +48M 5.0.2/racket/racket-5.0.2-bin-ppc-darwin.sh +50M 5.0.2/racket/racket-5.0.2-bin-ppc-osx-mac.dmg +49M 5.0.2/racket/racket-5.0.2-bin-x86_64-linux-f7.sh +17M 5.0.2/racket/racket-5.0.2-src-mac.dmg +17M 5.0.2/racket/racket-5.0.2-src-unix.tgz +21M 5.0.2/racket/racket-5.0.2-src-win.zip 8.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-debian.sh 8.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-f12.sh 8.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-ubuntu-jaunty.sh From 41eb7b86f6feaf5c22591efab3b419e75236ff6e Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 29 Jan 2011 13:03:41 -0500 Subject: [PATCH 065/746] Alpha version number for the v5.1 release --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 81b362c6e9..0d548af42c 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.0.99.7" +#define MZSCHEME_VERSION "5.0.99.900" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 0 #define MZSCHEME_VERSION_Z 99 -#define MZSCHEME_VERSION_W 7 +#define MZSCHEME_VERSION_W 900 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 304e6dc873d4049c58123c3be695d710beadcb91 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 29 Jan 2011 12:26:59 -0600 Subject: [PATCH 066/746] added a color:text method get-token-range and then used that to improve how f1 in drracket works Please include this commit on the release branch (cherry picked from commit 4090eabacb8d7b32900b4df18da06f14f1def40f) --- collects/drracket/private/unit.rkt | 42 ++++++++++++++++------ collects/framework/private/color.rkt | 18 +++++++--- collects/scribblings/framework/color.scrbl | 12 ++++++- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/collects/drracket/private/unit.rkt b/collects/drracket/private/unit.rkt index 4b4b681fe1..8d75db3ddd 100644 --- a/collects/drracket/private/unit.rkt +++ b/collects/drracket/private/unit.rkt @@ -238,16 +238,38 @@ module browser threading seems wrong. [before+ (and before (send text get-forward-sexp before))] [after (send text get-forward-sexp pos)] [after- (and after (send text get-backward-sexp after))]) - (cond - [(and before before+ - (<= before pos before+) - (eq? 'symbol (send text classify-position before))) - (send text get-text before before+)] - [(and after after- - (<= after- pos after) - (eq? 'symbol (send text classify-position after-))) - (send text get-text after- after)] - [else ""]))] + + (define (get-tokens start end) + (let loop ([i start]) + (cond + [(and (< i end) + (< i (send text last-position))) + (define-values (tstart tend) (send text get-token-range i)) + (cons (list (send text classify-position i) tstart tend) + (loop tend))] + [else '()]))) + + ;; find-searchable-tokens : number number -> (or/c #f (list symbol number number)) + (define (find-searchable-tokens start end) + (define tokens (get-tokens start end)) + (define raw-tokens (map (λ (x) (list-ref x 0)) tokens)) + (cond + [(equal? raw-tokens '(symbol)) + (car tokens)] + [(equal? raw-tokens '(constant symbol)) + (cadr tokens)] + [else #f])) + + (define searchable-token + (or (and before before+ + (<= before pos before+) + (find-searchable-tokens before before+)) + (and after after- + (<= after- pos after) + (find-searchable-tokens after- after)))) + (if searchable-token + (send text get-text (list-ref searchable-token 1) (list-ref searchable-token 2)) + ""))] [else (send text split-snip pos) (send text split-snip (+ pos 1)) diff --git a/collects/framework/private/color.rkt b/collects/framework/private/color.rkt index f7be4ce51e..08ef4f5ecc 100644 --- a/collects/framework/private/color.rkt +++ b/collects/framework/private/color.rkt @@ -817,16 +817,26 @@ added get-regions ;; Determines whether a position is a 'comment, 'string, etc. (define/public (classify-position position) + (define tokens (get-tokens-at-position 'classify-position position)) + (and tokens + (let ([root-data (send tokens get-root-data)]) + (and root-data + (data-type root-data))))) + + (define/public (get-token-range position) + (define tokens (get-tokens-at-position 'get-token-range position)) + (values (and tokens (send tokens get-root-start-position)) + (and tokens (send tokens get-root-end-position)))) + + (define/private (get-tokens-at-position who position) (when stopped? - (error 'classify-position "called on a color:text<%> whose colorer is stopped.")) + (error who "called on a color:text<%> whose colorer is stopped.")) (let ([ls (find-ls position)]) (and ls (let ([tokens (lexer-state-tokens ls)]) (tokenize-to-pos ls position) (send tokens search! (- position (lexer-state-start-pos ls))) - (let ([root-data (send tokens get-root-data)]) - (and root-data - (data-type root-data))))))) + tokens)))) (define/private (tokenize-to-pos ls position) (when (and (not (lexer-state-up-to-date? ls)) diff --git a/collects/scribblings/framework/color.scrbl b/collects/scribblings/framework/color.scrbl index 979155fa5c..2dd561e6a1 100644 --- a/collects/scribblings/framework/color.scrbl +++ b/collects/scribblings/framework/color.scrbl @@ -212,7 +212,7 @@ right kind. If @scheme[flash?] is true, the matching open parenthesis will be flashed. } - @defmethod*[(((classify-position (position natural-number?)) symbol?))]{ + @defmethod*[(((classify-position (position exact-nonnegative-integer?)) symbol?))]{ Return a symbol for the lexer-determined token type for the token that @@ -221,6 +221,16 @@ Must only be called while the tokenizer is started. } + @defmethod[(get-token-range [position exact-nonnegative-integer?]) + (values (or/c #f exact-nonnegative-integer?) + (or/c #f exact-nonnegative-integer?))]{ + + Returns the range of the token surrounding @racket[position], if there is a token there. + + This method must be called only when the tokenizer is started. + + } + @defmethod[#:mode augment (on-lexer-valid [valid? boolean?]) any]{ This method is an observer for when the lexer is working. It is called when the lexer's state changes from valid to invalid (and back). From dbad6461b1a121439309a0a1e080d957701b3e99 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 29 Jan 2011 13:32:13 -0600 Subject: [PATCH 067/746] doc typo (cherry picked from commit e43fa461a424a1f47c13fb3f02004abbddb90952) --- collects/mzlib/scribblings/pconvert.scrbl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/collects/mzlib/scribblings/pconvert.scrbl b/collects/mzlib/scribblings/pconvert.scrbl index d3b51ab9e2..e7487c201c 100644 --- a/collects/mzlib/scribblings/pconvert.scrbl +++ b/collects/mzlib/scribblings/pconvert.scrbl @@ -135,8 +135,9 @@ integer.} @defparam[current-print-convert-hook hook - (any/c/ (any/c . -> . any/c) - (any/c . -> . any/c))]{ + (any/c (any/c . -> . any/c) + (any/c . -> . any/c) + . -> . any/c)]{ Parameter that sets a procedure used by @scheme[print-convert] and @scheme[print-convert-expr] to convert values. The procedure From aeb104af1ec7e5a0e9d6155f1ae08ea0afb4e429 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 29 Jan 2011 18:57:02 -0600 Subject: [PATCH 068/746] fix a docs typo closes PR 11677 (cherry picked from commit a7fb695c88741c049033081bb6cf7e9d58fd2918) --- collects/teachpack/2htdp/scribblings/image.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/teachpack/2htdp/scribblings/image.scrbl b/collects/teachpack/2htdp/scribblings/image.scrbl index eb5f4e9a76..d22aa8e81d 100644 --- a/collects/teachpack/2htdp/scribblings/image.scrbl +++ b/collects/teachpack/2htdp/scribblings/image.scrbl @@ -68,7 +68,7 @@ Existing images can be rotated, scaled, flipped, and overlaid on top of each oth [mode (or/c 'outline "outline")] [pen-or-color (or/c image-color? pen?)]) image?])]{ - Constructs an ellipsis with the given width, height, mode, and color. + Constructs an ellipse with the given width, height, mode, and color. @mode/color-text From e5b2badea34f72ecfabd3dbc51007d3c82e6fc5d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 30 Jan 2011 07:47:10 -0600 Subject: [PATCH 069/746] fix problems with `read-language' error reporting (cherry picked from commit bc5ab1e03128db600a6909e2150ebfdfb9b3dee6) --- collects/scribblings/reference/read.scrbl | 4 +++- collects/tests/racket/read.rktl | 8 ++++++++ src/racket/src/read.c | 9 ++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/collects/scribblings/reference/read.scrbl b/collects/scribblings/reference/read.scrbl index 9355611abb..3e63ed48b3 100644 --- a/collects/scribblings/reference/read.scrbl +++ b/collects/scribblings/reference/read.scrbl @@ -158,7 +158,9 @@ is @racket[#f]. If @racket[in] has a @litchar{#lang} or @litchar{#!} specification, but parsing and resolving the specification raises an exception, the -exception is propagated by @racket[read-language]. +exception is propagated by @racket[read-language]. Having at least +@litchar{#l} or @litchar{#!} (after comments and whitespace) counts as +starting a @litchar{#lang} or @litchar{#!} specification. If @racket[in] does not specify a @tech{reader language} with @litchar{#lang} or @litchar{#!}, then @racket[fail-thunk] is diff --git a/collects/tests/racket/read.rktl b/collects/tests/racket/read.rktl index 55a860963a..38f93b84d3 100644 --- a/collects/tests/racket/read.rktl +++ b/collects/tests/racket/read.rktl @@ -1095,6 +1095,14 @@ (check-nothing ";" exn:fail:read:eof?) (check-nothing "#| |#" exn:fail:read:eof?) (check-nothing "8 9" exn:fail:read?)) +(err/rt-test (read-language (open-input-string "#l") void) exn:fail:read:eof?) +(err/rt-test (read-language (open-input-string "#la") void) exn:fail:read:eof?) +(err/rt-test (read-language (open-input-string ";;\n;\n#la") void) exn:fail:read:eof?) +(err/rt-test (read-language (open-input-string ";;\n;\n#lx") void) exn:fail:read?) +(test (void) read-language (open-input-string ";;\n;\n#xa") void) +;; Check error-message formatting: +(err/rt-test (read (open-input-string "#l")) + (lambda (exn) (regexp-match? #rx"`#l'" (exn-message exn)))) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/racket/src/read.c b/src/racket/src/read.c index a1e31523d0..6f0535b408 100644 --- a/src/racket/src/read.c +++ b/src/racket/src/read.c @@ -1547,16 +1547,19 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table * } return v; } else { + if (ch == EOF) --fl; scheme_read_err(port, stxsrc, line, col, pos, 6, ch, indentation, - "read: expected a single space after `#lang'", - found, fl); + "read%s: expected a single space after `#lang'", + (get_info ? "-language" : "")); return NULL; } } } } + if (ch == EOF) --fl; scheme_read_err(port, stxsrc, line, col, pos, fl, ch, indentation, - "read: bad input: `#%u'", + "read%s: bad input: `#%u'", + (get_info ? "-language" : ""), found, (intptr_t)fl); return NULL; } From 01c641d14f210f0452bc0246c3ff2d2ba5725560 Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Sun, 30 Jan 2011 12:10:47 -0500 Subject: [PATCH 070/746] fix lazy take bug -- invariant being tested on unforced argument (cherry picked from commit 808361b789efe494df60cdd85cb154627d9fdeb6) --- collects/lazy/lazy.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/lazy/lazy.rkt b/collects/lazy/lazy.rkt index 1171091cad..8d386567ab 100644 --- a/collects/lazy/lazy.rkt +++ b/collects/lazy/lazy.rkt @@ -576,8 +576,8 @@ (define* (take n l) (let ([n0 (! n)]) - (unless (exact-nonnegative-integer? n) - (raise-type-error 'take "non-negative exact integer" 0 n l)) + (unless (exact-nonnegative-integer? n0) + (raise-type-error 'take "non-negative exact integer" 0 n0 l)) (let loop ([n n0] [l l]) (if (zero? n) '() From 58f98ed1dcee69bfa6d6e6fa492ac326830e780a Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Sun, 30 Jan 2011 12:12:55 -0500 Subject: [PATCH 071/746] add test for lazy take bug fix -- invariant being incorrectly tested on unforced arg (cherry picked from commit 08d99f4858bb20f82c9266eaadf7de87dba19e4b) --- collects/tests/lazy/langimpl.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collects/tests/lazy/langimpl.rkt b/collects/tests/lazy/langimpl.rkt index 30f20406a2..6dbee9933a 100644 --- a/collects/tests/lazy/langimpl.rkt +++ b/collects/tests/lazy/langimpl.rkt @@ -24,7 +24,9 @@ (! (first (take 4 test-lst1))) => 1 (! (second (take 4 test-lst1))) => 2 (! (third (take 4 test-lst1))) => 3 - (! (fourth (take 4 test-lst1))) =error> "take: index 4 too large for input list")) + (! (fourth (take 4 test-lst1))) =error> "take: index 4 too large for input list" + (! (list-ref (take (car (list 1)) (list 2)) 0)) => 2 + )) ; not working, only get 1 test passed #;(define (langimpl-tests) From 7c51edfe762f16cd39f043507a88e62f06f828c9 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 30 Jan 2011 13:52:04 -0500 Subject: [PATCH 072/746] Reorganize, improve, and extend lazy tests. (cherry picked from commit 6b5e09073a31c030122b310140060c6c7692ea96) --- collects/lazy/lazy.rkt | 4 +- collects/tests/lazy/forcers.rkt | 52 ++++++++++++++ collects/tests/lazy/lang.rkt | 113 ++++++++++++++++++------------- collects/tests/lazy/langimpl.rkt | 33 --------- collects/tests/lazy/main.rkt | 12 ++-- collects/tests/lazy/promise.rkt | 6 +- 6 files changed, 131 insertions(+), 89 deletions(-) create mode 100644 collects/tests/lazy/forcers.rkt delete mode 100644 collects/tests/lazy/langimpl.rkt diff --git a/collects/lazy/lazy.rkt b/collects/lazy/lazy.rkt index 8d386567ab..b881061803 100644 --- a/collects/lazy/lazy.rkt +++ b/collects/lazy/lazy.rkt @@ -337,7 +337,7 @@ (define* (~vector-set! vec i val) (~ (vector-set! (! vec) (! i) val))) (define* (~set-box! box val) (~ (set-box! (! box) val))) - ;; not much to do with these besides inserting strict points + ;; not much to do with these besides inserting strictness points and ~begin (define-syntax (~cond stx) (syntax-case stx () [(_ [test body ...] ...) @@ -598,6 +598,8 @@ ;; -------------------------------------------------------------------------- ;; mzlib/list functionality + ;; These are a hack, they're not the same due to different error + ;; messages (and they work with improper lists too). (define* (rest x) (~cdr x)) (define* (first x) (~car x)) (define* (second x) (~cadr x)) diff --git a/collects/tests/lazy/forcers.rkt b/collects/tests/lazy/forcers.rkt new file mode 100644 index 0000000000..6a922b6050 --- /dev/null +++ b/collects/tests/lazy/forcers.rkt @@ -0,0 +1,52 @@ +#lang racket/base + +(require tests/eli-tester lazy/force) + +(define (test-lazy/force) + (test (! 1) => 1 + (! (! 1)) => 1 + (! (~ 1)) => 1 + (! (~ (~ (~ 1)))) => 1)) + +(define (test-!list) + (test (!list (list 1 2 3)) => '(1 2 3) + (!list (~ (list 1 2 3))) => '(1 2 3) + (!list (~ (cons 1 (~ (cons 2 (~ (cons 3 (~ null)))))))) => '(1 2 3) + (!list 1) => 1 ; works on dotted lists + (!list (cons 1 2)) => '(1 . 2))) + +(define (test-!!list) + (test (!!list (list 1 2 3)) => '(1 2 3) + (!!list (list (~ 1) (~ 2) (~ 3))) => '(1 2 3) + (!!list (list* (~ 1) (~ 2) (~ 3))) => '(1 2 . 3) + (!!list (~ (cons (~ 1) (~ (cons (~ 2) (~ (cons (~ 3) (~ null)))))))) + => '(1 2 3) + (!!list (~ (cons (~ 1) (~ (list 2 3))))) => '(1 2 3) + (!!list (~ (cons (~ 1) (~ (list 2 (~ 3)))))) => '(1 2 3))) + +(define (test-!!) + (parameterize ([print-graph #t]) + (test + (!! (~ (cons (~ 1) (~ (cons (~ 2) (~ (cons (~ 3) (~ null)))))))) + => '(1 2 3) + (format "~s" (!! (letrec ([ones (~ (cons 1 (~ ones)))]) ones))) + => "#0=(1 . #0#)" + (format "~s" (!! (letrec ([ones (~ (cons 1 (~ ones)))]) (list ones ones)))) + => "(#0=(1 . #0#) #0#)" + (format "~s" (!! (letrec ([x (vector 1 (~ x))]) x))) + => "#0=#(1 #0#)" + (format "~s" (!! (letrec ([x (vector-immutable 1 (~ x))]) x))) + => "#0=#(1 #0#)" + (format "~s" (!! (letrec ([x (box (~ x))]) x))) + => "#0=#�#" + (format "~s" (!! (letrec ([x (box-immutable (~ x))]) x))) + => "#0=#�#" + (format "~s" (!! (letrec ([x (make-prefab-struct 'foo 1 (~ x))]) x))) + => "#0=#s(foo 1 #0#)"))) + +(provide forcer-tests) +(define (forcer-tests) + (test do (test-lazy/force) + do (test-!list) + do (test-!!list) + do (test-!!))) diff --git a/collects/tests/lazy/lang.rkt b/collects/tests/lazy/lang.rkt index 81feaa3969..535745cb3b 100644 --- a/collects/tests/lazy/lang.rkt +++ b/collects/tests/lazy/lang.rkt @@ -1,54 +1,75 @@ -#lang scheme/base +#lang lazy -(require tests/eli-tester lazy/force) +(require tests/eli-tester) -;; Currently this has only tests for the lazy language `!' forcer. +;; tests for lazy language constructs -(define (test-lazy/force) - (test (! 1) => 1 - (! (! 1)) => 1 - (! (~ 1)) => 1 - (! (~ (~ (~ 1)))) => 1)) +(define (basic-tests) + (test + (! ((car (list if)) (< 1 2) 3 (error "poof"))) => 3 + (! ((car (list or)) 3 (error "poof"))) => 3 + (! ((car (list and)) (< 2 1) (error "poof"))) => #f + (!! (let ([x 0]) (set! x 1) (list x))) => '(1) ; implicit begin forces + (! (let ([x 0]) (when (zero? x) (error "poof")) 1)) =error> "poof" + (! (let ([x 0]) (when (zero? x) (set! x (add1 x)) (set! x (add1 x))) x)) + => 2 + (! (let ([x 1]) (unless (zero? x) (set! x (add1 x)) (set! x (add1 x))) x)) + => 3 + (! (let ([x 0]) (cond [(zero? x) (set! x (add1 x)) (set! x (add1 x))]) x)) + => 2 + (! (eq? 1 1)) => #t + (! (eq? 1 2)) => #f + (! (eqv? 1.0 1.0)) => #t + (! (eqv? 1.0 1)) => #f + (! (= 1.0 1)) => #t + (! (equal? (list 1.0) (list 1.0))) => #t + (! (letrec ([zs (cons 0 zs)]) (equal? (list zs zs) (list zs zs)))) => #t + )) -(define (test-!list) - (test (!list (list 1 2 3)) => '(1 2 3) - (!list (~ (list 1 2 3))) => '(1 2 3) - (!list (~ (cons 1 (~ (cons 2 (~ (cons 3 (~ null)))))))) => '(1 2 3) - (!list 1) => 1 ; works on dotted lists - (!list (cons 1 2)) => '(1 . 2))) +(define (list-tests) + (test + (! (car 0)) =error> "car: expects argument of type " + (! (cdr 0)) =error> "cdr: expects argument of type " + (! (car (cons 1 (/ 1 0)))) => 1 + (! (cdr (cons (/ 1 0) 1))) => 1 + (! (list-ref (list (/ 1 0) 1 (/ 1 0)) 1)) => 1 + (! (list-ref (cons 1 (/ 1 0)) 0)) => 1 ; doesn't force list structure + (! (list-tail (cons (/ 1 0) 0) 1)) => 0 + (! (length (list (/ 1 0) (/ 1 0) (/ 1 0)))) => 3 + (! (let ([l (list (/ 1 0) (/ 1 0))]) (length (append l l l)))) => 6 + (!! (member 1 (cons 0 (cons 1 2)))) => '(1 . 2) + (!! (memq 1 (cons 0 (cons 1 2)))) => '(1 . 2) + (!! (memv 1 (cons 0 (cons 1 2)))) => '(1 . 2) + (! (second (map car (list 1 2 3)))) =error> "expects argument of type" + (! (second (map car (list 1 '(2) 3)))) => 2 + )) -(define (test-!!list) - (test (!!list (list 1 2 3)) => '(1 2 3) - (!!list (list (~ 1) (~ 2) (~ 3))) => '(1 2 3) - (!!list (list* (~ 1) (~ 2) (~ 3))) => '(1 2 . 3) - (!!list (~ (cons (~ 1) (~ (cons (~ 2) (~ (cons (~ 3) (~ null)))))))) - => '(1 2 3) - (!!list (~ (cons (~ 1) (~ (list 2 3))))) => '(1 2 3) - (!!list (~ (cons (~ 1) (~ (list 2 (~ 3)))))) => '(1 2 3))) - -(define (test-!!) - (parameterize ([print-graph #t]) - (test - (!! (~ (cons (~ 1) (~ (cons (~ 2) (~ (cons (~ 3) (~ null)))))))) - => '(1 2 3) - (format "~s" (!! (letrec ([ones (~ (cons 1 (~ ones)))]) ones))) - => "#0=(1 . #0#)" - (format "~s" (!! (letrec ([ones (~ (cons 1 (~ ones)))]) (list ones ones)))) - => "(#0=(1 . #0#) #0#)" - (format "~s" (!! (letrec ([x (vector 1 (~ x))]) x))) - => "#0=#(1 #0#)" - (format "~s" (!! (letrec ([x (vector-immutable 1 (~ x))]) x))) - => "#0=#(1 #0#)" - (format "~s" (!! (letrec ([x (box (~ x))]) x))) - => "#0=#�#" - (format "~s" (!! (letrec ([x (box-immutable (~ x))]) x))) - => "#0=#�#" - (format "~s" (!! (letrec ([x (make-prefab-struct 'foo 1 (~ x))]) x))) - => "#0=#s(foo 1 #0#)"))) +(define (take-tests) + (define test-lst1 '(1 2 3)) + (test + (! (take "nonnum" test-lst1)) + =error> + #rx"take: expects type as 1st .* '\\(1 2 3\\)" + (! (take -1 test-lst1)) + =error> "take: expects type as 1st argument" + (! (take -1 "nonlist")) + =error> "take: expects type as 1st argument" + (! (take 0 "nonlist")) => '() + (! (take 1 "nonlist")) =error> "take: not a proper list: \"nonlist\"" + (! (take 0 null)) => '() + (! (take 0 test-lst1)) => '() + (!! (take 1 test-lst1)) => '(1) + (!! (take 2 test-lst1)) => '(1 2) + (!! (take 3 (take 4 test-lst1))) => '(1 2 3) ; doesn't force the error + (! (fourth (take 4 test-lst1))) ; this one does + =error> "take: index 4 too large for input list" + (! (list-ref (take (~ 1) (list 2)) 0)) => 2 + (! (take 0 (error))) => '() ; doesn't even force the list structure + (!! (take 1 (cons 0 (error "poof")))) => '(0) + )) (provide lang-tests) (define (lang-tests) - (test do (test-lazy/force) - do (test-!list) - do (test-!!list) - do (test-!!))) + (! (begin (basic-tests) + (list-tests) + (take-tests)))) diff --git a/collects/tests/lazy/langimpl.rkt b/collects/tests/lazy/langimpl.rkt deleted file mode 100644 index 6dbee9933a..0000000000 --- a/collects/tests/lazy/langimpl.rkt +++ /dev/null @@ -1,33 +0,0 @@ -#lang scheme/base - -(require tests/eli-tester lazy) - -;; tests for lazy language constructs -;; add tests as needed - -(provide test-take) - -(define (test-take) - (define test-lst1 '(1 2 3)) - (test (! (take "nonnum" test-lst1)) =error> "take: expects type as 1st argument, given: \"nonnum\"; other arguments were: (1 2 3)" - (! (take -1 test-lst1)) =error> "take: expects type as 1st argument, given: -1; other arguments were: (1 2 3)" - (! (take -1 "nonlist")) =error> "take: expects type as 1st argument, given: -1; other arguments were: \"nonlist\"" - (! (take 0 "nonlist")) => '() ; this is how Racket's take behaves - (! (take 1 "nonlist")) =error> "take: not a proper list: \"nonlist\"" - (! (take 0 null)) => '() - (! (take 0 test-lst1)) => '() ; test for push#22080 - (! (car (take 1 test-lst1))) => 1 - (! (cdr (take 1 test-lst1))) => '() - (! (first (take 2 test-lst1))) => 1 - (! (second (take 2 test-lst1))) => 2 - (! (cddr (take 2 test-lst1))) => '() - (! (first (take 4 test-lst1))) => 1 - (! (second (take 4 test-lst1))) => 2 - (! (third (take 4 test-lst1))) => 3 - (! (fourth (take 4 test-lst1))) =error> "take: index 4 too large for input list" - (! (list-ref (take (car (list 1)) (list 2)) 0)) => 2 - )) - -; not working, only get 1 test passed -#;(define (langimpl-tests) - (test (test-take))) \ No newline at end of file diff --git a/collects/tests/lazy/main.rkt b/collects/tests/lazy/main.rkt index eb81b0fa86..d83898e135 100644 --- a/collects/tests/lazy/main.rkt +++ b/collects/tests/lazy/main.rkt @@ -1,9 +1,7 @@ -#lang scheme/base +#lang racket/base -(require tests/eli-tester "promise.rkt" "lang.rkt" "langimpl.rkt") +(require tests/eli-tester "promise.rkt" "forcers.rkt" "lang.rkt") -(test do (lang-tests) -; do (langimpl-tests) ; not working, so import test-take directly - do (test-take) - do (promise-tests) -) +(test do (promise-tests) + do (forcer-tests) + do (lang-tests)) diff --git a/collects/tests/lazy/promise.rkt b/collects/tests/lazy/promise.rkt index 71e347fa9c..0dfb2b9ef1 100644 --- a/collects/tests/lazy/promise.rkt +++ b/collects/tests/lazy/promise.rkt @@ -1,6 +1,8 @@ -#lang scheme/base +#lang racket/base -(require scheme/promise tests/eli-tester (for-syntax scheme/base)) +;; Tests for the various racket promises + +(require racket/promise tests/eli-tester (for-syntax racket/base)) ;; check that things are `promise?'s or not (define (test-types) From 60cc50a54bf2e274b024aa606fdbed55dcc3e24b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 30 Jan 2011 15:39:40 -0600 Subject: [PATCH 073/746] avoid `on-size' problems Merge to 5.1 (cherry picked from commit e2c43bf3ecc969112693e926bbbb7cf846fea4eb) --- collects/mred/private/wxwindow.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/mred/private/wxwindow.rkt b/collects/mred/private/wxwindow.rkt index dc18af233d..7d82d2731d 100644 --- a/collects/mred/private/wxwindow.rkt +++ b/collects/mred/private/wxwindow.rkt @@ -206,8 +206,8 @@ (set! old-h h) (as-exit (lambda () (send mred on-size w h))))) (let* ([p (area-parent)] - [x (- (get-x) (or (and p (send p dx)) 0))] - [y (- (get-y) (or (and p (send p dy)) 0))]) + [x (max -10000 (min 10000 (- (get-x) (or (and p (send p dx)) 0))))] + [y (max -10000 (min 10000 (- (get-y) (or (and p (send p dy)) 0))))]) (when (not (and (= x old-x) (= y old-y))) (set! old-x x) (set! old-y y) From 3112877e2b216fdebd7e3b6df82d76ed0e14ed38 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 30 Jan 2011 15:39:50 -0600 Subject: [PATCH 074/746] cocoa: create window to show composition via an input method Merge to 5.1 (cherry picked from commit bbb12848d191d6d7a03513ce17463f649410a570) --- collects/mred/private/wx/cocoa/window.rkt | 71 +++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/collects/mred/private/wx/cocoa/window.rkt b/collects/mred/private/wx/cocoa/window.rkt index a6a597da60..409b6ef5eb 100644 --- a/collects/mred/private/wx/cocoa/window.rkt +++ b/collects/mred/private/wx/cocoa/window.rkt @@ -68,13 +68,15 @@ [-a _BOOL (resignFirstResponder) (and (super-tell resignFirstResponder) (let ([wx (->wx wxb)]) - (when wx (send wx is-responder wx #f)) + (when wx + (send wx is-responder wx #f) + (send wx set-saved-marked #f #f)) #t))] [-a _void (changeColor: [_id sender]) (let ([wx (->wx wxb)]) (when wx (send wx on-color-change)))]) -(import-class NSArray) +(import-class NSArray NSPanel NSTextView) (import-protocol NSTextInput) (define current-insert-text (make-parameter #f)) @@ -257,6 +259,12 @@ (substring s start (max (+ start (NSRange-length range)) (string-length s))))) +(define-objc-class InputMethodPanel NSPanel + [] + [-a _BOOL (canBecomeKeyWindow) #f] + [-a _BOOL (canBecomeMainWindow) #f] + [-a _void (windowDidResize: [_id notification]) + (reset-input-method-window-size)]) (define-objc-mixin (KeyMouseTextResponder Superclass) #:mixins (KeyMouseResponder) @@ -812,9 +820,64 @@ ;; For multi-key character composition: (define saved-marked #f) (define saved-sel #f) - (define/public (set-saved-marked v sel) (set! saved-marked v) (set! saved-sel sel)) + (define/public (set-saved-marked v sel) + (set! saved-marked v) + (set! saved-sel sel) + (if (and v + (not (string=? v "")) + ;; Don't show the window for an empty string or certain + ;; simple combinations (probably a better way than this); + (not (member v '("¨" "ˆ" "´" "`" "˜")))) + (create-compose-window) + (when compose-cocoa + (tellv compose-cocoa orderOut: #f)))) (define/public (get-saved-marked) saved-marked) - (define/public (get-saved-selected) saved-sel))) + (define/public (get-saved-selected) saved-sel) + + (define/private (create-compose-window) + (unless compose-cocoa + (set! compose-cocoa (tell (tell InputMethodPanel alloc) + initWithContentRect: #:type _NSRect (make-NSRect + (make-NSPoint 0 20) + (make-NSSize 300 20)) + styleMask: #:type _int (bitwise-ior NSUtilityWindowMask + NSResizableWindowMask + NSClosableWindowMask) + backing: #:type _int NSBackingStoreBuffered + defer: #:type _BOOL NO)) + (set! compose-text (tell (tell NSTextView alloc) + initWithFrame: #:type _NSRect (make-NSRect + (make-NSPoint 0 0) + (make-NSSize 10 10)))) + (tellv compose-cocoa setFloatingPanel: #:type _BOOL #t) + (tellv (tell compose-cocoa contentView) addSubview: compose-text) + (tellv compose-text sizeToFit) + (tellv compose-cocoa setContentBorderThickness: #:type _CGFloat 5.0 forEdge: #:type _int 1) + (let ([h (+ (NSSize-height + (NSRect-size + (tell #:type _NSRect + compose-cocoa frameRectForContentRect: + #:type _NSRect (make-NSRect (make-NSPoint 0 0) + (make-NSSize 0 0))))) + (NSSize-height (NSRect-size (tell #:type _NSRect compose-text frame))))]) + (tellv compose-cocoa setMinSize: #:type _NSSize (make-NSSize 1 h)) + (tellv compose-cocoa setMaxSize: #:type _NSSize (make-NSSize 32000 h)) + (tellv compose-cocoa setFrame: #:type _NSRect (make-NSRect (make-NSPoint 0 20) + (make-NSSize 300 h)) + display: #:type _BOOL #t)) + (reset-input-method-window-size) + (tellv compose-cocoa setDelegate: compose-cocoa)) + (tellv compose-text + setMarkedText: #:type _NSString saved-marked + selectedRange: #:type _NSRange (make-NSRange (car saved-sel) (cdr saved-sel))) + (tellv compose-cocoa orderFront: #f)))) + +(define (reset-input-method-window-size) + (tell compose-text setFrame: #:type _NSRect + (tell #:type _NSRect (tell compose-cocoa contentView) frame))) + +(define compose-cocoa #f) +(define compose-text #f) ;; ---------------------------------------- From 7b34013eda4d193cf350690ef925e2960e7c6d79 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 31 Jan 2011 06:43:47 -0600 Subject: [PATCH 075/746] attempt to clarify the overlay/xy and underlay/xy documentation Merge to 5.1 (cherry picked from commit 3add4bce4d822a92f1b5f9729a62d8fd48b1a833) --- .../teachpack/2htdp/scribblings/image.scrbl | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/collects/teachpack/2htdp/scribblings/image.scrbl b/collects/teachpack/2htdp/scribblings/image.scrbl index d22aa8e81d..cb54ea8d11 100644 --- a/collects/teachpack/2htdp/scribblings/image.scrbl +++ b/collects/teachpack/2htdp/scribblings/image.scrbl @@ -661,17 +661,21 @@ the @scheme[point-count] argument determines how many points the star has. } @defproc[(overlay/xy [i1 image?] [x real?] [y real?] [i2 image?]) image?]{ - Constructs an image by overlaying @racket[i1] on top of @racket[i2] after - shifting @racket[i2] over by @racket[x] pixels to the right and @racket[y] - pixels down. + Constructs an image by overlaying @racket[i1] on top of @racket[i2]. + The images are initially lined up on their upper-left corners and + then @racket[i2] is shifted to the right + by @racket[x] pixels to and down by @racket[y] pixels. + + This is the same as @racket[(underlay/xy i2 (- x) (- y) i1)]. + @image-examples[(overlay/xy (rectangle 20 20 "outline" "black") 20 0 (rectangle 20 20 "outline" "black")) (overlay/xy (rectangle 20 20 "solid" "red") - 20 20 + 10 10 (rectangle 20 20 "solid" "black")) (overlay/xy (rectangle 20 20 "solid" "red") - -20 -20 + -10 -10 (rectangle 20 20 "solid" "black")) (overlay/xy (overlay/xy (ellipse 40 40 "outline" "black") @@ -738,9 +742,10 @@ the @scheme[point-count] argument determines how many points the star has. } @defproc[(underlay/xy [i1 image?] [x real?] [y real?] [i2 image?]) image?]{ - Constructs an image by underlaying @racket[i1] underneath of @racket[i2] after - shifting @racket[i2] over by @racket[x] pixels to the right and @racket[y] - pixels down. + Constructs an image by underlaying @racket[i1] underneath @racket[i2]. + The images are initially lined up on their upper-left corners and + then @racket[i2] is shifted to the right + by @racket[x] pixels to and down by @racket[y] pixels. This is the same as @racket[(overlay/xy i2 (- x) (- y) i1)]. @@ -748,10 +753,10 @@ the @scheme[point-count] argument determines how many points the star has. 20 0 (rectangle 20 20 "outline" "black")) (underlay/xy (rectangle 20 20 "solid" "red") - 20 20 + 10 10 (rectangle 20 20 "solid" "black")) (underlay/xy (rectangle 20 20 "solid" "red") - -20 -20 + -10 -10 (rectangle 20 20 "solid" "black")) (underlay/xy (underlay/xy (ellipse 40 40 "solid" "gray") From c417d1f39d3bd98b73aab9ae8fb8c68e545cc56f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 31 Jan 2011 06:47:37 -0700 Subject: [PATCH 076/746] fix `read-language' exn construction in an EOF case Closes PR 11683 Merge to 5.1 (cherry picked from commit dd5f0dfc80ddaf6e7d3215519a08d907928c0e5a) --- collects/tests/racket/read.rktl | 7 +++++++ src/racket/src/read.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/collects/tests/racket/read.rktl b/collects/tests/racket/read.rktl index 38f93b84d3..3ccbb96391 100644 --- a/collects/tests/racket/read.rktl +++ b/collects/tests/racket/read.rktl @@ -1103,6 +1103,13 @@ ;; Check error-message formatting: (err/rt-test (read (open-input-string "#l")) (lambda (exn) (regexp-match? #rx"`#l'" (exn-message exn)))) +;; Make sure read-language error here is this can comes from read-language +;; and not from an ill-formed srcloc construction: +(let () + (define p (open-input-string ";\n")) + (port-count-lines! p) + (err/rt-test (read-language p) + (lambda (exn) (regexp-match? #rx"read-language" (exn-message exn))))) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/racket/src/read.c b/src/racket/src/read.c index 6f0535b408..fb99bc50eb 100644 --- a/src/racket/src/read.c +++ b/src/racket/src/read.c @@ -992,6 +992,13 @@ read_inner_inner(Scheme_Object *port, Scheme_Object *stxsrc, Scheme_Hash_Table * dispatch_ch = ch; if (get_info && (dispatch_ch != '#') && (dispatch_ch != ';')) { + /* If ch is EOF, then col or pos wasn't incremented by reading ch. + The col and pos might be used in an error message, which expects + to subtract one from each --- so counteract by adding one here. */ + if (ch == EOF) { + if (pos >= 0) pos++; + if (col >= 0) col++; + } return expected_lang("", ch, port, stxsrc, line, col, pos, get_info); } From 40055e2ba18c2da1ca41589395f12afc557aa3d5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 31 Jan 2011 12:39:57 -0700 Subject: [PATCH 077/746] cocoa: fix problem with dispatching key-up events Closes PR 11635 Merge to 5.1 (cherry picked from commit 152c636e1cd943a8f306fb5f96ed0197c2215e08) --- collects/mred/private/wx/cocoa/menu-bar.rkt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/collects/mred/private/wx/cocoa/menu-bar.rkt b/collects/mred/private/wx/cocoa/menu-bar.rkt index 2a3fde20f5..3bf8f0f8dd 100644 --- a/collects/mred/private/wx/cocoa/menu-bar.rkt +++ b/collects/mred/private/wx/cocoa/menu-bar.rkt @@ -58,7 +58,12 @@ (and r (begin (parameterize ([recurring-for-command #t]) - (tell r keyDown: evt)) + (let ([evt-type (tell #:type _NSInteger evt type)]) + (cond + [(= NSKeyDown evt-type) + (tell r keyDown: evt)] + [(= NSKeyUp evt-type) + (tell r keyUp: evt)]))) #t))))))))) (define cocoa-mb (tell (tell MyBarMenu alloc) init)) From ff18afc1a9a964231d100aef02e5791caad5dc92 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 28 Jan 2011 12:36:50 -0500 Subject: [PATCH 078/746] Documented opt-lambda: and popt-lambda:. (cherry picked from commit 4b3e621d0ff54671befe96bff3c49109128e8861) --- collects/typed-scheme/scribblings/ts-reference.scrbl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/collects/typed-scheme/scribblings/ts-reference.scrbl b/collects/typed-scheme/scribblings/ts-reference.scrbl index 84cb9545e7..710f0c70ef 100644 --- a/collects/typed-scheme/scribblings/ts-reference.scrbl +++ b/collects/typed-scheme/scribblings/ts-reference.scrbl @@ -296,6 +296,14 @@ A function of multiple arities. Note that each @racket[formals] must have a different arity.} @defform[(pcase-lambda: (a ...) [formals body] ...)]{ A polymorphic function of multiple arities.} +@defform/subs[(opt-lambda: formals . body) +([formals ([v : t] ... [v : t default] ...) + ([v : t] ... [v : t default] ... . [v : t *]) + ([v : t] ... [v : t default] ... . [v : t ...])])]{ +A function with optional arguments.} +@defform[(popt-lambda: (a ...) formals . body)]{ +A polymorphic function with optional arguments.} + @subsection{Loops} From 7a6d3c91e753046a9ae8459b7a0aefb4ab0522b4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 31 Jan 2011 19:24:49 -0700 Subject: [PATCH 079/746] update Racket history for v5.1 Merge to 5.1 (cherry picked from commit 44987d3ce2e376bca441a81a00878f8db4466bf5) --- doc/release-notes/racket/HISTORY.txt | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index d271c0416a..c0f3d7d52f 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,12 +1,9 @@ -5.0.99.7 -add `current-get-interaction-input-port', which enables - `racket/gui' events to be dispatched while a REPL is blocked - -5.0.99.2 -proxy => impersonator -equal? equates C pointers when they refer to the same address - -5.0.99.1 +Version 5.1, February 2011 +Renamed "proxy" to "impersonator" +Added current-get-interaction-input-port, which enables + racket/gui events to be dispatched while a REPL is blocked +Changed equal? to equate C pointers when they refer to the + same address Internal: weak boxes are cleared before non-will-like finalizers; use late-weak boxes to get the old behavior From f3085a81687f707214b40e33ad9e0796678b91b2 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 31 Jan 2011 22:35:33 -0500 Subject: [PATCH 080/746] New Racket version 5.0.99.900. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index d75e6b00fa..941b5f5e49 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 46976b91aa..8f0813a5e4 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,0,99,7 - PRODUCTVERSION 5,0,99,7 + FILEVERSION 5,0,99,900 + PRODUCTVERSION 5,0,99,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 0, 99, 7\0" + VALUE "FileVersion", "5, 0, 99, 900\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 0, 99, 7\0" + VALUE "ProductVersion", "5, 0, 99, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index e8be126ef2..0438cdff0a 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,0,99,7 - PRODUCTVERSION 5,0,99,7 + FILEVERSION 5,0,99,900 + PRODUCTVERSION 5,0,99,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 0, 99, 7" + VALUE "FileVersion", "5, 0, 99, 900" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 0, 99, 7" + VALUE "ProductVersion", "5, 0, 99, 900" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index 5050eba105..c9060e92d7 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.0.99.7 = s 'MzObj Class' + MzCOM.MzObj.5.0.99.900 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.0.99.7' + CurVer = s 'MzCOM.MzObj.5.0.99.900' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.0.99.7' + ProgID = s 'MzCOM.MzObj.5.0.99.900' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 0b5d08fee3..a07b1295c6 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 8909243ff5..5f0abe42b2 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,0,99,7 - PRODUCTVERSION 5,0,99,7 + FILEVERSION 5,0,99,900 + PRODUCTVERSION 5,0,99,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 0, 99, 7\0" + VALUE "FileVersion", "5, 0, 99, 900\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 0, 99, 7\0" + VALUE "ProductVersion", "5, 0, 99, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 03a1e24625..3774e48ce9 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,0,99,7 - PRODUCTVERSION 5,0,99,7 + FILEVERSION 5,0,99,900 + PRODUCTVERSION 5,0,99,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 0, 99, 7\0" + VALUE "FileVersion", "5, 0, 99, 900\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 0, 99, 7\0" + VALUE "ProductVersion", "5, 0, 99, 900\0" END END BLOCK "VarFileInfo" From 62e35844fb26f4022c2d5c66b7455a9c3dceb636 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Feb 2011 06:41:49 -0700 Subject: [PATCH 081/746] fix problem with `raco exe' Merge to 5.1 (cherry picked from commit b70e1eca60d2795bd9a0224dad235b646704935d) --- collects/compiler/distribute.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collects/compiler/distribute.rkt b/collects/compiler/distribute.rkt index f31c28b119..22c6cfab99 100644 --- a/collects/compiler/distribute.rkt +++ b/collects/compiler/distribute.rkt @@ -378,7 +378,9 @@ (let loop ([exts exts][counter counter]) (cond [(null? exts) (values null counter)] - [(eq? 'module (cadar (car exts))) + [(and (pair? (car (car exts))) + (pair? (cdar (car exts))) + (eq? 'module (cadar (car exts)))) (let-values ([(rest-exts counter) (loop (cdr exts) counter)]) (values (cons (car exts) rest-exts) counter))] From 2de895ce467d2facc4913a2616a411210b72a089 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Feb 2011 07:52:19 -0700 Subject: [PATCH 082/746] minor man-page corrections Merge to 5.1 (cherry picked from commit 0011b386ba5e80dd33ce69ba0f1b05ce0d3284cd) --- man/man1/gracket.1 | 4 ++-- man/man1/racket.1 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man/man1/gracket.1 b/man/man1/gracket.1 index d07e1a8b9d..9f89b570bd 100644 --- a/man/man1/gracket.1 +++ b/man/man1/gracket.1 @@ -30,11 +30,11 @@ is the same as supplying the option for interactive evaluation. .PP -Supplying a single non-switch argument to +Supplying non-switch, non-configuration arguments to .B gracket is the same as putting .B -u -before the argument to run it as a module-based script. +before the arguments to run the first one as a module-based script. .SH MORE INFORMATION For further information, run diff --git a/man/man1/racket.1 b/man/man1/racket.1 index 23b399ba0a..5e3d980670 100644 --- a/man/man1/racket.1 +++ b/man/man1/racket.1 @@ -25,11 +25,11 @@ is the same as supplying the option for interactive evaluation. .PP -Supplying a single non-switch argument to +Supplying non-switch, non-configuration arguments to .B racket is the same as putting .B -u -before the argument to run it as a module-based script. +before the arguments to run the first one as a module-based script. .SH MORE INFORMATION For further information, run From 0b9f8bcabe506acccee950e762a095342a73b881 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Tue, 1 Feb 2011 08:55:24 -0700 Subject: [PATCH 083/746] External versions Merge to release branch (cherry picked from commit 0aa19be48e0c736a6193ba284d9dc39c6f88af06) --- collects/web-server/compat/0/README | 4 ++-- collects/web-server/scribblings/faq.scrbl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/web-server/compat/0/README b/collects/web-server/compat/0/README index 9b75f4b435..d07e4c9f18 100644 --- a/collects/web-server/compat/0/README +++ b/collects/web-server/compat/0/README @@ -1,7 +1,7 @@ -In Racket 5.0.99.4 and before, the Web Server supported implicit +In Racket 5.0.2 and before, the Web Server supported implicit conversion of X-expressions and lists with the format (cons/c bytes? (listof (or/c string? bytes?))) into response data structures for output. -After 5.0.99.4, this implicit conversion has been generalized into any->response. In the process, implicit conversion has been completely removed from some internal plumbing AND the response structures have been streamlined---primarily for efficiency. +After 5.0.2, this implicit conversion has been generalized into any->response. In the process, implicit conversion has been completely removed from some internal plumbing AND the response structures have been streamlined---primarily for efficiency. This document describes the incompatible changes and how to restore the old behavior when that is possible. diff --git a/collects/web-server/scribblings/faq.scrbl b/collects/web-server/scribblings/faq.scrbl index dfa56abfc9..61d03a9baf 100644 --- a/collects/web-server/scribblings/faq.scrbl +++ b/collects/web-server/scribblings/faq.scrbl @@ -5,7 +5,7 @@ @section{Why is my servlet failing with a @racket[can-be-response?] contract violation after updating Racket?} -After 5.0.99.4, the Web Server had a backwards incompatible change that prevents X-expressions and lists of bytes from being directly returned from servlets. Please read @filepath{PLTHOME/collects/web-server/compat/0/README} to learn about porting your servlets forward. Don't worry. It's easy. +After 5.0.2, the Web Server had a backwards incompatible change that prevents X-expressions and lists of bytes from being directly returned from servlets. Please read @filepath{PLTHOME/collects/web-server/compat/0/README} to learn about porting your servlets forward. Don't worry. It's easy. @section{Why are my templates not updating on the server when I change the file on disk?} From 51e37ac3824d7bb1a92f9230fde91285c2d5f95a Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 1 Feb 2011 10:12:24 -0600 Subject: [PATCH 084/746] updated release notes please merge to 5.1 branch (cherry picked from commit d5749aebba5893e52a80881be37a3f3e8ababb2a) --- doc/release-notes/drracket/HISTORY.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/release-notes/drracket/HISTORY.txt b/doc/release-notes/drracket/HISTORY.txt index e2fe0a551d..338420147f 100644 --- a/doc/release-notes/drracket/HISTORY.txt +++ b/doc/release-notes/drracket/HISTORY.txt @@ -1,7 +1,9 @@ ------------------------------ - Version 5.0.2 + Version 5.1 ------------------------------ + . same (the game) has a new scoring system and different graphics + . Added image->color-list and color-list->bitmap to 2htdp/image From bb5407a24a59be7edd877681bac0b543a04d5201 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 1 Feb 2011 12:12:36 -0600 Subject: [PATCH 085/746] add an extra check to make sure drracket is more likely to startup when things go wrong in strange ways Please merge to the 5.1 release branch (cherry picked from commit 823b6629aae7a1c668c2dffb2d89a16fc4a5889c) --- collects/drracket/private/module-language.rkt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/collects/drracket/private/module-language.rkt b/collects/drracket/private/module-language.rkt index e7801396c5..34916eb38f 100644 --- a/collects/drracket/private/module-language.rkt +++ b/collects/drracket/private/module-language.rkt @@ -82,7 +82,11 @@ (set! sandbox (make-evaluator 'racket/base))))) (define/override (first-opened settings) - (define ns (get-ns (get-auto-text settings))) + (define ns (with-handlers ((exn:fail? (lambda (x) #f))) + ;; get-ns can fail in all kinds of strange ways; + ;; just give up if it does, since an error here + ;; means drracket won't start up. + (get-ns (get-auto-text settings)))) (when ns (current-namespace ns))) (define/private (get-ns str) From b11a9de62b78e4db932fdc8bcacd9f7611964c5d Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 1 Feb 2011 14:49:57 -0600 Subject: [PATCH 086/746] fix the get-token-range method in the case that the colorer's current region doesn't start at the begining of the buffer Please merge to the release branch (cherry picked from commit 8c6c1a0e9bfee79db27b6234a806df533b5bd7cb) --- collects/framework/private/color.rkt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/collects/framework/private/color.rkt b/collects/framework/private/color.rkt index 08ef4f5ecc..a1203f8fd1 100644 --- a/collects/framework/private/color.rkt +++ b/collects/framework/private/color.rkt @@ -817,16 +817,18 @@ added get-regions ;; Determines whether a position is a 'comment, 'string, etc. (define/public (classify-position position) - (define tokens (get-tokens-at-position 'classify-position position)) + (define-values (tokens ls) (get-tokens-at-position 'classify-position position)) (and tokens (let ([root-data (send tokens get-root-data)]) (and root-data (data-type root-data))))) (define/public (get-token-range position) - (define tokens (get-tokens-at-position 'get-token-range position)) - (values (and tokens (send tokens get-root-start-position)) - (and tokens (send tokens get-root-end-position)))) + (define-values (tokens ls) (get-tokens-at-position 'get-token-range position)) + (values (and tokens (+ (lexer-state-start-pos ls) + (send tokens get-root-start-position))) + (and tokens (+ (lexer-state-start-pos ls) + (send tokens get-root-end-position))))) (define/private (get-tokens-at-position who position) (when stopped? @@ -836,7 +838,7 @@ added get-regions (let ([tokens (lexer-state-tokens ls)]) (tokenize-to-pos ls position) (send tokens search! (- position (lexer-state-start-pos ls))) - tokens)))) + (values tokens ls))))) (define/private (tokenize-to-pos ls position) (when (and (not (lexer-state-up-to-date? ls)) From 8c312b3181fa97ebd168636f5f8f01c620e40d79 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 1 Feb 2011 17:47:57 -0500 Subject: [PATCH 087/746] Document the Path-String type. (cherry picked from commit 3c081d8fa7ed9f7328d6f9acffda4ef591da4e47) --- collects/typed-scheme/scribblings/ts-reference.scrbl | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/typed-scheme/scribblings/ts-reference.scrbl b/collects/typed-scheme/scribblings/ts-reference.scrbl index 710f0c70ef..48bcd6dc7b 100644 --- a/collects/typed-scheme/scribblings/ts-reference.scrbl +++ b/collects/typed-scheme/scribblings/ts-reference.scrbl @@ -79,6 +79,7 @@ default in Racket. @defidform[Input-Port] @defidform[Output-Port] @defidform[Path] +@defidform[Path-String] @defidform[Regexp] @defidform[PRegexp] @defidform[Bytes] From 6b121cdce64aa596eec408bb1c4741d1f9e65fea Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 1 Feb 2011 16:32:34 -0700 Subject: [PATCH 088/746] warning to stderr, not stdout See PR 11691 Merge to release branch (cherry picked from commit fd3595e7d30b7fcabba84185f8d5c4e6d63aa239) --- collects/parser-tools/lex.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/parser-tools/lex.rkt b/collects/parser-tools/lex.rkt index 279287553d..e9983ab962 100644 --- a/collects/parser-tools/lex.rkt +++ b/collects/parser-tools/lex.rkt @@ -113,7 +113,7 @@ (let ((next-check (vector-ref next 1))) (or (>= next-check max-char-num) (loop (add1 next-check) (cdr nexts)))))))))) - (printf "Warning: lexer at ~a can accept the empty string.\n" stx))) + (eprintf "Warning: lexer at ~a can accept the empty string.\n" stx))) (with-syntax ((start-state-stx start) (trans-table-stx trans) (no-lookahead-stx no-look) From d01e6a8dcce2a586953aa405bfeb1cec23c2c8bb Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 1 Feb 2011 20:49:58 -0500 Subject: [PATCH 089/746] Comment out what looks like debugging output --- collects/datalog/lang/configure-runtime.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/datalog/lang/configure-runtime.rkt b/collects/datalog/lang/configure-runtime.rkt index 5985d59d78..25e9ad3f93 100644 --- a/collects/datalog/lang/configure-runtime.rkt +++ b/collects/datalog/lang/configure-runtime.rkt @@ -1,7 +1,7 @@ #lang racket/base (define (configure data) - (printf "Configuring\n") + ;; (printf "Configuring\n") (current-read-interaction even-read)) (provide configure) @@ -17,4 +17,4 @@ (current-read-interaction odd-read))) (define (odd-read src ip) (current-read-interaction even-read) - eof) \ No newline at end of file + eof) From 0b4f5a093db77044b99797a50c3be44b2cc2d9e2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Feb 2011 19:36:22 -0700 Subject: [PATCH 090/746] add missing mutex unlock in error path Merge to 5.1 (cherry picked from commit 9134aa4ee80c0320a3f441b9cbf77cf268acfbb0) --- src/racket/src/future.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/racket/src/future.c b/src/racket/src/future.c index 3f4dce37c1..deeb313052 100644 --- a/src/racket/src/future.c +++ b/src/racket/src/future.c @@ -1660,6 +1660,7 @@ static void invoke_rtcall(Scheme_Future_State * volatile fs, future_t * volatile future->status = FINISHED; future->work_completed = 1; future->retval = 0; + mzrt_mutex_unlock(fs->future_mutex); } else { /* Signal the waiting worker thread that it can continue running machine code */ From 2e67a39ae87cbbaf58970e1aa544b6ff877d859b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Feb 2011 06:04:23 -0700 Subject: [PATCH 091/746] gtk: force display of images in button labels Merge to 5.1 (cherry picked from commit 7291d944c34b50f958896b4013121777adc4f8e3) --- collects/mred/private/wx/gtk/button.rkt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/collects/mred/private/wx/gtk/button.rkt b/collects/mred/private/wx/gtk/button.rkt index 561a304d19..719ffab2ba 100644 --- a/collects/mred/private/wx/gtk/button.rkt +++ b/collects/mred/private/wx/gtk/button.rkt @@ -33,6 +33,16 @@ (define-gtk gtk_container_remove (_fun _GtkWidget _GtkWidget -> _void)) (define-gtk gtk_bin_get_child (_fun _GtkWidget -> _GtkWidget)) +(define _GtkSettings (_cpointer 'GtkSettings)) +(define-gtk gtk_settings_get_default (_fun -> _GtkSettings)) +(define-gobj g_object_set/boolean + (_fun _GtkSettings _string _gboolean (_pointer = #f) -> _void) + #:c-id g_object_set) +(define (force-button-images-on gtk) + ;; Globally turning on button images isn't really the right thing. + ;; Is there a way to enable image just for the widget `gtk'? + (g_object_set/boolean (gtk_settings_get_default) "gtk-button-images" #t)) + (define-signal-handler connect-clicked "clicked" (_fun _GtkWidget -> _void) (lambda (gtk) @@ -65,7 +75,8 @@ (release-pixbuf pixbuf) (if (pair? label) (begin - (gtk_button_set_image gtk image-gtk) + (force-button-images-on gtk) + (gtk_button_set_image gtk image-gtk) (gtk_button_set_image_position gtk (case (caddr label) From 3b47d8eb35ab16872ea4f91cf2bdcaa0fabc3d8f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Feb 2011 06:32:51 -0700 Subject: [PATCH 092/746] gtk: fix drag-and-drop URI decoding Closes PR 11695 Merge to 5.1 (cherry picked from commit 2d01241f7ad3c3905a9629c6aa33ad7cd4c7e653) --- collects/mred/private/wx/gtk/window.rkt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/collects/mred/private/wx/gtk/window.rkt b/collects/mred/private/wx/gtk/window.rkt index fc6b99f0b4..5e5467712c 100644 --- a/collects/mred/private/wx/gtk/window.rkt +++ b/collects/mred/private/wx/gtk/window.rkt @@ -1,6 +1,7 @@ #lang racket/base (require ffi/unsafe racket/class + net/uri-codec ffi/unsafe/atomic "../../syntax.rkt" "../../lock.rkt" @@ -121,7 +122,10 @@ => (lambda (m) (queue-window-event wx (lambda () - (let ([path (bytes->path (cadr m))]) + (let ([path + (string->path + (uri-decode + (bytes->string/utf-8 (cadr m))))]) (send wx on-drop-file path)))))])))))) ;; ---------------------------------------- From 9e101a29414c5710d15e3942659994fb2a361812 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Feb 2011 06:46:03 -0700 Subject: [PATCH 093/746] gtk: map left-tab key to #\tab Closes PR 11697 Merge to 5.1 (cherry picked from commit 0eed4e9462a227326b2edd0e1c4b2d6e739043b4) --- collects/mred/private/wx/gtk/keycode.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/mred/private/wx/gtk/keycode.rkt b/collects/mred/private/wx/gtk/keycode.rkt index 2f70483248..02c5b9a48b 100644 --- a/collects/mred/private/wx/gtk/keycode.rkt +++ b/collects/mred/private/wx/gtk/keycode.rkt @@ -8,6 +8,7 @@ #hash((#xff08 . #\backspace) (#xffff . #\rubout) (#xff09 . #\tab) + (#xfe20 . #\tab) ; left tab (sometimes from ctl-shift-tab) (#xff0a . #\newline) (#xff0d . #\return) (#xff1b . escape) ; escape From 709947bbb186aa566853e50047708b9aa4fd4b9d Mon Sep 17 00:00:00 2001 From: Casey Klein Date: Wed, 2 Feb 2011 10:36:10 -0600 Subject: [PATCH 094/746] Updates the Redex history for v5.1 Please merge to release branch. (cherry picked from commit 309bb47c7e6dc0f4cdd0bcd6c3dfd426abb3f377) --- doc/release-notes/redex/HISTORY.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/release-notes/redex/HISTORY.txt b/doc/release-notes/redex/HISTORY.txt index 4b4d6a0577..5e477c17d9 100644 --- a/doc/release-notes/redex/HISTORY.txt +++ b/doc/release-notes/redex/HISTORY.txt @@ -1,3 +1,17 @@ +v5.1 + + * adds an optional #:pred keyword argument to `test-->>' form + + * added the `redex-pseudo-random-generator' parameter + + * added option `::=' syntax to non-terminal definitions + + * added contract support to `define-relation' + + * added the `test-->∃' form + + * fixed minor bugs + v5.0.2 * added `pretty-print-parameters' to control term pretty-printing From 63af7b4af06a1faeee8a8900dfb007f1c9468e9f Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 2 Feb 2011 13:54:37 -0500 Subject: [PATCH 095/746] Fix make-->vector doc typo. Closes PR 11698. Merge to 5.1. (cherry picked from commit 62327c5f50ff8b11a39d9d213811a17e853fe10f) --- collects/mzlib/scribblings/struct.scrbl | 2 +- collects/scribblings/guide/contracts-exists.scrbl | 2 +- collects/scribblings/guide/contracts-structure.scrbl | 2 +- src/plot/plplot/plot3d.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/collects/mzlib/scribblings/struct.scrbl b/collects/mzlib/scribblings/struct.scrbl index 90f57cf50e..d95166c621 100644 --- a/collects/mzlib/scribblings/struct.scrbl +++ b/collects/mzlib/scribblings/struct.scrbl @@ -60,7 +60,7 @@ property. ]} -@defform[(make->vector struct-id)]{ +@defform[(make-->vector struct-id)]{ Builds a function that accepts a structure type instance (matching @scheme[struct-id]) and provides a vector of the fields of the diff --git a/collects/scribblings/guide/contracts-exists.scrbl b/collects/scribblings/guide/contracts-exists.scrbl index 13081b9d53..3e8d25763a 100644 --- a/collects/scribblings/guide/contracts-exists.scrbl +++ b/collects/scribblings/guide/contracts-exists.scrbl @@ -44,7 +44,7 @@ data structure (perhaps accidentally) and thus any change in the representation (say to a more efficient representation that supports amortized constant time enqueue and dequeue operations) might break client code. -To ensure that the stack representation is abstact, we can use @racket[#:∃] in the +To ensure that the stack representation is abstract, we can use @racket[#:∃] in the @racket[provide/contract] expression, like this: @racketblock[(provide/contract #:∃ stack diff --git a/collects/scribblings/guide/contracts-structure.scrbl b/collects/scribblings/guide/contracts-structure.scrbl index 87ecd8d374..c81c6dc996 100644 --- a/collects/scribblings/guide/contracts-structure.scrbl +++ b/collects/scribblings/guide/contracts-structure.scrbl @@ -224,7 +224,7 @@ racket (code:comment "bst-between : number number -> contract") (code:comment "builds a contract for binary search trees") -(code:comment "whose values are betweeen low and high") +(code:comment "whose values are between low and high") (define (bst-between/c low high) (or/c null? (node/dc [val (between/c low high)] diff --git a/src/plot/plplot/plot3d.c b/src/plot/plplot/plot3d.c index b07d52d470..1aa91fed65 100644 --- a/src/plot/plplot/plot3d.c +++ b/src/plot/plplot/plot3d.c @@ -519,7 +519,7 @@ plsurf3d(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny, if (ct == 2) { /* yes, xx and yy are the intersection points of the triangle with - * the contour line -- draw a straight line betweeen the points + * the contour line -- draw a straight line between the points * -- at the end this will make up the contour line */ if (opt & SURF_CONT) { From e0029e50a83d4c04841875b3f034edafbbd79f0a Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 2 Feb 2011 14:18:29 -0500 Subject: [PATCH 096/746] Fix more doc typoes. Closes PR 11694. Merge to 5.1. (cherry picked from commit 2935170eff16b7d86a2f24234189cc083e9f360f) --- collects/scribblings/guide/contracts-examples.scrbl | 4 ++-- collects/scribblings/guide/contracts-examples/2.rkt | 2 +- collects/scribblings/guide/contracts-examples/5.rkt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/collects/scribblings/guide/contracts-examples.scrbl b/collects/scribblings/guide/contracts-examples.scrbl index 48a0b51613..c89b9b99e1 100644 --- a/collects/scribblings/guide/contracts-examples.scrbl +++ b/collects/scribblings/guide/contracts-examples.scrbl @@ -16,7 +16,7 @@ Mitchell and McKim's principles for design by contract DbC are derived from the 1970s style algebraic specifications. The overall goal of DbC is to specify the constructors of an algebra in terms of its observers. While we reformulate Mitchell and McKim's terminology and - we use a mostly applicative, we + we use a mostly applicative approach, we retain their terminology of ``classes'' and ``objects'': @itemize[ @@ -28,7 +28,7 @@ Mitchell and McKim's principles for design by contract DbC are derived implementation a command typically returns an new object of the same class.} -@item{@bold{Separate basic queries from derived queries} +@item{@bold{Separate basic queries from derived queries.} A @italic{derived query} returns a result that is computable in terms of basic queries.} diff --git a/collects/scribblings/guide/contracts-examples/2.rkt b/collects/scribblings/guide/contracts-examples/2.rkt index 9a53886be4..022eab13ab 100644 --- a/collects/scribblings/guide/contracts-examples/2.rkt +++ b/collects/scribblings/guide/contracts-examples/2.rkt @@ -50,7 +50,7 @@ [initialize (->d ([p contract?] [s (p p . -> . boolean?)]) () - ;; Mitchel and McKim use (= (count s) 0) here to express + ;; Mitchell and McKim use (= (count s) 0) here to express ;; the post-condition in terms of a primitive query [result (and/c stack? is-empty?)])] diff --git a/collects/scribblings/guide/contracts-examples/5.rkt b/collects/scribblings/guide/contracts-examples/5.rkt index ceeb0f96ec..e9ddf09926 100644 --- a/collects/scribblings/guide/contracts-examples/5.rkt +++ b/collects/scribblings/guide/contracts-examples/5.rkt @@ -1,7 +1,7 @@ #lang racket ;; Note: this queue doesn't implement the capacity restriction -;; of McKim and Mitchell's queue but this is easy to add. +;; of Mitchell and McKim's queue but this is easy to add. ;; a contract utility (define (all-but-last l) (reverse (cdr (reverse l)))) @@ -32,7 +32,7 @@ ;; primitive queries ;; Imagine providing this 'query' for the interface of the module - ;; only. Then in Scheme, there is no reason to have count or is-empty? + ;; only. Then in Racket there is no reason to have count or is-empty? ;; around (other than providing it to clients). After all items is ;; exactly as cheap as count. [items (->d ([q queue?]) () [result (listof (queue-p? q))])] From 728cf780b1a3fa457b34c40e90ea698ec6b0595e Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 2 Feb 2011 16:09:06 -0500 Subject: [PATCH 097/746] Avoid compiling plot if the source directory is missing (cherry picked from commit e91f243b641016468b2f8a98376193f26aae2302) --- src/racket/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racket/configure.ac b/src/racket/configure.ac index 8b5b0978cc..2488891852 100644 --- a/src/racket/configure.ac +++ b/src/racket/configure.ac @@ -1259,7 +1259,7 @@ fi makefiles="$makefiles foreign/Makefile" ac_configure_args="$ac_configure_args$SUB_CONFIGURE_EXTRAS" -if test "${enable_plot}" = "yes" ; then +if test -d "${srcdir}/plot" && test "${enable_plot}" = "yes" ; then makefiles="$makefiles plot/Makefile" MAKE_PLOT=plot From 0c03da259615a9dbb022a0eaf7658f69683a4cee Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Feb 2011 20:39:43 -0700 Subject: [PATCH 098/746] fix problem with allocation while holding a future lock Merge to 5.1 (cherry picked from commit 9d204c01cf910c1290838fe9712e083acc4eb474) --- src/racket/src/future.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/racket/src/future.c b/src/racket/src/future.c index deeb313052..9c60c64a03 100644 --- a/src/racket/src/future.c +++ b/src/racket/src/future.c @@ -227,7 +227,7 @@ typedef struct Scheme_Future_State { future_t *future_waiting_lwc; int next_futureid; - mzrt_mutex *future_mutex; + mzrt_mutex *future_mutex; /* BEWARE: don't allocate while holding this lock */ mzrt_sema *future_pending_sema; mzrt_sema *gc_ok_c; mzrt_sema *gc_done_c; @@ -825,19 +825,28 @@ Scheme_Object *touch(int argc, Scheme_Object *argv[]) mzrt_mutex_lock(fs->future_mutex); if (ft->work_completed) { + int id; + double time_of_start; + double time_of_completion; + retval = ft->retval; + id = ft->id; + time_of_start = ft->time_of_start; + time_of_completion = ft->time_of_completion; + + mzrt_mutex_unlock(fs->future_mutex); + /* Log execution time */ if (scheme_log_level_p(scheme_main_logger, SCHEME_LOG_DEBUG)) { scheme_log(scheme_main_logger, SCHEME_LOG_DEBUG, 0, - "future: %d finished. start time: %f, finish time: %f (%f ms)", - ft->id, - ft->time_of_start, - ft->time_of_completion, - ft->time_of_completion - ft->time_of_start); + "future: %d finished. start time: %f, finish time: %f (%f ms)", + id, + time_of_start, + time_of_completion, + time_of_completion - time_of_start); } - mzrt_mutex_unlock(fs->future_mutex); break; } else if (ft->rt_prim) From 6934115feccf65893cbda1818f1adc36cf42590f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Feb 2011 16:09:21 -0700 Subject: [PATCH 099/746] fix typo (cherry picked from commit d704f9565b8db7cf456dac84c025b188425c06c9) --- collects/scribblings/scribble/manual.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/scribble/manual.scrbl b/collects/scribblings/scribble/manual.scrbl index cdf1288bb7..c3baaea8bc 100644 --- a/collects/scribblings/scribble/manual.scrbl +++ b/collects/scribblings/scribble/manual.scrbl @@ -208,7 +208,7 @@ without insetting the code.} @defform[(RACKETRESULTBLOCK0 datum ...)] )]{ -Like @racketblock[racketblock], etc., but colors the typeset text as a +Like @racket[racketblock], etc., but colors the typeset text as a result (i.e., a single color with no hyperlinks) instead of code.} @deftogether[( From 68e13d858706e391edc274c10dd38d8fea51348c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Feb 2011 16:10:40 -0700 Subject: [PATCH 100/746] re-generate `configure' script Merge to 5.1, along with e91f243b64101 (cherry picked from commit 309e1aec4f800c5a5f947fc5ce07bf80bed07e5e) --- src/configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configure b/src/configure index 02106880ef..29d69a8246 100755 --- a/src/configure +++ b/src/configure @@ -9910,7 +9910,7 @@ fi makefiles="$makefiles foreign/Makefile" ac_configure_args="$ac_configure_args$SUB_CONFIGURE_EXTRAS" -if test "${enable_plot}" = "yes" ; then +if test -d "${srcdir}/plot" && test "${enable_plot}" = "yes" ; then makefiles="$makefiles plot/Makefile" MAKE_PLOT=plot From 9b9dc8c2f868e2cf9ac6042c22bdd1aae8a08951 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 2 Feb 2011 16:05:59 -0600 Subject: [PATCH 101/746] missed a multiple-vlaues change in a short-cut case. Please merge to the 5.1 release branch (cherry picked from commit 63aa388d495fc753c9772cc645e32672a841cc89) --- collects/framework/private/color.rkt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/collects/framework/private/color.rkt b/collects/framework/private/color.rkt index a1203f8fd1..365c48f0ea 100644 --- a/collects/framework/private/color.rkt +++ b/collects/framework/private/color.rkt @@ -825,20 +825,23 @@ added get-regions (define/public (get-token-range position) (define-values (tokens ls) (get-tokens-at-position 'get-token-range position)) - (values (and tokens (+ (lexer-state-start-pos ls) - (send tokens get-root-start-position))) - (and tokens (+ (lexer-state-start-pos ls) - (send tokens get-root-end-position))))) + (values (and tokens ls + (+ (lexer-state-start-pos ls) + (send tokens get-root-start-position))) + (and tokens ls + (+ (lexer-state-start-pos ls) + (send tokens get-root-end-position))))) (define/private (get-tokens-at-position who position) (when stopped? (error who "called on a color:text<%> whose colorer is stopped.")) (let ([ls (find-ls position)]) - (and ls - (let ([tokens (lexer-state-tokens ls)]) + (if ls + (let ([tokens (lexer-state-tokens ls)]) (tokenize-to-pos ls position) (send tokens search! (- position (lexer-state-start-pos ls))) - (values tokens ls))))) + (values tokens ls)) + (values #f #f)))) (define/private (tokenize-to-pos ls position) (when (and (not (lexer-state-up-to-date? ls)) From 9215e3c4018d6ea75b564ebb749b8120fc9d8bcc Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Feb 2011 19:00:27 -0700 Subject: [PATCH 102/746] fix `image-snip%' unmarshaling with filename Merge to 5.1 (cherry picked from commit c2c6c79a15b12d2ca689a75ed519f1fb364e1fd8) --- collects/racket/snip/private/snip.rkt | 3 +-- collects/tests/gracket/wxme.rkt | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/collects/racket/snip/private/snip.rkt b/collects/racket/snip/private/snip.rkt index 5ccae9bab5..fecdc0bd7c 100644 --- a/collects/racket/snip/private/snip.rkt +++ b/collects/racket/snip/private/snip.rkt @@ -787,8 +787,7 @@ (def/override (read [editor-stream-in% f]) (let ([scl (get-the-snip-class-list)] [can-inline? ((send f do-reading-version this) . > . 1)]) - (let ([filename (let ([s (send f get-bytes #f)]) - (subbytes s 0 (max 0 (sub1 (bytes-length s)))))]) + (let ([filename (send f get-bytes #f)]) (let-boxes ([type 0] [w 0.0] [h 0.0] diff --git a/collects/tests/gracket/wxme.rkt b/collects/tests/gracket/wxme.rkt index 4208af35ff..c436b39fb9 100644 --- a/collects/tests/gracket/wxme.rkt +++ b/collects/tests/gracket/wxme.rkt @@ -1347,4 +1347,23 @@ ;; ---------------------------------------- +(let () + (define (mk) (make-object image-snip% (collection-file-path "b-run.png" "icons") 'unknown #f #f)) + + (define is (mk)) + (define copy-is + (let () + (define sp (open-output-string)) + (define t (new text%)) + (send t insert (mk)) + (send t save-port sp) + (define t2 (new text%)) + (send t2 insert-port (open-input-string (get-output-string sp))) + (send t2 find-first-snip))) + + (expect (send (mk) get-filename) + (send copy-is get-filename))) + +;; ---------------------------------------- + (done) From 4e9b5bcaef12c0b6f5544a4cc2c9247ee0f0ea8f Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 2 Feb 2011 20:10:44 -0600 Subject: [PATCH 103/746] adjust the wxme reader so that it now creates image-snip%s when it finds image-snips in file it used to create image% objects that were simple containers for the data in the file; the change _should_ be backwards compatibile; the only know incompatibility is that the get-filename method now returns a path instead of bytes (this is to match the image-snip% class) closes PR 1168 please merge to the 5.1 release branch (cherry picked from commit 0fce29f552eeef416bfb66459123614518f02513) --- collects/racket/snip/private/snip.rkt | 6 +- collects/scribblings/gui/wxme.scrbl | 20 +-- .../gracket/image-snip-unmarshalling.rkt | 142 ++++++++++++++++++ collects/wxme/image.rkt | 59 +++++++- collects/wxme/wxme.rkt | 8 +- 5 files changed, 219 insertions(+), 16 deletions(-) create mode 100644 collects/tests/gracket/image-snip-unmarshalling.rkt diff --git a/collects/racket/snip/private/snip.rkt b/collects/racket/snip/private/snip.rkt index fecdc0bd7c..1bcd4f27dc 100644 --- a/collects/racket/snip/private/snip.rkt +++ b/collects/racket/snip/private/snip.rkt @@ -49,7 +49,8 @@ readable-snip<%> - image-type?) + image-type? + int->img-type) ;; these are used only in contracts ;; we don't want the real definitions b/c they require the gui @@ -826,6 +827,9 @@ (values filename (int->img-type type) #f))]) + ;; the call to create an image-snip% object + ;; here should match the way that super-make-object + ;; is called in wxme/image.rkt (let ([snip (make-object image-snip% (if (equal? loadfile #"") #f diff --git a/collects/scribblings/gui/wxme.scrbl b/collects/scribblings/gui/wxme.scrbl index e49260956a..875dd4bdd9 100644 --- a/collects/scribblings/gui/wxme.scrbl +++ b/collects/scribblings/gui/wxme.scrbl @@ -3,6 +3,7 @@ (for-label wxme wxme/editor wxme/image + racket/snip (except-in wxme/comment reader) (except-in wxme/xml reader) (except-in wxme/scheme reader) @@ -302,7 +303,7 @@ Several compatibility mappings are installed automatically for the @racketmodname[wxme] library. They correspond to popular graphical elements supported by various versions of DrRacket, including comment boxes, fractions, XML boxes, Racket boxes, text boxes, and images -generated by the ``world'' and ``image'' teachpacks (or, more +generated by the @racketmodname[htdp/image] teachpack (or, more generally, from @racketmodname[mrlib/cache-image-snip]), and test-case boxes. @@ -323,7 +324,8 @@ special-comment content is the readable instance. XML, Racket, and text boxes similarly produce instances of @racket[editor%] and @racket[readable<%>] that expand in the usual way; see @racketmodname[wxme/xml], @racketmodname[wxme/scheme], and -@racket[wxme/text]. Images from the ``world'' and ``image'' teachpacks +@racket[wxme/text]. Images from the +@racketmodname[htdp/image] teachpack are packaged as instances of @racket[cache-image%] from the @racketmodname[wxme/cache-image] library. Test-case boxes are packaged as instances of @racket[test-case%] from the @@ -353,14 +355,14 @@ editor's content.} @defmodule[wxme/image] -@defclass[image% object% ()]{ +@defclass[image% image-snip% ()]{ Instantiated for images in a @tech{WXME} stream in text mode. - -@defmethod[(get-filename) (or/c bytes? false/c)]{ - -Returns a filename as bytes, or @racket[#f] if data is available -instead.} +This class can just be treated like @racket[image-snip%] and should +behave just like it, except it has the methods below in addition +in case old code still needs them. In other words, the methods +below are provided for backwards compatibility with earlier +verisons of Racket. @defmethod[(get-data) (or/c bytes? false/c)]{ @@ -543,7 +545,7 @@ rational numbers.}] @defthing[reader (is-a?/c snip-reader<%>)]{ A text-mode reader for images in a WXME stream generated by the -``image'' and ``world'' teachpacks---or, more generally, by +@racketmodname[htdp/image] teachpack---or, more generally, by @racketmodname[mrlib/cache-image-snip].}] diff --git a/collects/tests/gracket/image-snip-unmarshalling.rkt b/collects/tests/gracket/image-snip-unmarshalling.rkt new file mode 100644 index 0000000000..cb8a4937ea --- /dev/null +++ b/collects/tests/gracket/image-snip-unmarshalling.rkt @@ -0,0 +1,142 @@ +#lang racket/gui +(require wxme + wxme/image) + +#| + +This file tests the wxme image-snip reader against the normal +image-snip reader (ie image-snip-class%'s read method) + +It creates a bunch of different image-snip% objects +(the try-perms and below functions) +and then feeds them thru both paths to get two new image snips +(in the beginning of test-wxme-image-snip-reader/proc) +and compares a bunch of properties of them +(the end of that function). + +|# + +(define-syntax (test-wxme-image-snip-reader stx) + (syntax-case stx () + [(_ is) + (with-syntax ([line (syntax-line stx)]) + #'(test-wxme-image-snip-reader/proc line is))])) + +(define tests 0) +(define (test-wxme-image-snip-reader/proc line is) + (set! tests (+ tests 1)) + (define t (new text%)) + (send t insert is) + (define sp (open-output-string)) + (void (send t save-port sp)) + (define wp (wxme-port->port (open-input-string (get-output-string sp)))) + (define wxme-is (read-char-or-special wp)) + + (define t2 (new text%)) + (send t2 insert-port (open-input-string (get-output-string sp))) + (define copy-is (send t2 find-first-snip)) + + (define (warn . args) + (fprintf (current-error-port) + (string-append (format "FAILED test-wxme-image-snip-reader.rkt line ~a: " line) + (apply format args)))) + + (define-syntax-rule (cmp mtd) (cmp/proc (λ (x) (send x mtd)) 'mtd)) + (define (cmp/proc call-mtd mtd) + (let ([is-ans (call-mtd is)] + [wxme-is-ans (call-mtd wxme-is)] + [copy-is-ans (call-mtd copy-is)]) + (unless (same? copy-is-ans wxme-is-ans) + (warn "~a returned different results; copy-is: ~s wxme-is: ~s\n" + mtd + copy-is-ans + wxme-is-ans)) + #; + (unless (same? is-ans copy-is-ans) + (warn "~a returned different results; is: ~s copy-is: ~s\n" + mtd + is-ans + copy-is-ans)))) + + (when (is-a? is image%) + (warn "the input image-snip% is an image%\n")) + + (unless (is-a? wxme-is image%) + (warn "new image snip is not an image%\n")) + + (cmp get-filename) + (cmp get-filetype) + (cmp get-bitmap) + (cmp get-bitmap-mask)) + +(define (same? x y) + (cond + [(and (is-a? x bitmap%) + (is-a? y bitmap%)) + (and (= (send x get-width) + (send y get-width)) + (= (send x get-height) + (send y get-height)) + (= (send x get-depth) + (send y get-depth)) + (check? (bitmap->bytes x #f) + (bitmap->bytes y #f) + 'bitmap/#f) + (check? (bitmap->bytes x #t) + (bitmap->bytes y #t) + 'bitmap/#t))] + [else (equal? x y)])) + + +(define (check? a b what) + (cond + [(equal? a b) #t] + [else + ;(fprintf (current-error-port) "checking ~s, doesn't match\n~s\nvs\n~s\n\n" what a b) + #f])) + +(define (bitmap->bytes bmp alpha?) + (define w (send bmp get-width)) + (define h (send bmp get-height)) + (define bytes (make-bytes (* 4 w h) 0)) + (send bmp get-argb-pixels 0 0 w h bytes alpha?) + bytes) + +(define (try-perms files kinds relative-path?s inline?s) + (for* ([file (in-list files)] + [kind (in-list kinds)] + [relative-path? (in-list relative-path?s)] + [inline? (in-list inline?s)]) + (test-wxme-image-snip-reader (make-object image-snip% file kind relative-path? inline?)))) + +(try-perms (list (collection-file-path "b-run.png" "icons")) + '(unknown unknown/mask unknown/alpha + png png/mask png/alpha) + '(#f) + '(#f #t)) + +(parameterize ([current-directory (collection-path "icons")]) + (try-perms (list "b-run.png") + '(unknown unknown/mask unknown/alpha + png png/mask png/alpha) + '(#f) + '(#f #t))) + +(define (draw-circle bm) + (define bdc (make-object bitmap-dc% bm)) + (send bdc set-smoothing 'smoothed) + (send bdc set-brush "red" 'solid) + (send bdc draw-ellipse 1 1 8 8) + (send bdc set-bitmap #f)) + +(let ([bm (make-bitmap 10 10 #f)]) + (draw-circle bm) + (test-wxme-image-snip-reader (make-object image-snip% bm)) + (test-wxme-image-snip-reader (make-object image-snip% bm #f)) + (test-wxme-image-snip-reader (make-object image-snip% bm bm))) + +(let ([bm (make-bitmap 10 10)]) + (draw-circle bm) + (test-wxme-image-snip-reader (make-object image-snip% bm))) + +(printf "ran ~a tests\n" tests) diff --git a/collects/wxme/image.rkt b/collects/wxme/image.rkt index 27915207b2..24e3dba79b 100644 --- a/collects/wxme/image.rkt +++ b/collects/wxme/image.rkt @@ -1,11 +1,62 @@ +#lang racket/base +(require racket/class + racket/snip + "private/class-help.ss") -(module image mzscheme - (require mzlib/class - "private/class-help.ss") +(provide image%) - (provide image%) +#| + +This code is a bit strange in order to attempt to +preserve backwards compatibility with pre-5.1 versions. + +The old version is: (define image% (class object% (init-accessible filename data w h dx dy) (super-new)))) + +The things I attempted to preserve: + + - image% as a class whose objects can be tested with is-a? + + - the get-* methods that init-accessible provides; with the exception + of get-filename, which is now the image-snip% method, these are done + still with init-accessible + + The get-filename method changed, tho: it now returns a path (it returned + bytes before) + + - the constructor arity (there are now additional optional arguments that + wxme supplies to be able to call super-make-object) + +The main change is to make this file depend on racket/snip so that +image% can be a subclass of image-snip% and thus work with things like +the 2htdp/universe libraries (in executables) + + +|# + +(define image% + (class image-snip% + (init filename) + (init-accessible data w h dx dy) + (init [relative 1] [type 'unknown]) + ;; the call to super-make-object is intended to mimic the way that racket/snip/private/snip.rkt + ;; creates an image-snip% object in the image-snip-class% class's read method + (let ([data (get-data)]) + (super-make-object + (if data + (let-values ([(in out) (make-pipe)]) + (thread (λ () (display data out) (close-output-port out))) + in) + (if (bytes? filename) + (bytes->path filename) + #f)) + (if data 'unknown/alpha type) + (positive? relative) + (and data #t))) + (inherit resize set-offset) + (resize (get-w) (get-h)) + (set-offset (get-dx) (get-dy)))) diff --git a/collects/wxme/wxme.rkt b/collects/wxme/wxme.rkt index 819e60b1b1..97f110c0dd 100644 --- a/collects/wxme/wxme.rkt +++ b/collects/wxme/wxme.rkt @@ -8,6 +8,7 @@ mzlib/list scheme/gui/dynamic syntax/modread + (only racket/snip/private/snip int->img-type) "image.ss" "editor.ss" "private/compat.ss") @@ -449,7 +450,7 @@ [h (read-inexact who port vers "image-snip height")] [dx (read-inexact who port vers "image-snip x-offset")] [dy (read-inexact who port vers "image-snip y-offset")] - [rel? (read-integer who port vers "image-snip relative?")]) + [relative (read-integer who port vers "image-snip relative?")]) (let ([data (and (and (equal? filename #"") (cvers . > . 1) @@ -466,7 +467,10 @@ (loop (add1 i))))))))]) (if (header-plain-text? header) #"." - (make-object image% (if data #f filename) data w h dx dy)))))] + (make-object image% + (if data #f filename) + data w h dx dy + relative (int->img-type type))))))] [else (if (header-skip-content? header) #f From cc249dcdc22d1a75c56316bc90b709268acd11be Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 3 Feb 2011 06:16:26 -0700 Subject: [PATCH 104/746] fix jpeg writing Closes PR 11701 Merge to 5.1 (cherry picked from commit 16eb172e5af019ce8f0aa6563c65f8c06ad7bee8) --- collects/racket/draw/unsafe/jpeg.rkt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/collects/racket/draw/unsafe/jpeg.rkt b/collects/racket/draw/unsafe/jpeg.rkt index 08e7753d1c..9399aec0fc 100644 --- a/collects/racket/draw/unsafe/jpeg.rkt +++ b/collects/racket/draw/unsafe/jpeg.rkt @@ -562,11 +562,13 @@ (define (init-destination m) (void)) -(define (empty-output-buffer m) +(define (do-empty-output-buffer m all?) (let* ([d (jpeg_compress_struct-dest m)] [b (jpeg_destination_mgr-buffer d)] [bstr (scheme_make_sized_byte_string b - (- BUFFER-SIZE (jpeg_destination_mgr-free_in_buffer d)) + (if all? + BUFFER-SIZE + (- BUFFER-SIZE (jpeg_destination_mgr-free_in_buffer d))) 0)] [out (ptr-ref (jpeg_compress_struct-client_data m) _scheme)]) (write-bytes bstr out) @@ -574,8 +576,11 @@ (set-jpeg_destination_mgr-free_in_buffer! d BUFFER-SIZE) #t)) +(define (empty-output-buffer m) + (do-empty-output-buffer m #t)) + (define (term-destination m) - (empty-output-buffer m) + (do-empty-output-buffer m #f) ;; Maybe add support to optionally close port as early as possible? (when #f (let ([in (ptr-ref (jpeg_decompress_struct-client_data m) _scheme)]) From bef9f8f0cb78253d10d32858a01c4c5be3db5c8e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 3 Feb 2011 06:30:10 -0700 Subject: [PATCH 105/746] fix guide typos Closes PR 11700 Merge to 5.1 (cherry picked from commit 08cc4dffb2ebdf5d60abce6a121adf32817b4fdb) --- collects/scribblings/guide/match.scrbl | 6 +++--- collects/scribblings/guide/performance.scrbl | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/collects/scribblings/guide/match.scrbl b/collects/scribblings/guide/match.scrbl index 426294d992..2918045db4 100644 --- a/collects/scribblings/guide/match.scrbl +++ b/collects/scribblings/guide/match.scrbl @@ -84,9 +84,9 @@ variables} that are bound in the result expressions: (match '(1 2) [(list x) (+ x 1)] [(list x y) (+ x y)]) -(match (make-hat 23 'bowler) - [(struct shoe (sz col)) sz] - [(struct hat (sz stl)) sz]) +(match (hat 23 'bowler) + [(shoe sz col) sz] + [(hat sz stl) sz]) ] An ellipsis, written @litchar{...}, act like a Kleene star within a diff --git a/collects/scribblings/guide/performance.scrbl b/collects/scribblings/guide/performance.scrbl index 396a46b3c5..e1db549753 100644 --- a/collects/scribblings/guide/performance.scrbl +++ b/collects/scribblings/guide/performance.scrbl @@ -64,10 +64,10 @@ The module system aids optimization by helping to ensure that identifiers have the usual bindings. That is, the @racket[+] provided by @racketmodname[racket/base] can be recognized by the compiler and inlined, which is especially important for @tech{JIT}-compiled code. -In contrast, in a traditional interactive Racket system, the top-level +In contrast, in a traditional interactive Scheme system, the top-level @racket[+] binding might be redefined, so the compiler cannot assume a fixed @racket[+] binding (unless special flags or declarations -act as a poor-man's module system to indicate otherwise). +are used to compensate for the lack of a module system). Even in the top-level environment, importing with @racket[require] enables some inlining optimizations. Although a @racket[+] definition From 99866b29fdf6877b31f4434c97287c7e401eed5f Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 3 Feb 2011 10:23:16 -0500 Subject: [PATCH 106/746] Check for libracket instead of any .so file (cherry picked from commit 83d2e5c151609f8c578007b5b2f74fbee8c4e71d) --- collects/setup/unixstyle-install.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/setup/unixstyle-install.rkt b/collects/setup/unixstyle-install.rkt index ef16708e3d..c731c6d958 100644 --- a/collects/setup/unixstyle-install.rkt +++ b/collects/setup/unixstyle-install.rkt @@ -383,7 +383,7 @@ (define (move/copy-distribution move?) (define do-tree (move/copy-tree move?)) (current-directory rktdir) - (when (ormap (lambda (p) (regexp-match #rx"[.]so" p)) (ls "lib")) + (when (ormap (lambda (p) (regexp-match #rx"libracket.*[.]so" p)) (ls "lib")) (error "Cannot handle distribution of shared-libraries (yet)")) (with-handlers ([exn? (lambda (e) (undo-changes) (raise e))]) (define binfiles (ls "bin")) ; see below From d1f4b2fdfc1457e90ae3b64ed7f10417d9887cce Mon Sep 17 00:00:00 2001 From: John Clements Date: Thu, 3 Feb 2011 10:24:42 -0800 Subject: [PATCH 107/746] stepper HISTORY.txt updated (cherry picked from commit b60aca2f8fe1a75d34bba01245d13af54e90ff15) --- doc/release-notes/stepper/HISTORY.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/release-notes/stepper/HISTORY.txt b/doc/release-notes/stepper/HISTORY.txt index e3f0cf543e..c47a687563 100644 --- a/doc/release-notes/stepper/HISTORY.txt +++ b/doc/release-notes/stepper/HISTORY.txt @@ -1,5 +1,12 @@ Stepper ------- +Changes for v5.1: + +Quite a bit of rackety, retabbing, refactoring. There's no longer a closure +table, but instead functions expand into applicable structures. Cleanup of +unnecessary function arguments. Got rid of '2vals' idiom. Improved jump +to ... error messages. + Changes for v5.0.2: Bug fixes, Big Bang working again. Define-struct in local not working. From cebe089e1bbfb7d54f9b146c77c212575ac91101 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 3 Feb 2011 17:59:43 -0600 Subject: [PATCH 108/746] don't show themodule langauge opt-in buttons when we're not in the module language anymore (this extra check is necessary because we might have moved languages between the time the timer is started and when it fires) closes PR 11705 Please merge to the release 5.1 branch (cherry picked from commit c119cef915e7e739540eb07bb31693713f2aea0c) --- collects/drracket/private/module-language-tools.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collects/drracket/private/module-language-tools.rkt b/collects/drracket/private/module-language-tools.rkt index e4360fb184..a230666c34 100644 --- a/collects/drracket/private/module-language-tools.rkt +++ b/collects/drracket/private/module-language-tools.rkt @@ -100,7 +100,9 @@ (unless timer (set! timer (new timer% [notify-callback - (λ () (move-to-new-language))] + (λ () + (when in-module-language? + (move-to-new-language)))] [just-once? #t]))) (send timer stop) (send timer start 200 #t))))) From fb36f2147703d66a3ed78fc80b574b4c8d7203db Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 3 Feb 2011 14:22:12 -0700 Subject: [PATCH 109/746] fixed doc typo Fixes PR 11703 Merge to release branch (cherry picked from commit 4ef3dfe6a8770e385fd9dd70d68d599df43b9cd1) --- collects/syntax/scribblings/parse/patterns.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/syntax/scribblings/parse/patterns.scrbl b/collects/syntax/scribblings/parse/patterns.scrbl index 610f094579..9c15c86423 100644 --- a/collects/syntax/scribblings/parse/patterns.scrbl +++ b/collects/syntax/scribblings/parse/patterns.scrbl @@ -147,7 +147,7 @@ One of @ref[~commit s] or @ref[~commit h]: @defidform[~delimit-cut]{ -One of @ref[~delimit-cut s] or @ref[~describe h]: +One of @ref[~delimit-cut s] or @ref[~delimit-cut h]: @itemize[ @item{@ref[~delimit-cut h] if the subpattern is a @tech{proper @Hpattern}} @item{@ref[~delimit-cut s] otherwise} From 4bb3fd937aa668418184c53617f1953dbaa6a2b7 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 3 Feb 2011 14:32:34 -0700 Subject: [PATCH 110/746] fix macro stepper bug (missing hash) Merge to release branch (cherry picked from commit 1054c504ead66fc348487ec726c92bb83a51bd67) --- collects/macro-debugger/syntax-browser/widget.rkt | 4 ++-- collects/macro-debugger/view/step-display.rkt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/collects/macro-debugger/syntax-browser/widget.rkt b/collects/macro-debugger/syntax-browser/widget.rkt index fd75cdd0ff..b84fddc62f 100644 --- a/collects/macro-debugger/syntax-browser/widget.rkt +++ b/collects/macro-debugger/syntax-browser/widget.rkt @@ -117,8 +117,8 @@ (send -text change-style clickback-style a b))))) (define/public (add-syntax stx - #:binders [binders #f] - #:shift-table [shift-table #f] + #:binders [binders '#hash()] + #:shift-table [shift-table '#hash()] #:definites [definites #f] #:hi-colors [hi-colors null] #:hi-stxss [hi-stxss null] diff --git a/collects/macro-debugger/view/step-display.rkt b/collects/macro-debugger/view/step-display.rkt index 51259a617e..d2f6f7d58d 100644 --- a/collects/macro-debugger/view/step-display.rkt +++ b/collects/macro-debugger/view/step-display.rkt @@ -84,9 +84,9 @@ (show-poststep step shift-table)])) (define/public (add-syntax stx - #:binders [binders #f] + #:binders [binders '#hash()] #:definites [definites #f] - #:shift-table [shift-table #f]) + #:shift-table [shift-table '#hash()]) (send/i sbview sb:syntax-browser<%> add-syntax stx #:binders binders #:definites definites From 6eedd57f8b408d9e98f414b1a1dfd3a1117ceaa2 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 3 Feb 2011 16:42:05 -0700 Subject: [PATCH 111/746] fixed race in rackunit gui Merge to release branch (cherry picked from commit 9d42ef9235e40de846fc480d6fcd13fa0f00a929) --- collects/rackunit/private/gui/view.rkt | 67 ++++++++++++++------------ 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/collects/rackunit/private/gui/view.rkt b/collects/rackunit/private/gui/view.rkt index 79315f597f..4de4a148df 100644 --- a/collects/rackunit/private/gui/view.rkt +++ b/collects/rackunit/private/gui/view.rkt @@ -71,8 +71,16 @@ still be there, just not visible? (view this) (controller controller))) - ;; for update management - (define update-queue (make-hasheq)) + ;; Update management + ;; Do adds in order, then updates in any order (hash). + + ;; add-queue : (listof (-> void)) + (define add-queue null) + + ;; update-queue : (imm-hashof model<%> #t) + (define update-queue '#hasheq()) + + ;; update-lock : semaphore (define update-lock (make-semaphore 1)) (send editor lock #t) @@ -83,12 +91,6 @@ still be there, just not visible? ;; View Links - (define/public (create-view-link model parent) - (parameterize ((current-eventspace eventspace)) - (queue-callback - (lambda () - (send tree-view create-view-link model parent))))) - (define/private (get-view-link model) (send tree-view get-view-link model)) @@ -108,10 +110,18 @@ still be there, just not visible? ;; Update Management + ;; create-view-link : model suite-result<%>/#f -> void + (define/public (create-view-link model parent) + (let ([proc (lambda () (send tree-view create-view-link model parent))]) + (semaphore-wait update-lock) + (set! add-queue (cons proc add-queue)) + (semaphore-post update-lock) + (process-updates))) + ;; queue-for-update : model -> void (define/public (queue-for-update model) (semaphore-wait update-lock) - (hash-set! update-queue model #t) + (set! update-queue (hash-set update-queue model #t)) (semaphore-post update-lock) (process-updates)) @@ -120,38 +130,33 @@ still be there, just not visible? (parameterize ((current-eventspace eventspace)) (queue-callback (lambda () - (let ([models-to-update (grab+clear-update-queue)]) - (for ([model models-to-update]) + (let-values ([(adds updates) (grab+clear-update-queue)]) + (for ([add (in-list adds)]) + (add)) + (for ([model (in-hash-keys updates)]) (do-model-update model))))))) - ;; grab+clear-update-queue : -> void + ;; grab+clear-update-queue : -> (values list hash) ;; ** Must be called from eventspace thread. (define/private (grab+clear-update-queue) (semaphore-wait update-lock) - (if (positive? (hash-count update-queue)) - (let ([old-queue update-queue]) - (set! update-queue (make-hasheq)) - (semaphore-post update-lock) - (reverse - (hash-map old-queue (lambda (k v) k)))) - (begin (semaphore-post update-lock) - null))) + (begin0 + (values (reverse add-queue) + update-queue) + (set! add-queue null) + (set! update-queue '#hasheq()) + (semaphore-post update-lock))) ;; do-model-update : model<%> -> void ;; ** Must be called from eventspace thread. (define/private (do-model-update model) (let ([view-link (get-view-link model)]) - (cond [view-link - (send tree-view update-item view-link) - (when (eq? model (get-selected-model)) - (show-model model))] - [(not view-link) - ;; If the view-link has not been created, - ;; yield until it is. - (unless (yield) - (error 'rackunit-gui - "internal error: no progress waiting for view-link")) - (do-model-update model)]))) + (unless view-link + ;; should not be possible + (error 'rackunit-gui "internal error: no view-link")) + (send tree-view update-item view-link) + (when (eq? model (get-selected-model)) + (show-model model)))) ;; Update display From 968eb414759007c569cd93c802f676c3174173a7 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 3 Feb 2011 16:53:49 -0700 Subject: [PATCH 112/746] auto-open top-level test suites in rackunit gui Merge to release branch (cherry picked from commit e3c02f7072638719d3d7b81cd3dcde4c1171a101) --- collects/rackunit/private/gui/view.rkt | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/collects/rackunit/private/gui/view.rkt b/collects/rackunit/private/gui/view.rkt index 4de4a148df..9a716b04f5 100644 --- a/collects/rackunit/private/gui/view.rkt +++ b/collects/rackunit/private/gui/view.rkt @@ -222,19 +222,22 @@ still be there, just not visible? ;; Construction - ;; create-view-link : result<%> suite-result<%>/#f-> item + ;; create-view-link : result<%> suite-result<%>/#f-> void (define/public (create-view-link model parent) - (let ([parent-link - (if parent - (get-view-link parent) - this)]) - (initialize-view-link (cond [(is-a? model suite<%>) - (send parent-link new-list)] - [(is-a? model case<%>) - (send parent-link new-item)]) - model))) + (let* ([parent-link + (if parent + (get-view-link parent) + this)] + [view-link + (cond [(is-a? model suite<%>) + (send parent-link new-list)] + [(is-a? model case<%>) + (send parent-link new-item)])]) + (initialize-view-link view-link model) + (when (and (is-a? model suite<%>) (not parent)) + (send view-link open)))) - ;; initialize-view-link : result<%> (U compound-item% item%) -> item + ;; initialize-view-link : result<%> (U compound-item% item%) -> void (define/private (initialize-view-link item model) (set-view-link model item) (send item user-data model) From cc4c928274a7d60e5c973b98ac360fa2e31b632e Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 3 Feb 2011 15:55:44 -0500 Subject: [PATCH 113/746] Try to kill the test thread after a minute, and exit after another minute. (cherry picked from commit 2fe690b29ebe2c0df572b25f675051e3f0232d3f) --- collects/tests/run-automated-tests.rkt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/collects/tests/run-automated-tests.rkt b/collects/tests/run-automated-tests.rkt index de5ce084a1..6fb9427d53 100755 --- a/collects/tests/run-automated-tests.rkt +++ b/collects/tests/run-automated-tests.rkt @@ -73,7 +73,13 @@ (lambda () (sleep (* 60 timeout)) (echo "Timeout!") - (break-thread th))))) + (break-thread th) + (sleep 60) + (echo " A minute has passed, killing the test thread!") + (kill-thread th) + (sleep 60) + (echo " Another minute passed, aborting!") + (abort 1 "Goodbye."))))) (parameterize* ([exit-handler (lambda (n) (abort n "exit with error code ~a" n))] [current-namespace (make-base-empty-namespace)]) From bfae2d4573a5685c4b2afedc12343d2cae9464a2 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 3 Feb 2011 21:24:11 -0500 Subject: [PATCH 114/746] Proxy the irc logs from pre.racket-lang.org. That's where the bot needs to run; use a proxy instead of NFS. (cherry picked from commit d2a6da75617b3c97235f489188c50daa3aab23b8) --- collects/meta/web/www/irc.rkt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/collects/meta/web/www/irc.rkt b/collects/meta/web/www/irc.rkt index 5e10970200..42835d509e 100644 --- a/collects/meta/web/www/irc.rkt +++ b/collects/meta/web/www/irc.rkt @@ -11,9 +11,14 @@ @page[#:title "IRC" #:part-of 'community]{ @iframe[src: webchat-link width: "100%" height: "400"]}) -(define irc-logs-symlink - (symlink "/home/scheme/irc-logs/racket/" "irc-logs")) -(define (irc-logs text) @a[href: (list irc-logs-symlink "/")]{@text}) +(define irc-logs + (let () + @plain[#:file "irc-logs/.htaccess" #:referrer values]{ + RewriteEngine on + RewriteRule ^(.*)$ http://pre.racket-lang.org@; + /irc-logs/@||racket/@|"$1"| [P] + } + (lambda (text) @a[href: "irc-logs/"]{@text}))) (define (irc-quick) @parlist[@strong{Discussion Channel} From c10d0a6f88364b98cd136c2c1229d8d0554e4c7a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 3 Feb 2011 13:16:39 -0700 Subject: [PATCH 115/746] fix doc bug Closes PR 11690 Merge to 5.1 (cherry picked from commit ab588eb69ad01acdd24ee82f0d37471767c64c59) --- collects/scribblings/guide/pattern-macros.scrbl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/collects/scribblings/guide/pattern-macros.scrbl b/collects/scribblings/guide/pattern-macros.scrbl index 4a967768fc..877b7fc3df 100644 --- a/collects/scribblings/guide/pattern-macros.scrbl +++ b/collects/scribblings/guide/pattern-macros.scrbl @@ -3,6 +3,8 @@ scribble/eval "guide-utils.ss") +@(define swap-eval (make-base-eval)) + @title[#:tag "pattern-macros"]{Pattern-Based Macros} A @deftech{pattern-based macro} replaces any code that matches a @@ -247,9 +249,9 @@ Given our macro definitions, the @racket[swap] or @racket[rotate] identifiers must be used after an open parenthesis, otherwise a syntax error is reported: -@interaction-eval[(define-syntax swap (syntax-rules ()))] +@interaction-eval[#:eval swap-eval (define-syntax swap (syntax-rules ()))] -@interaction[(+ swap 3)] +@interaction[#:eval swap-eval (+ swap 3)] An @deftech{identifier macro} works in any expression. For example, we can define @racket[clock] as an identifier macro that expands to @@ -481,3 +483,6 @@ Racket with just three small pattern-based macros: @racket[define-cbr], @racket[define-for-cbr], and @racket[define-get/put-id]. +@; ----------------------------------------------------------------- + +@close-eval[swap-eval] From 4e33afc1005d4c1681a894a5ef845636f4847acc Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Feb 2011 07:11:48 -0700 Subject: [PATCH 116/746] fix dc<%> Closes PR 11706 Merge to 5.1 (cherry picked from commit 913f6b54868d594e4d47b84618df353f418a1805) --- collects/racket/draw/private/dc-intf.rkt | 68 +++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/collects/racket/draw/private/dc-intf.rkt b/collects/racket/draw/private/dc-intf.rkt index d0f9801192..c5f53ec415 100644 --- a/collects/racket/draw/private/dc-intf.rkt +++ b/collects/racket/draw/private/dc-intf.rkt @@ -6,4 +6,70 @@ (define dc<%> (interface () - draw-text)) + cache-font-metrics-key + clear + copy + draw-arc + draw-bitmap + draw-bitmap-section + draw-ellipse + draw-line + draw-lines + draw-path + draw-point + draw-polygon + draw-rectangle + draw-rounded-rectangle + draw-spline + draw-text + end-doc + end-page + erase + flush + get-alpha + get-background + get-brush + get-char-height + get-char-width + get-clipping-region + get-font + get-gl-context + get-initial-matrix + get-origin + get-pen + get-rotation + get-scale + get-size + get-smoothing + get-text-background + get-text-extent + get-text-foreground + get-text-mode + get-transformation + glyph-exists? + ok? + resume-flush + rotate + scale + set-alpha + set-background + set-brush + set-clipping-rect + set-clipping-region + set-font + set-initial-matrix + set-origin + set-pen + set-rotation + set-scale + set-smoothing + set-text-background + set-text-foreground + set-text-mode + set-transformation + start-doc + start-page + suspend-flush + transform + translate + try-color)) From 9721ad1ce734f2c12150cb28881a4db67a8dc842 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Feb 2011 07:25:02 -0700 Subject: [PATCH 117/746] cocoa: fix problems with `radio-box%' in no-selection mode Closes PR 11708 Merge to 5.1 (cherry picked from commit 5d1b78384d390520edf970021bc0c144f78c259e) --- collects/mred/private/wx/cocoa/radio-box.rkt | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/collects/mred/private/wx/cocoa/radio-box.rkt b/collects/mred/private/wx/cocoa/radio-box.rkt index 237ec581d1..558418df55 100644 --- a/collects/mred/private/wx/cocoa/radio-box.rkt +++ b/collects/mred/private/wx/cocoa/radio-box.rkt @@ -26,6 +26,9 @@ #:mixins (FocusResponder KeyMouseResponder CursorDisplayer) [wxb] (-a _void (clicked: [_id sender]) + ;; In case we were in 0-item mode, switch to Radio mode to + ;; ensure that only one button is selected: + (tellv self setMode: #:type _int NSRadioModeMatrix) (queue-window*-event wxb (lambda (wx) (send wx clicked))))) (define-objc-class MyImageButtonCell NSButtonCell @@ -127,15 +130,21 @@ (if (= i -1) (begin ;; Need to change to NSListModeMatrix to disable all. - ;; It seem that we don't have to change the mode back, for some reason. (tellv (get-cocoa) setMode: #:type _int NSListModeMatrix) (tellv (get-cocoa) deselectAllCells)) - (tellv (get-cocoa) selectCellAtRow: #:type _NSInteger (if horiz? 0 i) - column: #:type _NSInteger (if horiz? i 0)))) + (begin + (tellv (get-cocoa) setMode: #:type _int NSRadioModeMatrix) + (tellv (get-cocoa) selectCellAtRow: #:type _NSInteger (if horiz? 0 i) + column: #:type _NSInteger (if horiz? i 0))))) (define/public (get-selection) - (if horiz? - (tell #:type _NSInteger (get-cocoa) selectedColumn) - (tell #:type _NSInteger (get-cocoa) selectedRow))) + (let ([c (tell (get-cocoa) selectedCell)] + [pos (if horiz? + (tell #:type _NSInteger (get-cocoa) selectedColumn) + (tell #:type _NSInteger (get-cocoa) selectedRow))]) + (if (and c + (positive? (tell #:type _NSInteger c state))) + pos + -1))) (define/public (number) count) (define/override (maybe-register-as-child parent on?) From 08ff71d1a1bdb8ded13d698ed6e095fc77aa2908 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Feb 2011 09:19:19 -0700 Subject: [PATCH 118/746] win32: fix horizontal `radio-box%' Merge to 5.1 (cherry picked from commit 8f404a46187da3c21dcf52185d0912abdf3ba85f) --- collects/mred/private/wx/win32/radio-box.rkt | 77 +++++++++++--------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/collects/mred/private/wx/win32/radio-box.rkt b/collects/mred/private/wx/win32/radio-box.rkt index e395003a5e..329f5c8616 100644 --- a/collects/mred/private/wx/win32/radio-box.rkt +++ b/collects/mred/private/wx/win32/radio-box.rkt @@ -49,42 +49,47 @@ (define label-bitmaps null) (define radio-hwnds - (let loop ([y 0] [w 0] [labels labels]) - (if (null? labels) - (begin - (MoveWindow hwnd 0 0 w y #t) - null) - (let* ([label (car labels)] - [bitmap? (label . is-a? . bitmap%)] - [radio-hwnd - (CreateWindowExW/control 0 - "PLTBUTTON" - (if (string? label) - label - "") - (bitwise-ior BS_RADIOBUTTON WS_CHILD WS_CLIPSIBLINGS - (if bitmap? - BS_BITMAP - 0)) - 0 0 0 0 - hwnd - #f - hInstance - #f)]) - (when bitmap? - (let ([hbitmap (bitmap->hbitmap label)]) - (set! label-bitmaps (cons hbitmap label-bitmaps)) - (SendMessageW radio-hwnd BM_SETIMAGE IMAGE_BITMAP - (cast hbitmap _HBITMAP _LPARAM)))) - (ShowWindow radio-hwnd SW_SHOW) - (set-control-font font radio-hwnd) - (let-values ([(w1 h) - (auto-size font label 0 0 20 4 - (lambda (w h) - (MoveWindow radio-hwnd 0 (+ y SEP) w h #t) - (values w h)))]) - (cons radio-hwnd - (loop (+ y SEP h) (max w1 w) (cdr labels)))))))) + (let ([horiz? (memq 'horizontal style)]) + (let loop ([y 0] [w 0] [labels labels]) + (if (null? labels) + (begin + (MoveWindow hwnd 0 0 w y #t) + null) + (let* ([label (car labels)] + [bitmap? (label . is-a? . bitmap%)] + [radio-hwnd + (CreateWindowExW/control 0 + "PLTBUTTON" + (if (string? label) + label + "") + (bitwise-ior BS_RADIOBUTTON WS_CHILD WS_CLIPSIBLINGS + (if bitmap? + BS_BITMAP + 0)) + 0 0 0 0 + hwnd + #f + hInstance + #f)]) + (when bitmap? + (let ([hbitmap (bitmap->hbitmap label)]) + (set! label-bitmaps (cons hbitmap label-bitmaps)) + (SendMessageW radio-hwnd BM_SETIMAGE IMAGE_BITMAP + (cast hbitmap _HBITMAP _LPARAM)))) + (ShowWindow radio-hwnd SW_SHOW) + (set-control-font font radio-hwnd) + (let-values ([(w1 h) + (auto-size font label 0 0 20 4 + (lambda (w1 h1) + (if horiz? + (MoveWindow radio-hwnd (+ w SEP) 0 w1 h1 #t) + (MoveWindow radio-hwnd 0 (+ y SEP) w1 h1 #t)) + (values w1 h1)))]) + (cons radio-hwnd + (loop (if horiz? (max y h) (+ y SEP h)) + (if horiz? (+ w SEP w1) (max w1 w)) + (cdr labels))))))))) (unless (= val -1) (SendMessageW (list-ref radio-hwnds val) BM_SETCHECK 1 0)) From 1fba9e40fbbd7de41b2fe4fbbf0c7145ae634af5 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 4 Feb 2011 13:06:23 -0600 Subject: [PATCH 119/746] add a little more about quasiquote to the guide Please merge to the 5.1 release branch (cherry picked from commit 74f8b0e2f13c47cbd13bf1b0a1275ee389fdbdf9) --- collects/scribblings/guide/match.scrbl | 16 +++++ collects/scribblings/guide/qq.scrbl | 97 ++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/collects/scribblings/guide/match.scrbl b/collects/scribblings/guide/match.scrbl index 2918045db4..7025ba9f1a 100644 --- a/collects/scribblings/guide/match.scrbl +++ b/collects/scribblings/guide/match.scrbl @@ -119,6 +119,22 @@ pattern variables can be bound to lists of lists of matches: [(list (list '! x ...) ...) x]) ] + +The @racket[quasiquote] form (see @secref["qq"] for more about it) can also be used to build patterns. +While unquoted portions of a normal quasiquoted form mean regular racket evaluation, here unquoted +portions mean go back to regular pattern matching. + +So, in the example below, the with expression is the pattern and it gets rewritten into the +application expression, using quasiquote as a pattern in the first instance and quasiquote +to build an expression in the second. + +@interaction[ +#:eval match-eval +(match `{with {x 1} {+ x 1}} + [`{with {,id ,rhs} ,body} + `{{lambda {,id} ,body} ,rhs}]) +] + For information on many more pattern forms, see @racketmodname[racket/match]. Forms like @racket[match-let] and @racket[match-lambda] support diff --git a/collects/scribblings/guide/qq.scrbl b/collects/scribblings/guide/qq.scrbl index f9fa41dc49..30b674f2ff 100644 --- a/collects/scribblings/guide/qq.scrbl +++ b/collects/scribblings/guide/qq.scrbl @@ -24,6 +24,63 @@ evaluated to produce a value that takes the place of the `(1 2 ,(+ 1 2), (- 5 1))) ] +This form can be used to write functions that build lists according to +certain patterns. + +@examples[ +(eval:alts (define (deep n) + (cond + [(zero? n) 0] + [else + (#,qq ((#,uq n) (#,uq (deep (- n 1)))))])) + (define (deep n) + (cond + [(zero? n) 0] + [else + (quasiquote ((unquote n) (unquote (deep (- n 1)))))]))) +(deep 8) +] + +Or even to cheaply construct expressions programmatically. (Of course, 9 times out of 10, +you should be using a @seclink["macros"]{macro} to do this +(the 10th time being when you're working through +a textbook like @hyperlink["http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/"]{PLAI}).) + +@examples[(define (build-exp n) + (add-lets n (make-sum n))) + + (eval:alts + (define (add-lets n body) + (cond + [(zero? n) body] + [else + (#,qq + (let ([(#,uq (n->var n)) (#,uq n)]) + (#,uq (add-lets (- n 1) body))))])) + (define (add-lets n body) + (cond + [(zero? n) body] + [else + (quasiquote + (let ([(unquote (n->var n)) (unquote n)]) + (unquote (add-lets (- n 1) body))))]))) + + (eval:alts + (define (make-sum n) + (cond + [(= n 1) (n->var 1)] + [else + (#,qq (+ (#,uq (n->var n)) + (#,uq (make-sum (- n 1)))))])) + (define (make-sum n) + (cond + [(= n 1) (n->var 1)] + [else + (quasiquote (+ (unquote (n->var n)) + (unquote (make-sum (- n 1)))))]))) + (define (n->var n) (string->symbol (format "x~a" n))) + (build-exp 3)] + The @racket[unquote-splicing] form is similar to @racket[unquote], but its @racket[_expr] must produce a list, and the @racket[unquote-splicing] form must appear in a context that produces @@ -35,6 +92,46 @@ is spliced into the context of its use. `(1 2 ,@(list (+ 1 2) (- 5 1)) 5)) ] +Using splicing we can revise the construction of our example expressions above +to have just a single @racket[let] expression and a single @racket[+] expression. + +@examples[(eval:alts + (define (build-exp n) + (add-lets + n + (#,qq (+ (#,(racket unquote-splicing) + (build-list + n + (λ (x) (n->var (+ x 1))))))))) + (define (build-exp n) + (add-lets + n + (quasiquote (+ (unquote-splicing + (build-list + n + (λ (x) (n->var (+ x 1)))))))))) + (eval:alts + (define (add-lets n body) + (#,qq + (let (#,uq + (build-list + n + (λ (n) + (#,qq + [(#,uq (n->var (+ n 1))) (#,uq (+ n 1))])))) + (#,uq body)))) + (define (add-lets n body) + (quasiquote + (let (unquote + (build-list + n + (λ (n) + (quasiquote + [(unquote (n->var (+ n 1))) (unquote (+ n 1))])))) + (unquote body))))) + (define (n->var n) (string->symbol (format "x~a" n))) + (build-exp 3)] + If a @racket[quasiquote] form appears within an enclosing @racket[quasiquote] form, then the inner @racket[quasiquote] effectively cancels one layer of @racket[unquote] and From ae73336ede1df5e53ab7a45c83ddac3a4d360a07 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 4 Feb 2011 15:35:51 -0700 Subject: [PATCH 120/746] fixed macro stepper bug Merge to release branch (cherry picked from commit 2c1d49de6f4b10f8ea921a5c6fc03729c72878d4) --- collects/macro-debugger/model/reductions.rkt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/collects/macro-debugger/model/reductions.rkt b/collects/macro-debugger/model/reductions.rkt index 925d3f2b1e..2eb58fbaa5 100644 --- a/collects/macro-debugger/model/reductions.rkt +++ b/collects/macro-debugger/model/reductions.rkt @@ -1,5 +1,6 @@ #lang racket/base (require racket/match + (for-syntax racket/base) "../util/eomap.rkt" "stx-util.rkt" "deriv-util.rkt" @@ -34,9 +35,16 @@ ;; Syntax -(define-syntax-rule (match/count x . clauses) +(define-syntax-rule (match/count x clause ...) (begin (sequence-number (add1 (sequence-number))) - (match x . clauses))) + (let ([v x]) + (match v + clause ... + [_ (error 'match "failed to match ~e at line ~s" v (line-of x))])))) + +(define-syntax (line-of stx) + (syntax-case stx () + [(line-of x) #`(quote #,(syntax-line #'x))])) ;; Derivations => Steps @@ -472,7 +480,10 @@ ;; Add remark step? ]] [(struct local-remark (contents)) - (R [#:reductions (list (walk/talk 'remark contents))])])) + (R [#:reductions (list (walk/talk 'remark contents))])] + + [#f + (R)])) ;; List : ListDerivation -> RST (define (List ld) From e8a0c3c1872e94080822155ee166e371cbb86222 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Feb 2011 19:17:11 -0700 Subject: [PATCH 121/746] cocoa: yet another hack around weird cocoa behavior Closes PR 11712 Merge to 5.1 (cherry picked from commit 845ca2d58668c40c2ce2ab314867974877b2da93) --- collects/mred/private/wx/cocoa/slider.rkt | 7 +++++++ collects/mred/private/wx/cocoa/window.rkt | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/collects/mred/private/wx/cocoa/slider.rkt b/collects/mred/private/wx/cocoa/slider.rkt index c0e820e3c8..e735287d69 100644 --- a/collects/mred/private/wx/cocoa/slider.rkt +++ b/collects/mred/private/wx/cocoa/slider.rkt @@ -8,6 +8,7 @@ "const.rkt" "utils.rkt" "window.rkt" + "queue.rkt" "../common/event.rkt" "../common/queue.rkt" "../common/freeze.rkt" @@ -158,6 +159,12 @@ (define/public (update-message [val (get-value)]) (tellv message-cocoa setTitleWithMnemonic: #:type _NSString (format "~a" val))) + (inherit get-cocoa-window) + (define/override (post-mouse-down) + ;; For some reason, dragging a slider disabled mouse-moved + ;; events for the window, so turn them back on: + (tellv (get-cocoa-window) setAcceptsMouseMovedEvents: #:type _BOOL #t)) + (define/override (maybe-register-as-child parent on?) (register-as-child parent on?))) diff --git a/collects/mred/private/wx/cocoa/window.rkt b/collects/mred/private/wx/cocoa/window.rkt index 409b6ef5eb..906c034978 100644 --- a/collects/mred/private/wx/cocoa/window.rkt +++ b/collects/mred/private/wx/cocoa/window.rkt @@ -98,7 +98,10 @@ [wxb] [-a _void (mouseDown: [_id event]) (unless (do-mouse-event wxb event 'left-down #t #f #f 'right-down) - (super-tell #:type _void mouseDown: event))] + (super-tell #:type _void mouseDown: event) + (let ([wx (->wx wxb)]) + (when wx + (send wx post-mouse-down))))] [-a _void (mouseUp: [_id event]) (unless (do-mouse-event wxb event 'left-up #f #f #f 'right-up) (super-tell #:type _void mouseUp: event))] @@ -727,6 +730,8 @@ [caps-down #f]) #f)) + (define/public (post-mouse-down) (void)) + (define/public (on-char s) (void)) (define/public (on-event m) (void)) (define/public (queue-on-size) (void)) From b32d2eeaace0ae8be236f1a2c90d11640601d414 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Feb 2011 06:41:09 -0700 Subject: [PATCH 122/746] futures: fix lightweight-continuation GC bug Merge to 5.1 (cherry picked from commit 7579b487913b3bf84d339686f2e77c0136359d53) --- src/racket/src/fun.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/racket/src/fun.c b/src/racket/src/fun.c index 3c223f67f5..e68dbf40f7 100644 --- a/src/racket/src/fun.c +++ b/src/racket/src/fun.c @@ -8516,6 +8516,7 @@ Scheme_Lightweight_Continuation *scheme_capture_lightweight_continuation(Scheme_ lw = (Scheme_Lightweight_Continuation *)storage[0]; lw->stack_slice = stack; + lwc = lw->saved_lwc; len = lwc->runstack_start - lwc->runstack_end; runstack_slice = MALLOC_N(Scheme_Object*, len); @@ -8535,6 +8536,7 @@ Scheme_Lightweight_Continuation *scheme_capture_lightweight_continuation(Scheme_ runstack_slice[i] = 0; } + lwc = lw->saved_lwc; len = lwc->cont_mark_stack_end - lwc->cont_mark_stack_start; if (len) { From cc3e6e18125a1ee72b2587a1c815cba1b8133ec1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Feb 2011 06:42:08 -0700 Subject: [PATCH 123/746] futures: fix `future' when given a non-JITted procedure Merge to 5.1 (cherry picked from commit da6d4f3fbac79bf2369810c2252c9489e2ded99f) --- collects/tests/future/future.rkt | 12 ++++++++++++ src/racket/src/future.c | 24 +++++++++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/collects/tests/future/future.rkt b/collects/tests/future/future.rkt index 3371ef6105..907bd75cf4 100644 --- a/collects/tests/future/future.rkt +++ b/collects/tests/future/future.rkt @@ -202,3 +202,15 @@ We should also test deep continuations. (future (lambda () (and (eq? (touch f) f) (current-future))))))) + +;; Make sure that `future' doesn't mishandle functions +;; that aren't be JITted: +(check-equal? + (for/list ([i (in-range 10)]) (void)) + (map + touch + (for/list ([i (in-range 10)]) + (if (even? i) + (future void) + (future (parameterize ([eval-jit-enabled #f]) + (eval #'(lambda () (void))))))))) diff --git a/src/racket/src/future.c b/src/racket/src/future.c index 9c60c64a03..3ade173584 100644 --- a/src/racket/src/future.c +++ b/src/racket/src/future.c @@ -642,8 +642,13 @@ Scheme_Object *scheme_future(int argc, Scheme_Object *argv[]) } } - nc = (Scheme_Native_Closure*)lambda; - ncd = nc->code; + if (SAME_TYPE(SCHEME_TYPE(lambda), scheme_native_closure_type)) { + nc = (Scheme_Native_Closure*)lambda; + ncd = nc->code; + } else { + nc = NULL; + ncd = NULL; + } /* Create the future descriptor and add to the queue as 'pending' */ ft = MALLOC_ONE_TAGGED(future_t); @@ -655,17 +660,18 @@ Scheme_Object *scheme_future(int argc, Scheme_Object *argv[]) ft->status = PENDING; /* JIT the code if not already JITted */ - if (ncd->code == scheme_on_demand_jit_code) - { + if (ncd) { + if (ncd->code == scheme_on_demand_jit_code) scheme_on_demand_generate_lambda(nc, 0, NULL); + + if (ncd->max_let_depth > FUTURE_RUNSTACK_SIZE * sizeof(void*)) { + /* Can't even call it in a future thread */ + ft->status = PENDING_OVERSIZE; } - if (ncd->max_let_depth > FUTURE_RUNSTACK_SIZE * sizeof(void*)) { - /* Can't even call it in a future thread */ + ft->code = (void*)ncd->code; + } else ft->status = PENDING_OVERSIZE; - } - - ft->code = (void*)ncd->code; if (ft->status != PENDING_OVERSIZE) { mzrt_mutex_lock(fs->future_mutex); From 88c18e08f6c51ea0d00df499928a3c6718fad019 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Sat, 5 Feb 2011 07:13:17 -0700 Subject: [PATCH 124/746] Fixes PR11713 (cherry picked from commit b4c3d82c948ba263a19b680eeadde88ac7b7e4c6) --- collects/rackunit/scribblings/philosophy.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/rackunit/scribblings/philosophy.scrbl b/collects/rackunit/scribblings/philosophy.scrbl index 5b439a04b6..de659850d3 100644 --- a/collects/rackunit/scribblings/philosophy.scrbl +++ b/collects/rackunit/scribblings/philosophy.scrbl @@ -110,7 +110,7 @@ which is the ancestor of RackUnit and the most widely used frameworks in Java, .Net, Python, and Ruby, and many other languages. That this is insufficient for all users is apparent if one considers the proliferation of ``simpler'' -testing frameworks in Racket such as SRFI-78, or the +testing frameworks in Scheme such as SRFI-78, or the practice of beginner programmers. Unfortunately these simpler methods are inadequate for testing larger systems. To the best of my knowledge RackUnit is the only From a917f465f788e53bbd1e26f5350f8eac9b162f64 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Feb 2011 12:23:03 -0700 Subject: [PATCH 125/746] add `file/resource' (cherry picked from commit b4ce4bbd2ce53dc6b1b1ed372514092ce6951ade) --- collects/file/resource.rkt | 251 +++++++++++++++++++++++ collects/file/scribblings/file.scrbl | 1 + collects/file/scribblings/resource.scrbl | 100 +++++++++ collects/tests/racket/mzlib-tests.rktl | 1 + collects/tests/racket/resource.rktl | 50 +++++ 5 files changed, 403 insertions(+) create mode 100644 collects/file/resource.rkt create mode 100644 collects/file/scribblings/resource.scrbl create mode 100644 collects/tests/racket/resource.rktl diff --git a/collects/file/resource.rkt b/collects/file/resource.rkt new file mode 100644 index 0000000000..d668497a7c --- /dev/null +++ b/collects/file/resource.rkt @@ -0,0 +1,251 @@ +#lang racket/base +(require ffi/unsafe + ffi/unsafe/define) + +(provide get-resource + write-resource) + +(define _HKEY (_cpointer/null 'HKEY)) + +(define (const-hkey v) + (cast (bitwise-ior v (arithmetic-shift -1 32)) _intptr _HKEY)) + +(define HKEY_CLASSES_ROOT (const-hkey #x80000000)) +(define HKEY_CURRENT_USER (const-hkey #x80000001)) +(define HKEY_LOCAL_MACHINE (const-hkey #x80000002)) +(define HKEY_USERS (const-hkey #x80000003)) +(define HKEY_CURRENT_CONFIG (const-hkey #x80000005)) + +(define REG_SZ 1) +(define REG_BINARY 3) +(define REG_DWORD 4) + +(define (section->hkey who section) + (cond + [(equal? section "HKEY_CLASSES_ROOT") + HKEY_CLASSES_ROOT] + [(equal? section "HKEY_CURRENT_CONFIG") + HKEY_CURRENT_CONFIG] + [(equal? section "HKEY_CURRENT_USER") + HKEY_CURRENT_USER] + [(equal? section "HKEY_LOCAL_MACHINE") + HKEY_LOCAL_MACHINE] + [(equal? section "HKEY_USERS") + HKEY_USERS] + [else + (raise-type-error who + (string-append + "\"HKEY_CLASSES_ROOT\", \"HKEY_CURRENT_CONFIG\", " + "\"HKEY_CURRENT_USER\", \"HKEY_LOCAL_MACHINE\", " + "or \"HKEY_USERS\"") + section)])) + +(define advapi-dll (and (eq? (system-type) 'windows) + (ffi-lib "Advapi32.dll"))) + +(define-ffi-definer define-advapi advapi-dll + #:default-make-fail make-not-available) + +(define win64? (equal? "win32\\x86_64" (path->string (system-library-subpath #f)))) +(define win_abi (if win64? #f 'stdcall)) + +(define _LONG _long) +(define _DWORD _int32) +(define _REGSAM _DWORD) + +(define KEY_QUERY_VALUE #x1) +(define KEY_SET_VALUE #x2) + +(define ERROR_SUCCESS 0) + +(define-advapi RegOpenKeyExW (_fun #:abi win_abi + _HKEY _string/utf-16 _DWORD _REGSAM (hkey : (_ptr o _HKEY)) + -> (r : _LONG) + -> (and (= r ERROR_SUCCESS) hkey))) +(define-advapi RegCreateKeyExW (_fun #:abi win_abi + _HKEY _string/utf-16 (_DWORD = 0) + (_pointer = #f) ; class + _DWORD ; options + _REGSAM + _pointer ; security + (hkey : (_ptr o _HKEY)) + (_ptr o _DWORD) ; disposition + -> (r : _LONG) + -> (and (= r ERROR_SUCCESS) hkey))) + +(define-advapi RegQueryValueExW (_fun #:abi win_abi + _HKEY _string/utf-16 (_pointer = #f) + (type : (_ptr o _DWORD)) + _pointer (len : (_ptr io _DWORD)) + -> (r : _LONG) + -> (if (= r ERROR_SUCCESS) + (values len type) + (values #f #f)))) +(define-advapi RegSetValueExW (_fun #:abi win_abi + _HKEY _string/utf-16 (_pointer = #f) + _DWORD _pointer _DWORD + -> (r : _LONG) + -> (= r ERROR_SUCCESS))) + +(define-advapi RegCloseKey (_fun #:abi win_abi _HKEY -> _LONG)) + +(define (check-platform who) + (unless (eq? 'windows (system-type)) + (raise + (make-exn:fail:unsupported + (format "~a: unsupported on this platform" who) + (current-continuation-marks))))) + +(define (extract-sub-hkey hkey entry op create-key?) + (cond + [(regexp-match #rx"^(.*)\\\\+([^\\]*)$" entry) + => (lambda (m) + (let ([sub-hkey (RegOpenKeyExW hkey (cadr m) 0 op)] + [sub-entry (caddr m)]) + (if (and (not sub-hkey) + create-key?) + (values (RegCreateKeyExW hkey (cadr m) 0 op #f) + sub-entry) + (values sub-hkey sub-entry))))] + [else (values hkey entry)])) + +(define (get-resource section entry [value #f] [file #f] + #:type [rtype (or (and (box? value) + (or + (and (exact-integer? (unbox value)) + 'integer) + (and (bytes? (unbox value)) + 'bytes))) + 'string)]) + (define hkey (section->hkey 'get-resource section)) + (unless (string? entry) + (raise-type-error 'get-resource "string" entry)) + (unless (or (not value) + (and (box? value) + (let ([value (unbox value)]) + (or (string? value) (bytes? value) (exact-integer? value))))) + (raise-type-error 'get-resource "box of string, byte string, or exact integer")) + (unless (not file) + (raise-type-error 'get-resource "#f" file)) + (unless (memq rtype '(string bytes integer)) + (raise-type-error 'get-resource "'string, 'bytes, or 'integer" rtype)) + + (check-platform 'get-resource) + + (define-values (sub-hkey sub-entry) + (extract-sub-hkey hkey entry KEY_QUERY_VALUE #f)) + + (and sub-hkey + (begin0 + (let-values ([(len type) + ;; Get size, first + (RegQueryValueExW sub-hkey sub-entry #f 0)]) + (and len + (let ([s (make-bytes len)]) + (let-values ([(len2 type2) + ;; Get value, now that we have a bytes string of the right size + (RegQueryValueExW sub-hkey sub-entry s len)]) + (and len2 + (let ([r + ;; Unmarhsal according to requested type: + (let ([s (cond + [(= type REG_SZ) + (cast s _pointer _string/utf-16)] + [(= type REG_DWORD) + (number->string (ptr-ref s _DWORD))] + [else + s])] + [to-string (lambda (s) + (if (bytes? s) + (bytes->string/utf-8 s #\?) + s))]) + (cond + [(eq? rtype 'string) (to-string s)] + [(eq? rtype 'integer) + (let ([n (string->number (to-string s))]) + (or (and n (exact-integer? n) n) + 0))] + [else + (if (string? s) + (string->bytes/utf-8 s) + s)]))]) + (if (box? value) + (begin + (set-box! value r) + #t) + r))))))) + (unless (eq? hkey sub-hkey) + (RegCloseKey sub-hkey))))) + +(define (write-resource section entry value [file #f] + #:type [type 'string] + #:create-key? [create-key? #f]) + (define hkey (section->hkey 'write-resource section)) + (unless (string? entry) + (raise-type-error 'write-resource "string" entry)) + (unless (or (string? value) (bytes? value) (exact-integer? value)) + (raise-type-error 'write-resource "string, byte string, or exact integer")) + (unless (not file) + (raise-type-error 'write-resource "#f" file)) + (unless (memq type '(string bytes dword)) + (raise-type-error 'write-resource "'string, 'bytes, or 'dword" type)) + + (check-platform 'write-resource) + + (define-values (sub-hkey sub-entry) + (extract-sub-hkey hkey entry KEY_SET_VALUE create-key?)) + + (and sub-hkey + (begin0 + (let ([v (case type + [(string) + (to-utf-16 + (cond + [(exact-integer? value) (number->string value)] + [(string? value) value] + [else (bytes->string/utf-8 value #\?)]))] + [(bytes) + (cond + [(exact-integer? value) + (string->bytes/utf-8 (number->string value))] + [(string? value) (string->bytes/utf-8 value)] + [else value])] + [(dword) + (to-dword-ptr + (cond + [(exact-integer? value) value] + [(string? value) (string->number value)] + [(bytes? value) + (string->number (bytes->string/utf-8 value #\?))]))])] + [ty (case type + [(string) REG_SZ] + [(bytes) REG_BINARY] + [(dword) REG_DWORD])]) + (RegSetValueExW sub-hkey sub-entry ty v (bytes-length v))) + (unless (eq? hkey sub-hkey) + (RegCloseKey sub-hkey))))) + +(define (to-utf-16 s) + (let ([v (malloc _gcpointer)]) + (ptr-set! v _string/utf-16 s) + (let ([p (ptr-ref v _gcpointer)]) + (let ([len (* 2 (+ 1 (utf-16-length s)))]) + (ptr-ref v (_bytes o len)))))) + +(define (utf-16-length s) + (for/fold ([len 0]) ([c (in-string s)]) + (+ len + (if ((char->integer c) . > . #xFFFF) + 2 + 1)))) + +(define (to-dword-ptr v) + (let ([v (if (and (exact-integer? v) + (<= (- (expt 2 31)) + v + (sub1 (expt 2 31)))) + v + 0)]) + (let ([p (malloc _DWORD)]) + (ptr-set! p _DWORD v) + (cast p _pointer (_bytes o (ctype-sizeof _DWORD)))))) diff --git a/collects/file/scribblings/file.scrbl b/collects/file/scribblings/file.scrbl index e9ccc91601..4ab38c6d8a 100644 --- a/collects/file/scribblings/file.scrbl +++ b/collects/file/scribblings/file.scrbl @@ -13,6 +13,7 @@ @include-section["md5.scrbl"] @include-section["sha1.scrbl"] @include-section["gif.scrbl"] +@include-section["resource.scrbl"] @(bibliography (bib-entry #:key "Gervautz1990" diff --git a/collects/file/scribblings/resource.scrbl b/collects/file/scribblings/resource.scrbl new file mode 100644 index 0000000000..4fc5254a68 --- /dev/null +++ b/collects/file/scribblings/resource.scrbl @@ -0,0 +1,100 @@ +#lang scribble/doc +@(require "common.ss" + (for-label file/resource)) + +@title[#:tag "resource"]{Windows Registry} + +@defmodule[file/resource] + +@defproc[(get-resource [section (or/c "HKEY_CLASSES_ROOT" + "HKEY_CURRENT_CONFIG" + "HKEY_CURRENT_USER" + "HKEY_LOCAL_MACHINE" + "HKEY_USERS")] + [entry string?] + [value-box (or/f #f (box/c (or/c string? bytes? exact-integer?))) #f] + [file #f #f] + [#:type type (or/c 'string 'bytes 'integer) _derived-from-value-box]) + (or/c #f string? bytes? exact-integer? #t)]{ + +Gets a value from the Windows registry. Under platforms other than + Windows, an @racket[exn:fail:unsupported] exception is raised. + +The resource value is keyed on the combination of @racket[section] and + @racket[entry]. The result is @racket[#f] if no value is found for + the specified @racket[section] and @racket[entry]. If @racket[value-box] + is a box, then the result is @racket[#t] if a value is found, and the + box is filled with the value; when @racket[value-box] is @racket[#f], the result is the found + value. + +The @racket[type] argument determines how a value in the registry is + converted to a Racket value. If @racket[value-box] is a box, then the + default @racket[type] is derived from the initial box content, + otherwise the default @racket[type] is @racket['string]. + +Registry values of any format can be extracted. Values using the + registry format @tt{REG_SZ} are treated as strings, and values with + the format @tt{REG_DWORD} are treated as 32-bit signed integers. All + other formats are treated as raw bytes. Data from the registry is + converted to the requested type @racket[type]: + +@itemlist[ + + @item{A @tt{REG_SZ} registry value is converted to an integer using + @racket[string->number] (using @racket[0] if the result is not + an exact integer), and it is converted to bytes using + @racket[string->bytes/utf-8].} + + @item{A @tt{REG_DWORD} registry value is converted to a string or + byte string via @racket[number->string] and (for byte strings) + @racket[string->bytes/utf-8].} + + @item{Any other kind of registry value is converted to a string or + integer using @racket[bytes->string/utf-8] and (for integers) + @racket[string->number].} + +] + +The @racket[file] argument is included for backward compatibility and + must be @racket[#f]. + +To get the ``default'' value for an entry, use a trailing backslash. For +example, the following expression gets a command line for starting a +browser: + +@racketblock[ + (get-resource "HKEY_CLASSES_ROOT" + "htmlfile\\shell\\open\\command\\") +]} + +@defproc[(write-resource [section (or/c "HKEY_CLASSES_ROOT" + "HKEY_CURRENT_CONFIG" + "HKEY_CURRENT_USER" + "HKEY_LOCAL_MACHINE" + "HKEY_USERS")] + [entry string?] + [value (or/c string? bytes? exact-integer?)] + [file #f #f] + [#:type type (or/c 'string 'bytes 'integer) 'string] + [#:create-key? create-key? any/c #f]) + boolean?]{ + +Write a value to the Windows registry. Under platforms other than + Windows, an @racket[exn:fail:unsupported] exception is raised. + +The resource value is keyed on the combination of @racket[section] and + @racket[entry]. If @racket[create-key?] is false, the resource entry + must already exist, otherwise the write fails. The result is + @racket[#f] if the write fails or @racket[#t] if it succeeds. + +The @racket[type] argument determines the format of the value in the + registry: @racket['string] writes using the @tt{REG_SZ} format, + @racket['bytes] writes using the @tt{REG_BINARY} format, and + @racket['dword] writes using the @tt{REG_DWORD} format. Any kind of + @racket[value] can be converted for any kind of @racket[type] using + the inverse of the conversions for @racket[get-resource]. + +The @racket[file] argument must be @racket[#f]. A path is allowed for + backward compatibility of arguments, but providing a path causes an + @racket[exn:fail:unsupported] exception to be raised.} + diff --git a/collects/tests/racket/mzlib-tests.rktl b/collects/tests/racket/mzlib-tests.rktl index 81fc47b394..5305a069b0 100644 --- a/collects/tests/racket/mzlib-tests.rktl +++ b/collects/tests/racket/mzlib-tests.rktl @@ -27,5 +27,6 @@ (load-in-sandbox "shared.rktl") (load-in-sandbox "kw.rktl") (load-in-sandbox "macrolib.rktl") +(load-in-sandbox "resource.rktl") (report-errs) diff --git a/collects/tests/racket/resource.rktl b/collects/tests/racket/resource.rktl new file mode 100644 index 0000000000..9ab8b8c98f --- /dev/null +++ b/collects/tests/racket/resource.rktl @@ -0,0 +1,50 @@ + +;; This test modifies registry entries under Windows +;; within HKEY_CURRENT_USER\Software\PLT + +(load-relative "loadtest.rktl") + +(Section 'resource) + +(require file/resource) + +(when (eq? 'windows (system-type)) + (define key "HKEY_CURRENT_USER") + (define (entry s) (string-append "SOFTWARE\\PLT\\" s)) + + (test #t 'init (write-resource key (entry "Stuff") "Hello" #:create-key? #t)) + + ;; A string-valued resource: + (test #t write-resource key (entry "Stuff") "Hola") + (test "Hola" get-resource key (entry "Stuff")) + (test #"Hola" get-resource key (entry "Stuff") #:type 'bytes) + (test 0 get-resource key (entry "Stuff") #:type 'integer) + (let ([b (box "")]) + (test #t get-resource key (entry "Stuff") b) + (test "Hola" unbox b)) + (let ([b (box #"")]) + (test #t get-resource key (entry "Stuff") b) + (test #"Hola" unbox b)) + (let ([b (box 10)]) + (test #t get-resource key (entry "Stuff") b) + (test 0 unbox b)) + + ;; An integer-valued resource + (test #t write-resource key (entry "Count") 17 #:type 'dword) + (test "17" get-resource key (entry "Count")) + (test #"17" get-resource key (entry "Count") #:type 'bytes) + (test 17 get-resource key (entry "Count") #:type 'integer) + (test #t write-resource key (entry "Count") -17 #:type 'dword) + (test -17 get-resource key (entry "Count") #:type 'integer) + + ;; A bytes-valued resource: + (test #t write-resource key (entry "Data") #"i\377mage" #:type 'bytes) + (test "i?mage" get-resource key (entry "Data")) + (test #"i\377mage" get-resource key (entry "Data") #:type 'bytes) + (test 0 get-resource key (entry "Data") #:type 'integer) + + (void)) + +(report-errs) + + From e4db039f201f8f18b3b258e19b465354d7266791 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Feb 2011 14:24:22 -0700 Subject: [PATCH 126/746] `file/resource': improve compatibility by generating "failure" results instead of exn:fail:unsupported (cherry picked from commit 337500552c8bbf3c3078236a483c889003b2a44c) --- collects/file/resource.rkt | 37 ++++++----------- collects/file/scribblings/resource.scrbl | 40 +++++++----------- collects/tests/racket/resource.rktl | 53 ++++++++++++++---------- 3 files changed, 60 insertions(+), 70 deletions(-) diff --git a/collects/file/resource.rkt b/collects/file/resource.rkt index d668497a7c..3ff776541c 100644 --- a/collects/file/resource.rkt +++ b/collects/file/resource.rkt @@ -32,13 +32,9 @@ HKEY_LOCAL_MACHINE] [(equal? section "HKEY_USERS") HKEY_USERS] + [(string? section) #f] [else - (raise-type-error who - (string-append - "\"HKEY_CLASSES_ROOT\", \"HKEY_CURRENT_CONFIG\", " - "\"HKEY_CURRENT_USER\", \"HKEY_LOCAL_MACHINE\", " - "or \"HKEY_USERS\"") - section)])) + (raise-type-error who "string" section)])) (define advapi-dll (and (eq? (system-type) 'windows) (ffi-lib "Advapi32.dll"))) @@ -89,15 +85,10 @@ (define-advapi RegCloseKey (_fun #:abi win_abi _HKEY -> _LONG)) -(define (check-platform who) - (unless (eq? 'windows (system-type)) - (raise - (make-exn:fail:unsupported - (format "~a: unsupported on this platform" who) - (current-continuation-marks))))) - -(define (extract-sub-hkey hkey entry op create-key?) +(define (extract-sub-hkey file hkey entry op create-key?) (cond + [(not (eq? 'windows (system-type))) (values #f #f)] + [file #f] [(regexp-match #rx"^(.*)\\\\+([^\\]*)$" entry) => (lambda (m) (let ([sub-hkey (RegOpenKeyExW hkey (cadr m) 0 op)] @@ -125,15 +116,14 @@ (let ([value (unbox value)]) (or (string? value) (bytes? value) (exact-integer? value))))) (raise-type-error 'get-resource "box of string, byte string, or exact integer")) - (unless (not file) - (raise-type-error 'get-resource "#f" file)) + (unless (or (not file) + (path-string? file)) + (raise-type-error 'get-resource "path string or #f" file)) (unless (memq rtype '(string bytes integer)) (raise-type-error 'get-resource "'string, 'bytes, or 'integer" rtype)) - (check-platform 'get-resource) - (define-values (sub-hkey sub-entry) - (extract-sub-hkey hkey entry KEY_QUERY_VALUE #f)) + (extract-sub-hkey file hkey entry KEY_QUERY_VALUE #f)) (and sub-hkey (begin0 @@ -185,15 +175,14 @@ (raise-type-error 'write-resource "string" entry)) (unless (or (string? value) (bytes? value) (exact-integer? value)) (raise-type-error 'write-resource "string, byte string, or exact integer")) - (unless (not file) - (raise-type-error 'write-resource "#f" file)) + (unless (or (not file) + (path-string? file)) + (raise-type-error 'write-resource "path string or #f" file)) (unless (memq type '(string bytes dword)) (raise-type-error 'write-resource "'string, 'bytes, or 'dword" type)) - (check-platform 'write-resource) - (define-values (sub-hkey sub-entry) - (extract-sub-hkey hkey entry KEY_SET_VALUE create-key?)) + (extract-sub-hkey file hkey entry KEY_SET_VALUE create-key?)) (and sub-hkey (begin0 diff --git a/collects/file/scribblings/resource.scrbl b/collects/file/scribblings/resource.scrbl index 4fc5254a68..ff290dce1b 100644 --- a/collects/file/scribblings/resource.scrbl +++ b/collects/file/scribblings/resource.scrbl @@ -2,23 +2,27 @@ @(require "common.ss" (for-label file/resource)) +@(define-syntax-rule (compat section indexed-racket) + @elem{For backward compatibilty, the + result is @racket[#f] for platforms other than Windows, when + @racket[file] is not @racket[#f], or when @racket[section] is not + @indexed-racket["HKEY_CLASSES_ROOT"], + @indexed-racket["HKEY_CURRENT_CONFIG"], + @indexed-racket["HKEY_CURRENT_USER"], + @indexed-racket["HKEY_LOCAL_MACHINE"], or @indexed-racket["HKEY_USERS"].}) + @title[#:tag "resource"]{Windows Registry} @defmodule[file/resource] -@defproc[(get-resource [section (or/c "HKEY_CLASSES_ROOT" - "HKEY_CURRENT_CONFIG" - "HKEY_CURRENT_USER" - "HKEY_LOCAL_MACHINE" - "HKEY_USERS")] +@defproc[(get-resource [section string?] [entry string?] [value-box (or/f #f (box/c (or/c string? bytes? exact-integer?))) #f] - [file #f #f] + [file (or/c #f fail-path?) #f] [#:type type (or/c 'string 'bytes 'integer) _derived-from-value-box]) (or/c #f string? bytes? exact-integer? #t)]{ -Gets a value from the Windows registry. Under platforms other than - Windows, an @racket[exn:fail:unsupported] exception is raised. +Gets a value from the Windows registry. @compat[section indexed-racket] The resource value is keyed on the combination of @racket[section] and @racket[entry]. The result is @racket[#f] if no value is found for @@ -55,9 +59,6 @@ Registry values of any format can be extracted. Values using the ] -The @racket[file] argument is included for backward compatibility and - must be @racket[#f]. - To get the ``default'' value for an entry, use a trailing backslash. For example, the following expression gets a command line for starting a browser: @@ -67,20 +68,15 @@ browser: "htmlfile\\shell\\open\\command\\") ]} -@defproc[(write-resource [section (or/c "HKEY_CLASSES_ROOT" - "HKEY_CURRENT_CONFIG" - "HKEY_CURRENT_USER" - "HKEY_LOCAL_MACHINE" - "HKEY_USERS")] +@defproc[(write-resource [section string?] [entry string?] [value (or/c string? bytes? exact-integer?)] - [file #f #f] + [file (or/c path-string? #f) #f] [#:type type (or/c 'string 'bytes 'integer) 'string] [#:create-key? create-key? any/c #f]) boolean?]{ -Write a value to the Windows registry. Under platforms other than - Windows, an @racket[exn:fail:unsupported] exception is raised. +Write a value to the Windows registry. @compat[section racket] The resource value is keyed on the combination of @racket[section] and @racket[entry]. If @racket[create-key?] is false, the resource entry @@ -92,9 +88,5 @@ The @racket[type] argument determines the format of the value in the @racket['bytes] writes using the @tt{REG_BINARY} format, and @racket['dword] writes using the @tt{REG_DWORD} format. Any kind of @racket[value] can be converted for any kind of @racket[type] using - the inverse of the conversions for @racket[get-resource]. - -The @racket[file] argument must be @racket[#f]. A path is allowed for - backward compatibility of arguments, but providing a path causes an - @racket[exn:fail:unsupported] exception to be raised.} + the inverse of the conversions for @racket[get-resource].} diff --git a/collects/tests/racket/resource.rktl b/collects/tests/racket/resource.rktl index 9ab8b8c98f..7f6a77da8e 100644 --- a/collects/tests/racket/resource.rktl +++ b/collects/tests/racket/resource.rktl @@ -8,40 +8,49 @@ (require file/resource) -(when (eq? 'windows (system-type)) +(let () (define key "HKEY_CURRENT_USER") (define (entry s) (string-append "SOFTWARE\\PLT\\" s)) + (define (rtest* kws kvs r . l) + (if (eq? 'windows (system-type)) + (keyword-apply test kws kvs r l) + (keyword-apply test kws kvs #f l))) + (define rtest (make-keyword-procedure rtest*)) + (define (xtest r alt-r . l) + (if (eq? 'windows (system-type)) + (apply test r l) + (apply test alt-r l))) - (test #t 'init (write-resource key (entry "Stuff") "Hello" #:create-key? #t)) + (rtest #t 'init (write-resource key (entry "Stuff") "Hello" #:create-key? #t)) ;; A string-valued resource: - (test #t write-resource key (entry "Stuff") "Hola") - (test "Hola" get-resource key (entry "Stuff")) - (test #"Hola" get-resource key (entry "Stuff") #:type 'bytes) - (test 0 get-resource key (entry "Stuff") #:type 'integer) + (rtest #t write-resource key (entry "Stuff") "Hola") + (rtest "Hola" get-resource key (entry "Stuff")) + (rtest #"Hola" get-resource key (entry "Stuff") #:type 'bytes) + (rtest 0 get-resource key (entry "Stuff") #:type 'integer) (let ([b (box "")]) - (test #t get-resource key (entry "Stuff") b) - (test "Hola" unbox b)) + (rtest #t get-resource key (entry "Stuff") b) + (xtest "Hola" "" unbox b)) (let ([b (box #"")]) - (test #t get-resource key (entry "Stuff") b) - (test #"Hola" unbox b)) + (rtest #t get-resource key (entry "Stuff") b) + (xtest #"Hola" #"" unbox b)) (let ([b (box 10)]) - (test #t get-resource key (entry "Stuff") b) - (test 0 unbox b)) + (rtest #t get-resource key (entry "Stuff") b) + (xtest 0 10 unbox b)) ;; An integer-valued resource - (test #t write-resource key (entry "Count") 17 #:type 'dword) - (test "17" get-resource key (entry "Count")) - (test #"17" get-resource key (entry "Count") #:type 'bytes) - (test 17 get-resource key (entry "Count") #:type 'integer) - (test #t write-resource key (entry "Count") -17 #:type 'dword) - (test -17 get-resource key (entry "Count") #:type 'integer) + (rtest #t write-resource key (entry "Count") 17 #:type 'dword) + (rtest "17" get-resource key (entry "Count")) + (rtest #"17" get-resource key (entry "Count") #:type 'bytes) + (rtest 17 get-resource key (entry "Count") #:type 'integer) + (rtest #t write-resource key (entry "Count") -17 #:type 'dword) + (rtest -17 get-resource key (entry "Count") #:type 'integer) ;; A bytes-valued resource: - (test #t write-resource key (entry "Data") #"i\377mage" #:type 'bytes) - (test "i?mage" get-resource key (entry "Data")) - (test #"i\377mage" get-resource key (entry "Data") #:type 'bytes) - (test 0 get-resource key (entry "Data") #:type 'integer) + (rtest #t write-resource key (entry "Data") #"i\377mage" #:type 'bytes) + (rtest "i?mage" get-resource key (entry "Data")) + (rtest #"i\377mage" get-resource key (entry "Data") #:type 'bytes) + (rtest 0 get-resource key (entry "Data") #:type 'integer) (void)) From a25b553b8e9d182070f6fc86a80edf64237c4df5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Feb 2011 07:25:47 -0700 Subject: [PATCH 127/746] `get-resource' and `write-resource': support .ini files (cherry picked from commit 18eb7c86b5f135445858de032d93c96f36c4ad4e) --- collects/file/resource.rkt | 195 ++++++++++++++--------- collects/file/scribblings/resource.scrbl | 49 ++++-- collects/tests/racket/resource.rktl | 17 +- 3 files changed, 170 insertions(+), 91 deletions(-) diff --git a/collects/file/resource.rkt b/collects/file/resource.rkt index 3ff776541c..9a58731e07 100644 --- a/collects/file/resource.rkt +++ b/collects/file/resource.rkt @@ -38,9 +38,13 @@ (define advapi-dll (and (eq? (system-type) 'windows) (ffi-lib "Advapi32.dll"))) +(define kernel-dll (and (eq? (system-type) 'windows) + (ffi-lib "kernel32.dll"))) (define-ffi-definer define-advapi advapi-dll #:default-make-fail make-not-available) +(define-ffi-definer define-kernel kernel-dll + #:default-make-fail make-not-available) (define win64? (equal? "win32\\x86_64" (path->string (system-library-subpath #f)))) (define win_abi (if win64? #f 'stdcall)) @@ -48,6 +52,7 @@ (define _LONG _long) (define _DWORD _int32) (define _REGSAM _DWORD) +(define _BOOL (make-ctype _int (lambda (v) (if v 1 0)) (lambda (v) (not (zero? v))))) (define KEY_QUERY_VALUE #x1) (define KEY_SET_VALUE #x2) @@ -85,10 +90,32 @@ (define-advapi RegCloseKey (_fun #:abi win_abi _HKEY -> _LONG)) +(define-kernel WritePrivateProfileStringW (_fun #:abi win_abi + _string/utf-16 ; app + _string/utf-16 ; key + _string/utf-16 ; val + _string/utf-16 ; filename + -> _BOOL)) +(define-kernel GetPrivateProfileStringW (_fun #:abi win_abi + _string/utf-16 ; app + _string/utf-16 ; key + _string/utf-16 ; default + _pointer ; result + _DWORD ; result size in wide chars + _string/utf-16 ; filename + -> _DWORD)) + +(define (file->ini f) + (cond + [(not f) (file->ini + (build-path (find-system-path 'home-dir) "mred.ini"))] + [(string? f) (file->ini (string->path f))] + [(path? f) (path->string (cleanse-path (path->complete-path f)))])) + (define (extract-sub-hkey file hkey entry op create-key?) (cond [(not (eq? 'windows (system-type))) (values #f #f)] - [file #f] + [file (values #f #f)] [(regexp-match #rx"^(.*)\\\\+([^\\]*)$" entry) => (lambda (m) (let ([sub-hkey (RegOpenKeyExW hkey (cadr m) 0 op)] @@ -122,50 +149,70 @@ (unless (memq rtype '(string bytes integer)) (raise-type-error 'get-resource "'string, 'bytes, or 'integer" rtype)) + (define (to-rtype s) + (let ([to-string (lambda (s) + (if (bytes? s) + (bytes->string/utf-8 s #\?) + s))]) + (cond + [(eq? rtype 'string) (to-string s)] + [(eq? rtype 'integer) + (let ([n (string->number (to-string s))]) + (or (and n (exact-integer? n) n) + 0))] + [else + (if (string? s) + (string->bytes/utf-8 s) + s)]))) + (define-values (sub-hkey sub-entry) (extract-sub-hkey file hkey entry KEY_QUERY_VALUE #f)) - (and sub-hkey - (begin0 - (let-values ([(len type) - ;; Get size, first - (RegQueryValueExW sub-hkey sub-entry #f 0)]) - (and len - (let ([s (make-bytes len)]) - (let-values ([(len2 type2) - ;; Get value, now that we have a bytes string of the right size - (RegQueryValueExW sub-hkey sub-entry s len)]) - (and len2 - (let ([r - ;; Unmarhsal according to requested type: - (let ([s (cond - [(= type REG_SZ) - (cast s _pointer _string/utf-16)] - [(= type REG_DWORD) - (number->string (ptr-ref s _DWORD))] - [else - s])] - [to-string (lambda (s) - (if (bytes? s) - (bytes->string/utf-8 s #\?) - s))]) - (cond - [(eq? rtype 'string) (to-string s)] - [(eq? rtype 'integer) - (let ([n (string->number (to-string s))]) - (or (and n (exact-integer? n) n) - 0))] - [else - (if (string? s) - (string->bytes/utf-8 s) - s)]))]) - (if (box? value) - (begin - (set-box! value r) - #t) - r))))))) - (unless (eq? hkey sub-hkey) - (RegCloseKey sub-hkey))))) + (cond + [sub-hkey + (begin0 + (let-values ([(len type) + ;; Get size, first + (RegQueryValueExW sub-hkey sub-entry #f 0)]) + (and len + (let ([s (make-bytes len)]) + (let-values ([(len2 type2) + ;; Get value, now that we have a bytes string of the right size + (RegQueryValueExW sub-hkey sub-entry s len)]) + (and len2 + (let ([r + ;; Unmarhsal according to requested type: + (let ([s (cond + [(= type REG_SZ) + (cast s _pointer _string/utf-16)] + [(= type REG_DWORD) + (number->string (ptr-ref s _DWORD))] + [else + s])]) + (to-rtype s))]) + (if (box? value) + (begin + (set-box! value r) + #t) + r))))))) + (unless (eq? hkey sub-hkey) + (RegCloseKey sub-hkey)))] + [(eq? 'windows (system-type)) + (let* ([SIZE 1024] + [dest (make-bytes (* SIZE 2) 0)] + [DEFAULT "$$default"] + [len (GetPrivateProfileStringW section entry DEFAULT + dest SIZE + (file->ini file))]) + (let ([s (cast dest _pointer _string/utf-16)]) + (and (not (equal? s DEFAULT)) + (let ([r (to-rtype s)]) + (if value + (begin + (set-box! value r) + #t) + r)))))] + [else #f])) (define (write-resource section entry value [file #f] #:type [type 'string] @@ -181,38 +228,44 @@ (unless (memq type '(string bytes dword)) (raise-type-error 'write-resource "'string, 'bytes, or 'dword" type)) + (define (to-string value) + (cond + [(exact-integer? value) (number->string value)] + [(string? value) value] + [else (bytes->string/utf-8 value #\?)])) + (define-values (sub-hkey sub-entry) (extract-sub-hkey file hkey entry KEY_SET_VALUE create-key?)) - (and sub-hkey - (begin0 - (let ([v (case type - [(string) - (to-utf-16 - (cond - [(exact-integer? value) (number->string value)] - [(string? value) value] - [else (bytes->string/utf-8 value #\?)]))] - [(bytes) - (cond - [(exact-integer? value) - (string->bytes/utf-8 (number->string value))] - [(string? value) (string->bytes/utf-8 value)] - [else value])] - [(dword) - (to-dword-ptr - (cond - [(exact-integer? value) value] - [(string? value) (string->number value)] - [(bytes? value) - (string->number (bytes->string/utf-8 value #\?))]))])] - [ty (case type - [(string) REG_SZ] - [(bytes) REG_BINARY] - [(dword) REG_DWORD])]) - (RegSetValueExW sub-hkey sub-entry ty v (bytes-length v))) - (unless (eq? hkey sub-hkey) - (RegCloseKey sub-hkey))))) + (cond + [sub-hkey + (begin0 + (let ([v (case type + [(string) + (to-utf-16 (to-string value))] + [(bytes) + (cond + [(exact-integer? value) + (string->bytes/utf-8 (number->string value))] + [(string? value) (string->bytes/utf-8 value)] + [else value])] + [(dword) + (to-dword-ptr + (cond + [(exact-integer? value) value] + [(string? value) (string->number value)] + [(bytes? value) + (string->number (bytes->string/utf-8 value #\?))]))])] + [ty (case type + [(string) REG_SZ] + [(bytes) REG_BINARY] + [(dword) REG_DWORD])]) + (RegSetValueExW sub-hkey sub-entry ty v (bytes-length v))) + (unless (eq? hkey sub-hkey) + (RegCloseKey sub-hkey)))] + [(eq? 'windows (system-type)) + (WritePrivateProfileStringW section entry (to-string value) (file->ini file))] + [else #f])) (define (to-utf-16 s) (let ([v (malloc _gcpointer)]) diff --git a/collects/file/scribblings/resource.scrbl b/collects/file/scribblings/resource.scrbl index ff290dce1b..e0c1b3e5ae 100644 --- a/collects/file/scribblings/resource.scrbl +++ b/collects/file/scribblings/resource.scrbl @@ -2,14 +2,19 @@ @(require "common.ss" (for-label file/resource)) -@(define-syntax-rule (compat section indexed-racket) +@(define-syntax-rule (compat file section indexed-racket what) @elem{For backward compatibilty, the - result is @racket[#f] for platforms other than Windows, when - @racket[file] is not @racket[#f], or when @racket[section] is not + result is @racket[#f] for platforms other than Windows. The registry + is @|what| when + @racket[file] is @racket[#f] and when @racket[section] is @indexed-racket["HKEY_CLASSES_ROOT"], @indexed-racket["HKEY_CURRENT_CONFIG"], @indexed-racket["HKEY_CURRENT_USER"], - @indexed-racket["HKEY_LOCAL_MACHINE"], or @indexed-racket["HKEY_USERS"].}) + @indexed-racket["HKEY_LOCAL_MACHINE"], or @indexed-racket["HKEY_USERS"]. + When @racket[file] is @racket[#f] and @racket[section] is not one of + the special registry strings, then + @racket[(build-path (find-system-path 'home-dir) "mred.ini")] + is @|what|.}) @title[#:tag "resource"]{Windows Registry} @@ -22,7 +27,8 @@ [#:type type (or/c 'string 'bytes 'integer) _derived-from-value-box]) (or/c #f string? bytes? exact-integer? #t)]{ -Gets a value from the Windows registry. @compat[section indexed-racket] +Gets a value from the Windows registry or an @filepath{.ini} + file. @compat[file section indexed-racket "read"] The resource value is keyed on the combination of @racket[section] and @racket[entry]. The result is @racket[#f] if no value is found for @@ -31,7 +37,7 @@ The resource value is keyed on the combination of @racket[section] and box is filled with the value; when @racket[value-box] is @racket[#f], the result is the found value. -The @racket[type] argument determines how a value in the registry is +The @racket[type] argument determines how a value in the resource is converted to a Racket value. If @racket[value-box] is a box, then the default @racket[type] is derived from the initial box content, otherwise the default @racket[type] is @racket['string]. @@ -40,11 +46,12 @@ Registry values of any format can be extracted. Values using the registry format @tt{REG_SZ} are treated as strings, and values with the format @tt{REG_DWORD} are treated as 32-bit signed integers. All other formats are treated as raw bytes. Data from the registry is - converted to the requested type @racket[type]: + converted to the requested @racket[type] as follows: @itemlist[ - @item{A @tt{REG_SZ} registry value is converted to an integer using + @item{A @tt{REG_SZ} registry value + is converted to an integer using @racket[string->number] (using @racket[0] if the result is not an exact integer), and it is converted to bytes using @racket[string->bytes/utf-8].} @@ -59,9 +66,12 @@ Registry values of any format can be extracted. Values using the ] -To get the ``default'' value for an entry, use a trailing backslash. For -example, the following expression gets a command line for starting a -browser: +Resources from @filepath{.ini} files are always strings, and are +converted like @tt{REG_SZ} registry values. + +To get the ``default'' value for a registry entry, use a trailing +backslash. For example, the following expression gets a command line +for starting a browser: @racketblock[ (get-resource "HKEY_CLASSES_ROOT" @@ -76,17 +86,22 @@ browser: [#:create-key? create-key? any/c #f]) boolean?]{ -Write a value to the Windows registry. @compat[section racket] +Write a value to the Windows registry or an @filepath{.ini} + file. @compat[file section racket "written"] The resource value is keyed on the combination of @racket[section] and - @racket[entry]. If @racket[create-key?] is false, the resource entry - must already exist, otherwise the write fails. The result is - @racket[#f] if the write fails or @racket[#t] if it succeeds. + @racket[entry]. If @racket[create-key?] is false when writing to the + registry, the resource entry must already exist, otherwise the write + fails. The result is @racket[#f] if the write fails or @racket[#t] if + it succeeds. -The @racket[type] argument determines the format of the value in the +The @racket[type] argument determines the format of the value written to the registry: @racket['string] writes using the @tt{REG_SZ} format, @racket['bytes] writes using the @tt{REG_BINARY} format, and @racket['dword] writes using the @tt{REG_DWORD} format. Any kind of @racket[value] can be converted for any kind of @racket[type] using - the inverse of the conversions for @racket[get-resource].} + the inverse of the conversions for @racket[get-resource]. + +When writing to an @filepath{.ini} file, the format is always a + string, independent of @racket[type].} diff --git a/collects/tests/racket/resource.rktl b/collects/tests/racket/resource.rktl index 7f6a77da8e..cbbe765bd8 100644 --- a/collects/tests/racket/resource.rktl +++ b/collects/tests/racket/resource.rktl @@ -6,7 +6,8 @@ (Section 'resource) -(require file/resource) +(require file/resource + racket/file) (let () (define key "HKEY_CURRENT_USER") @@ -52,8 +53,18 @@ (rtest #"i\377mage" get-resource key (entry "Data") #:type 'bytes) (rtest 0 get-resource key (entry "Data") #:type 'integer) + ;; .ini file: + (let ([tmp-ini (make-temporary-file "temp~a.ini")]) + (rtest #f get-resource "Temporary" "Stuff" #f tmp-ini) + (rtest #t write-resource "Temporary" "Stuff" "howdy" tmp-ini) + (rtest "howdy" get-resource "Temporary" "Stuff" #f tmp-ini) + (rtest #f get-resource "Temporary" "more" #f tmp-ini) + (rtest #t write-resource "Temporary" "more" 10 tmp-ini) + (rtest 10 get-resource "Temporary" "more" #f tmp-ini #:type 'integer) + (when (eq? 'windows (system-type)) + (test "[Temporary]\r\nStuff=howdy\r\nmore=10\r\n" file->string tmp-ini) + (delete-file tmp-ini))) + (void)) (report-errs) - - From 745e5018fd10c82a60a335aa12cf648b7c2888c3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Feb 2011 08:32:33 -0700 Subject: [PATCH 128/746] fix coverage of `file/resource' tests (cherry picked from commit 3c4807f032ca63b4804f6dc4a4aa498085b6291d) --- collects/tests/racket/resource.rktl | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/collects/tests/racket/resource.rktl b/collects/tests/racket/resource.rktl index cbbe765bd8..a055ccd975 100644 --- a/collects/tests/racket/resource.rktl +++ b/collects/tests/racket/resource.rktl @@ -38,10 +38,18 @@ (let ([b (box 10)]) (rtest #t get-resource key (entry "Stuff") b) (xtest 0 10 unbox b)) - + (rtest #t write-resource key (entry "Stuff") 88) + (rtest "88" get-resource key (entry "Stuff")) + (rtest #t write-resource key (entry "Stuff") #"!") + (rtest "!" get-resource key (entry "Stuff")) + ;; An integer-valued resource (rtest #t write-resource key (entry "Count") 17 #:type 'dword) (rtest "17" get-resource key (entry "Count")) + (rtest #t write-resource key (entry "Count") "17" #:type 'dword) + (rtest "17" get-resource key (entry "Count")) + (rtest #t write-resource key (entry "Count") #"17" #:type 'dword) + (rtest "17" get-resource key (entry "Count")) (rtest #"17" get-resource key (entry "Count") #:type 'bytes) (rtest 17 get-resource key (entry "Count") #:type 'integer) (rtest #t write-resource key (entry "Count") -17 #:type 'dword) @@ -52,17 +60,24 @@ (rtest "i?mage" get-resource key (entry "Data")) (rtest #"i\377mage" get-resource key (entry "Data") #:type 'bytes) (rtest 0 get-resource key (entry "Data") #:type 'integer) + (rtest #t write-resource key (entry "Data") 17 #:type 'bytes) + (rtest "17" get-resource key (entry "Data")) + (rtest #t write-resource key (entry "Data") "17" #:type 'bytes) + (rtest "17" get-resource key (entry "Data")) ;; .ini file: (let ([tmp-ini (make-temporary-file "temp~a.ini")]) (rtest #f get-resource "Temporary" "Stuff" #f tmp-ini) (rtest #t write-resource "Temporary" "Stuff" "howdy" tmp-ini) (rtest "howdy" get-resource "Temporary" "Stuff" #f tmp-ini) + (let ([b (box "")]) + (rtest #t get-resource "Temporary" "Stuff" b tmp-ini) + (xtest "howdy" "" unbox b)) (rtest #f get-resource "Temporary" "more" #f tmp-ini) (rtest #t write-resource "Temporary" "more" 10 tmp-ini) (rtest 10 get-resource "Temporary" "more" #f tmp-ini #:type 'integer) (when (eq? 'windows (system-type)) - (test "[Temporary]\r\nStuff=howdy\r\nmore=10\r\n" file->string tmp-ini) + (rtest "[Temporary]\r\nStuff=howdy\r\nmore=10\r\n" file->string tmp-ini) (delete-file tmp-ini))) (void)) From ca1e603f7f0a8e8d4a758e29727268073bc433b1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 4 Feb 2011 13:33:37 -0700 Subject: [PATCH 129/746] adjust `racket/gui/base' to re-export `file/resource' Merge to 5.1 along with b4ce4bb, 3375005, 18eb7c8, 3c4807f (cherry picked from commit 5eeec97878e2491688514f03fe3898f6ea4dd933) --- collects/mred/mred-sig.rkt | 2 ++ collects/mred/private/mred.rkt | 4 +++- collects/scribblings/gui/gui.scrbl | 3 ++- doc/release-notes/racket/Draw_and_GUI_5_1.txt | 15 ++++++++++++--- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/collects/mred/mred-sig.rkt b/collects/mred/mred-sig.rkt index fc8dec478b..ffee140991 100644 --- a/collects/mred/mred-sig.rkt +++ b/collects/mred/mred-sig.rkt @@ -91,6 +91,7 @@ get-panel-background get-ps-setup-from-user get-highlight-background-color get-highlight-text-color +get-resource get-text-from-user get-the-editor-data-class-list get-the-snip-class-list @@ -210,4 +211,5 @@ window<%> write-editor-global-footer write-editor-global-header write-editor-version +write-resource yield diff --git a/collects/mred/private/mred.rkt b/collects/mred/private/mred.rkt index 72594f600c..889008b6d4 100644 --- a/collects/mred/private/mred.rkt +++ b/collects/mred/private/mred.rkt @@ -5,6 +5,7 @@ make-base-empty-namespace) scheme/class racket/draw racket/snip + file/resource mzlib/etc (prefix wx: "kernel.ss") (prefix wx: "wxme/editor.ss") @@ -169,7 +170,8 @@ [else #f]))) (provide (all-from racket/draw) - (all-from racket/snip)) + (all-from racket/snip) + (all-from file/resource)) (provide button% canvas% diff --git a/collects/scribblings/gui/gui.scrbl b/collects/scribblings/gui/gui.scrbl index 4321754b77..177cb15986 100644 --- a/collects/scribblings/gui/gui.scrbl +++ b/collects/scribblings/gui/gui.scrbl @@ -10,7 +10,8 @@ @defmodule*/no-declare[(racket/gui/base)]{The @racketmodname[racket/gui/base] library provides all of the class, interface, and procedure bindings defined in this manual, in addition -to the bindings of @racketmodname[racket/draw].} +to the bindings of @racketmodname[racket/draw] and +@racketmodname[file/resource].} @defmodulelang*/no-declare[(racket/gui)]{The @racketmodname[racket/gui] language combines all bindings of the diff --git a/doc/release-notes/racket/Draw_and_GUI_5_1.txt b/doc/release-notes/racket/Draw_and_GUI_5_1.txt index d44cc4d9ab..fec9eab2b6 100644 --- a/doc/release-notes/racket/Draw_and_GUI_5_1.txt +++ b/doc/release-notes/racket/Draw_and_GUI_5_1.txt @@ -156,12 +156,21 @@ jump-defeating `dynamic-wind' that formerly guarded callbacks has been removed. +Registry Functions +----------------- + +The `get-resource' and `write-resource' functions have moved to a +`file/resource' library that is re-exported by `racket/gui/base'. +These function now work only for reading and writing the Windows +registry; they report failure for other platforms and modes. + + Removed Functions ----------------- -The `write-resource, `get-reource', and `send-event' functions have -been removed from `racket/gui/base'. If there is any demand for the -removed functionality, it will be implemented in a new library. +The `send-event' function has been removed from `racket/gui/base'. If +there is any demand for the removed functionality, it will be +implemented in a new library. The `current-ps-afm-file-paths' and `current-ps-cmap-file-paths' functions have been removed, because they no longer apply. PostScript From 4c20048bff3533b89a2011eb5c90940c9e1e32c9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Feb 2011 14:11:30 -0700 Subject: [PATCH 130/746] minor correction to release notes Merge to 5.1 (cherry picked from commit ead1c366d19eefb7b2489a062e18e8c410242ef0) --- doc/release-notes/racket/Draw_and_GUI_5_1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes/racket/Draw_and_GUI_5_1.txt b/doc/release-notes/racket/Draw_and_GUI_5_1.txt index fec9eab2b6..63c19627ee 100644 --- a/doc/release-notes/racket/Draw_and_GUI_5_1.txt +++ b/doc/release-notes/racket/Draw_and_GUI_5_1.txt @@ -162,7 +162,7 @@ Registry Functions The `get-resource' and `write-resource' functions have moved to a `file/resource' library that is re-exported by `racket/gui/base'. These function now work only for reading and writing the Windows -registry; they report failure for other platforms and modes. +registry or ".ini" files; they report failure for other platforms. Removed Functions From 17157945bb417652840e94deba5bea4a2f1b3cb0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Feb 2011 16:33:02 -0700 Subject: [PATCH 131/746] fix scheduler's support for `ffi/unsafe/try-atomic' where problems with abort-without-dynamic-wind mode caused a spurious trigger of nack evts Merge to 5.1 (cherry picked from commit 3e38071dae88590befcb46ef953e123447af5e3f) --- src/racket/include/scheme.h | 5 ++++- src/racket/src/sema.c | 3 ++- src/racket/src/thread.c | 11 +++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/racket/include/scheme.h b/src/racket/include/scheme.h index 58e50d815d..60d500d28c 100644 --- a/src/racket/include/scheme.h +++ b/src/racket/include/scheme.h @@ -1155,7 +1155,10 @@ typedef void (*Scheme_Kill_Action_Func)(void *); thread = NULL; \ if (scheme_setjmp(newbuf)) { \ scheme_pop_kill_action(); \ - func(data); \ + thread = scheme_get_current_thread(); \ + if (!thread->cjs.skip_dws) { \ + func(data); \ + } \ scheme_longjmp(*savebuf, 1); \ } else { # define END_ESCAPEABLE() \ diff --git a/src/racket/src/sema.c b/src/racket/src/sema.c index 37cab3e519..0953a3117e 100644 --- a/src/racket/src/sema.c +++ b/src/racket/src/sema.c @@ -654,7 +654,8 @@ int scheme_wait_semas_chs(int n, Scheme_Object **o, int just_try, Syncing *synci } else if (semas[i]->so.type == scheme_never_evt_type) { /* Never ready. */ } else if (semas[i]->so.type == scheme_channel_syncer_type) { - /* Probably no need to poll */ + if (((Scheme_Channel_Syncer *)semas[i])->picked) + break; } else if (try_channel(semas[i], syncing, i, NULL)) break; } diff --git a/src/racket/src/thread.c b/src/racket/src/thread.c index 85697facc9..988507af57 100644 --- a/src/racket/src/thread.c +++ b/src/racket/src/thread.c @@ -4051,6 +4051,9 @@ static void call_on_atomic_timeout(int must) Scheme_Object *blocker; Scheme_Ready_Fun block_check; Scheme_Needs_Wakeup_Fun block_needs_wakeup; + Scheme_Kill_Action_Func private_on_kill; + void *private_kill_data; + void **private_kill_next; /* Save any state that has to do with the thread blocking or sleeping, in case scheme_on_atomic_timeout() runs Racket code. */ @@ -4062,6 +4065,10 @@ static void call_on_atomic_timeout(int must) block_check = p->block_check; block_needs_wakeup = p->block_needs_wakeup; + private_on_kill = p->private_on_kill; + private_kill_data = p->private_kill_data; + private_kill_next = p->private_kill_next; + p->running = MZTHREAD_RUNNING; p->sleep_end = 0.0; p->block_descriptor = 0; @@ -4077,6 +4084,10 @@ static void call_on_atomic_timeout(int must) p->blocker = blocker; p->block_check = block_check; p->block_needs_wakeup = block_needs_wakeup; + + p->private_on_kill = private_on_kill; + p->private_kill_data = private_kill_data; + p->private_kill_next = private_kill_next; } static void find_next_thread(Scheme_Thread **return_arg) { From abb10d86c0f71d5294e35fb106d35549ca5a2faa Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Feb 2011 16:36:05 -0700 Subject: [PATCH 132/746] Adjust FrTime mailbox implementation to use `thread-{receive,send}' instead of async channels. This change allows Fred to work. The change is needed due to implementation weaknesses at multiple levels, but mostly because `on-subwindow-event' has to complete atomically --- or else events are pessimistically discarded, and async-channel communication never completes atomically. In contrast, messages can be posted to the built-in message queue for a thread (because it's built in). Probably the async-channel library should switch to using the built-in thread queue support. Merge to 5.1 (cherry picked from commit 3c6652b83c278321f7e9c5f881977bb9f0906f11) --- collects/frtime/core/mailbox.rkt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/collects/frtime/core/mailbox.rkt b/collects/frtime/core/mailbox.rkt index 24bafaa750..14026afe22 100644 --- a/collects/frtime/core/mailbox.rkt +++ b/collects/frtime/core/mailbox.rkt @@ -7,10 +7,12 @@ (define (snoc x l) (append l (list x))) ; Define mailboxes -(define-struct mailbox (manager control msgs)) +(define-struct mailbox (manager control)) (define (new-mailbox) (define control-ch (make-channel)) - (define msgs-ch (make-async-channel)) + (define (thread-recv-evt) + (handle-evt (thread-receive-evt) + (lambda (e) (thread-receive)))) ; Try to match one message (define (try-to-match req msg) (match req @@ -32,7 +34,7 @@ (list* msg (try-to-match* req msgs)))])) ; Accept new messages until we need to match one (define (not-on-receive msgs) - (sync (handle-evt msgs-ch + (sync (handle-evt (thread-recv-evt) (lambda (new-msg) (not-on-receive (snoc new-msg msgs)))) (handle-evt control-ch @@ -51,7 +53,7 @@ [(not timeout) false] [(> elapsed timeout) 0] [else (/ (- timeout elapsed) 1000.0)])) - (define new-msg (sync/timeout wait-time msgs-ch)) + (define new-msg (sync/timeout wait-time (thread-recv-evt))) (if new-msg (if (try-to-match req new-msg) (not-on-receive msgs) @@ -63,17 +65,17 @@ (thread (lambda () (not-on-receive empty)))) - (make-mailbox manager control-ch msgs-ch)) + (make-mailbox manager control-ch)) (define-struct receive (reply-ch timeout timeout-thunk matcher)) (define (mailbox-send! mb msg) (match mb - [(struct mailbox (thd _ msgs)) + [(struct mailbox (thd _)) (thread-resume thd) - (async-channel-put msgs msg)])) + (thread-send thd msg)])) (define (mailbox-receive mb timeout timeout-thunk matcher) (match mb - [(struct mailbox (thd control _)) + [(struct mailbox (thd control)) (define reply-ch (make-channel)) (thread-resume thd) (channel-put control (make-receive reply-ch timeout timeout-thunk matcher)) From 74b9465b4e1170ca8f63bfeedc6fa9d360ed9728 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Feb 2011 16:48:04 -0700 Subject: [PATCH 133/746] document limitations of `on-subwindow-event' and `on-subwindow-char' Merge to 5.1 (cherry picked from commit e2a0fd02ef89da7d8efbfe26739ca82d8a42c7ad) --- collects/scribblings/gui/window-intf.scrbl | 18 +++++++++++++++--- doc/release-notes/racket/Draw_and_GUI_5_1.txt | 5 +++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/collects/scribblings/gui/window-intf.scrbl b/collects/scribblings/gui/window-intf.scrbl index 3c3645b89f..17318469af 100644 --- a/collects/scribblings/gui/window-intf.scrbl +++ b/collects/scribblings/gui/window-intf.scrbl @@ -374,6 +374,14 @@ Called when this window or a child window receives a keyboard event. @method[window<%> on-subwindow-char] method returns @scheme[#f], the event is passed on to the receiver's normal key-handling mechanism. +The @scheme[event] argument is the event that was generated for the + @scheme[receiver] window. + +The atomicity limitation @method[window<%> on-subwindow-event] applies + to @method[window<%> on-subwindow-char] as well. That is, an insufficiently cooperative + @method[window<%> on-subwindow-char] method can effectively disable + a control's handling of key events, even when it returns @racket[#f] + BEWARE: The default @xmethod[frame% on-subwindow-char] and @xmethod[dialog% on-subwindow-char] methods consume certain keyboard events (e.g., arrow keys, Enter) used @@ -382,9 +390,6 @@ BEWARE: The default reach the ``receiver'' child unless the default frame or dialog method is overridden. -The @scheme[event] argument is the event that was generated for the - @scheme[receiver] window. - } @methimpl{ @@ -409,6 +414,13 @@ Called when this window or a child window receives a mouse event. The @scheme[event] argument is the event that was generated for the @scheme[receiver] window. +If the @method[window<%> on-subwindow-event] method chain does not complete + atomically (i.e., without requiring other threads to run) or does not complete + fast enough, then the corresponding event may not be delivered to a target + control, such as a button. In other words, an insufficiently cooperative + @method[window<%> on-subwindow-event] method can effectively disable a + control's handling of mouse events, even when it returns @racket[#f]. + } @methimpl{ diff --git a/doc/release-notes/racket/Draw_and_GUI_5_1.txt b/doc/release-notes/racket/Draw_and_GUI_5_1.txt index 63c19627ee..128f037bd4 100644 --- a/doc/release-notes/racket/Draw_and_GUI_5_1.txt +++ b/doc/release-notes/racket/Draw_and_GUI_5_1.txt @@ -155,6 +155,11 @@ callbacks or outside of an even callback. The continuation barrier and jump-defeating `dynamic-wind' that formerly guarded callbacks has been removed. +The `on-subwindow-char' and `on-subwindow-event' methods for controls +are somewhat more restructed in the actions they can take without +disabling the control's handling of key and mouse events. See the +documentation for more information. + Registry Functions ----------------- From 98313114922b2d4d7848bfed5292e86c08db75a7 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 6 Feb 2011 07:24:19 -0600 Subject: [PATCH 134/746] 2htdp/image: place-image/align doesn't really need to check that the second image argument has a pinhole (cherry picked from commit eb45a6f15b5ab6d013bed62041ecd7240d561fb3) --- collects/2htdp/private/image-more.rkt | 5 ++--- collects/2htdp/tests/test-image.rkt | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/collects/2htdp/private/image-more.rkt b/collects/2htdp/private/image-more.rkt index 0473b17dd1..f6b16c5c18 100644 --- a/collects/2htdp/private/image-more.rkt +++ b/collects/2htdp/private/image-more.rkt @@ -382,9 +382,8 @@ (define/chk (place-image/align image1 x1 y1 x-place y-place image2) (when (or (eq? x-place 'pinhole) (eq? y-place 'pinhole)) (check-dependencies 'place-image/align - (and (send image1 get-pinhole) - (send image2 get-pinhole)) - "when x-place or y-place is ~e or ~e, then both of the image arguments must have pinholes" + (send image1 get-pinhole) + "when x-place or y-place is ~e or ~e, the the first image argument must have a pinhole" 'pinhole "pinhole")) (place-image/internal image1 x1 y1 image2 x-place y-place)) diff --git a/collects/2htdp/tests/test-image.rkt b/collects/2htdp/tests/test-image.rkt index 1973616d66..7a63fedd59 100644 --- a/collects/2htdp/tests/test-image.rkt +++ b/collects/2htdp/tests/test-image.rkt @@ -1891,6 +1891,17 @@ 0 0 "center" "center" (rectangle 10 100 'solid 'blue))) +(test (clear-pinhole + (place-image/align + (center-pinhole (rectangle 100 10 'solid 'red)) + 0 0 "pinhole" "pinhole" + (rectangle 10 100 'solid 'blue))) + => + (place-image/align + (rectangle 100 10 'solid 'red) + 0 0 "center" "center" + (rectangle 10 100 'solid 'blue))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; test errors. @@ -2030,18 +2041,7 @@ => #rx"^underlay/align") -(test/exn (place-image/align - (center-pinhole (rectangle 10 100 'solid 'blue)) - 0 0 "pinhole" "center" - (rectangle 100 10 'solid 'red)) - => - #rx"^place-image/align") -(test/exn (place-image/align - (center-pinhole (rectangle 10 100 'solid 'blue)) - 0 0 "center" "pinhole" - (rectangle 100 10 'solid 'red)) - => - #rx"^place-image/align") + (test/exn (place-image/align (rectangle 100 10 'solid 'red) 0 0 "pinhole" "center" From f7f0faf83fe0f4b1d89c916d39bd1df3fb029efc Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Tue, 8 Feb 2011 13:07:35 -0500 Subject: [PATCH 135/746] update history (cherry picked from commit e71ccdac3899c22bba3a49fcec0f0344a5ab4db3) --- doc/release-notes/teachpack/HISTORY.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/release-notes/teachpack/HISTORY.txt b/doc/release-notes/teachpack/HISTORY.txt index 3c864c20f3..8eaff4b18f 100644 --- a/doc/release-notes/teachpack/HISTORY.txt +++ b/doc/release-notes/teachpack/HISTORY.txt @@ -1,3 +1,9 @@ +------------------------------------------------------------------------ +Version 5.1 [Tue Feb 8 13:05:17 EST 2011] + +* to-draw (old name: on-draw) is now required for big-bang expressions +* bug fixes in world, image, etc + ------------------------------------------------------------------------ Version 5.0.2. [Wed Oct 27 18:30:26 EDT 2010] From 79760264e7d11e852f898088926b6ff04f5fa2c1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Feb 2011 07:41:19 -0700 Subject: [PATCH 136/746] gtk: fix X selection for older Gtk versions Merge to 5.1 (cherry picked from commit f21f0bdba2af7282b747e858d81379135a5189a9) --- collects/mred/private/wx/gtk/clipboard.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/mred/private/wx/gtk/clipboard.rkt b/collects/mred/private/wx/gtk/clipboard.rkt index 22264bdf3b..c049a012b1 100644 --- a/collects/mred/private/wx/gtk/clipboard.rkt +++ b/collects/mred/private/wx/gtk/clipboard.rkt @@ -25,7 +25,6 @@ (define _GtkClipboard (_cpointer 'GtkClipboard)) (define _GtkDisplay _pointer) -(define _GtkSelectionData (_cpointer 'GtkSelectionData)) ;; Recent versions of Gtk provide function calls to ;; access data, but use structure when the functions are @@ -38,6 +37,7 @@ [length _int] [display _GtkDisplay])) +(define _GtkSelectionData _GtkSelectionDataT-pointer) (define-gdk gdk_atom_intern (_fun _string _gboolean -> _GdkAtom)) From 98dd05c6d32f4599b0908d393baa974f69792df5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Feb 2011 09:01:22 -0700 Subject: [PATCH 137/746] fix `set-icon' in frame% to make mask argument optional Merge to 5.1 (cherry picked from commit f4a881f0e37f291c604ae40ab52d2e36ca411609) --- collects/mred/private/wx/cocoa/frame.rkt | 2 +- collects/mred/private/wx/gtk/frame.rkt | 2 +- collects/mred/private/wx/win32/frame.rkt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/mred/private/wx/cocoa/frame.rkt b/collects/mred/private/wx/cocoa/frame.rkt index c70d89d277..c6d31f78f9 100644 --- a/collects/mred/private/wx/cocoa/frame.rkt +++ b/collects/mred/private/wx/cocoa/frame.rkt @@ -549,7 +549,7 @@ (define/public (on-activate on?) (void)) - (define/public (set-icon bm1 bm2 [mode 'both]) (void)) ;; FIXME + (define/public (set-icon bm1 [bm2 #f] [mode 'both]) (void)) ;; FIXME (define/override (call-pre-on-event w e) (pre-on-event w e)) diff --git a/collects/mred/private/wx/gtk/frame.rkt b/collects/mred/private/wx/gtk/frame.rkt index 8c43cf8e9e..d91223e21e 100644 --- a/collects/mred/private/wx/gtk/frame.rkt +++ b/collects/mred/private/wx/gtk/frame.rkt @@ -334,7 +334,7 @@ (define big-icon #f) (define small-icon #f) - (define/public (set-icon bm mask [mode 'both]) + (define/public (set-icon bm [mask #f] [mode 'both]) (let ([bm (if mask (let* ([nbm (make-object bitmap% (send bm get-width) diff --git a/collects/mred/private/wx/win32/frame.rkt b/collects/mred/private/wx/win32/frame.rkt index 712f5ffd4a..8a32696d8f 100644 --- a/collects/mred/private/wx/win32/frame.rkt +++ b/collects/mred/private/wx/win32/frame.rkt @@ -527,7 +527,7 @@ (define small-hicon #f) (define big-hicon #f) - (define/public (set-icon bm mask [mode 'both]) + (define/public (set-icon bm [mask #f] [mode 'both]) (let* ([bg-hbitmap (let* ([bm (make-object bitmap% (send bm get-width) (send bm get-height))] [dc (make-object bitmap-dc% bm)]) From 0707a3f95468125686756628e388dfdae2d51ef8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Feb 2011 12:23:14 -0700 Subject: [PATCH 138/746] win32: fix parent HWND of canvas% Merge to 5.1 (cherry picked from commit 6b1112a9adad14b4bb4fd49431697a493b781622) --- collects/mred/private/wx/win32/canvas.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/mred/private/wx/win32/canvas.rkt b/collects/mred/private/wx/win32/canvas.rkt index 0c5ddba9e9..a6723720ab 100644 --- a/collects/mred/private/wx/win32/canvas.rkt +++ b/collects/mred/private/wx/win32/canvas.rkt @@ -116,7 +116,7 @@ (if hscroll? WS_HSCROLL 0) (if vscroll? WS_VSCROLL 0)) 0 0 w h - (or panel-hwnd (send parent get-hwnd)) + (or panel-hwnd (send parent get-client-hwnd)) #f hInstance #f)) From aeedcef3a3a97c21622b5bb0f1f30cfb457c685d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Feb 2011 12:42:36 -0700 Subject: [PATCH 139/746] fix s:home keybinding Merge to 5.1 (cherry picked from commit 33db7b1229e4be54c3ef0cf06eef86761c70a623) --- collects/framework/private/keymap.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/framework/private/keymap.rkt b/collects/framework/private/keymap.rkt index ab94d1bdfa..54fca114a7 100644 --- a/collects/framework/private/keymap.rkt +++ b/collects/framework/private/keymap.rkt @@ -1127,7 +1127,7 @@ (add "make-read-only" make-read-only) (add "beginning-of-line" beginning-of-line) - (add "selec-to-beginning-of-line" select-to-beginning-of-line) + (add "select-to-beginning-of-line" select-to-beginning-of-line) ; Map keys to functions From 672ac1970a0c890b822179ccb074d0a72c79b5b7 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 8 Feb 2011 11:48:37 -0500 Subject: [PATCH 140/746] Improve the apache rewrite instructions. Specifically, mention the `NE' flag and point at the apache "current" version of the page. (cherry picked from commit 42eb0a9e88a668c29aab75712c90003c2868518c) --- .../web-server/scribblings/server-faq.scrbl | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/collects/web-server/scribblings/server-faq.scrbl b/collects/web-server/scribblings/server-faq.scrbl index 153e5b8cd5..0b71be07fa 100644 --- a/collects/web-server/scribblings/server-faq.scrbl +++ b/collects/web-server/scribblings/server-faq.scrbl @@ -6,37 +6,48 @@ @section{How do I use Apache with the Racket Web Server?} -You may want to put Apache in front of your Racket Web Server application. -Apache can rewrite and proxy requests for a private (or public) Racket Web Server: +You may want to put Apache in front of your Racket Web Server +application. Apache can rewrite and proxy requests for a private (or +public) Racket Web Server: @verbatim{ -RewriteRule ^(.*)$ http://localhost:8080/$1 [P] + RewriteEngine on + RewriteRule ^(.*)$ http://localhost:8080/$1 [P,NE] } -The first argument to @exec{RewriteRule} is a match pattern. The second is how to rewrite the URL. -The @exec{[P]} flag instructs Apache to proxy the request. If you do not include this, Apache will -return an HTTP Redirect response and the client should make a second request. +The first argument to @exec{RewriteRule} is a match pattern. The second +is how to rewrite the URL. The bracketed part contains flags that +specify the type of rewrite, in this case the @litchar{P} flag instructs +Apache to proxy the request. (If you do not include this, Apache will +return an HTTP Redirect response and the client will make a second +request to @litchar{localhost:8080} which will not work on a different +machine.) In addition, the @litchar{NE} flag is needed to avoid +escaping parts of the URL --- without it, a @litchar{;} is escaped as +@litchar{%3B} which will break the proxied request. -See Apache's documentation for more details on @link["http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewriterule"]{RewriteRule}. +See Apache's documentation for more details on +@link["http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule"]{RewriteRule}. @section{Can the server create a PID file?} -The server has no option for this, but you can add it very easily. There's two techniques. +The server has no option for this, but you can add it very +easily. There's two techniques. First, if you use a UNIX platform, in your shell startup script you can use @verbatim{ -echo $$ > PID -exec run-web-server + echo $$ > PID + exec run-web-server } -Using @exec{exec} will reuse the same process, and therefore, the PID file will be accurate. +Using @exec{exec} will reuse the same process, and therefore, the PID +file will be accurate. Second, if you want to make your own Racket start-up script, you can write: @(require (for-label mzlib/os)) @racketblock[ -(require mzlib/os) -(with-output-to-file _your-pid-file (lambda () (write (getpid)))) -(_start-server) + (require mzlib/os) + (with-output-to-file _your-pid-file (lambda () (write (getpid)))) + (_start-server) ] @section[#:tag "faq:https"]{How do I set up the server to use HTTPS?} From e61034cc0b353a2c6eeddb063bbdad634802b4e8 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 10 Feb 2011 14:20:15 -0500 Subject: [PATCH 141/746] Don't assume that the user sexpr is a list. Fixes PR 11718 (cherry picked from commit 4b1960e1f07f58a6be12b172c3bbaf994a2d4e0c) --- collects/racket/private/misc.rkt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/collects/racket/private/misc.rkt b/collects/racket/private/misc.rkt index 916c07620d..26aba931c1 100644 --- a/collects/racket/private/misc.rkt +++ b/collects/racket/private/misc.rkt @@ -22,10 +22,17 @@ (lambda (user-stx) (syntax-case** dr #t user-stx () free-identifier=? [(_ . pattern) (syntax/loc user-stx template)] - [_ (let*-values ([(sexpr) (syntax->datum user-stx)] - [(msg) (format - "~.s did not match pattern ~.s" - sexpr (cons (car sexpr) 'pattern))]) + [_ (let*-values + ([(sexpr) (syntax->datum user-stx)] + [(msg) + (if (pair? sexpr) + (format "~.s did not match pattern ~.s" + sexpr (cons (car sexpr) 'pattern)) + (if (symbol? sexpr) + (format "must be used in a pattern ~.s" + (cons sexpr 'pattern)) + (error 'internal-error + "something bad happened")))]) (raise-syntax-error #f msg user-stx))]))))] [(_ (name . ptrn) tmpl) (err "expected an identifier" #'name)] [(_ (name . ptrn)) (err "missing template")] From c88cde60921b07c79837ca9e63333834aaecea66 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 9 Feb 2011 14:21:33 -0700 Subject: [PATCH 142/746] fix typos Merge to 5.1 (cherry picked from commit 379feaeac2ebd07b17ebc6f54d04c084171410e9) --- doc/release-notes/racket/Draw_and_GUI_5_1.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/release-notes/racket/Draw_and_GUI_5_1.txt b/doc/release-notes/racket/Draw_and_GUI_5_1.txt index 128f037bd4..75d625c27b 100644 --- a/doc/release-notes/racket/Draw_and_GUI_5_1.txt +++ b/doc/release-notes/racket/Draw_and_GUI_5_1.txt @@ -17,7 +17,7 @@ API: Racket. The GRacket executable still offers some additional GUI-specific - functiontality however. Most notably, GRacket is a GUI application + functionality however. Most notably, GRacket is a GUI application under Windows (as opposed to a console application, which is launched slightly differently by the OS), GRacket is a bundle under Mac OS X (so the dock icon is the Racket logo, for example), and @@ -91,8 +91,8 @@ The old translation and scaling transformations apply after the initial matrix. The new rotation transformation applies after the other transformations. This layering is redundant, since all transformations can be expressed in a single matrix, but it is -backward-compatibile. Methods like `get-translation', -`set-translation', `scale', etc. help hide the reundancy. +backward-compatible. Methods like `get-translation', +`set-translation', `scale', etc. help hide the redundancy. PostScript, PDF, and SVG Drawing Contexts @@ -150,13 +150,13 @@ into the control. Event callbacks are delimited by a continuation prompt using the default continuation prompt tag. As a result, continuations can be -usufully captured during one event callback and applied during other +usefully captured during one event callback and applied during other callbacks or outside of an even callback. The continuation barrier and jump-defeating `dynamic-wind' that formerly guarded callbacks has been removed. The `on-subwindow-char' and `on-subwindow-event' methods for controls -are somewhat more restructed in the actions they can take without +are somewhat more restricted in the actions they can take without disabling the control's handling of key and mouse events. See the documentation for more information. From f3e51f3d805444108821d28e464baff3730902aa Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 11 Feb 2011 10:09:15 -0500 Subject: [PATCH 143/746] Update version number for the v5.1 release --- src/racket/src/schvers.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 0d548af42c..454818538e 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.0.99.900" +#define MZSCHEME_VERSION "5.1" #define MZSCHEME_VERSION_X 5 -#define MZSCHEME_VERSION_Y 0 -#define MZSCHEME_VERSION_Z 99 -#define MZSCHEME_VERSION_W 900 +#define MZSCHEME_VERSION_Y 1 +#define MZSCHEME_VERSION_Z 0 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 30209c96917891513167238c8b2afbb23bedb26e Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 11 Feb 2011 10:17:29 -0500 Subject: [PATCH 144/746] New Racket version 5.1. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 12 ++++++------ src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index 941b5f5e49..a4f6b16489 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 8f0813a5e4..c56056a585 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,0,99,900 - PRODUCTVERSION 5,0,99,900 + FILEVERSION 5,1,0,0 + PRODUCTVERSION 5,1,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 0, 99, 900\0" + VALUE "FileVersion", "5, 1, 0, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 0, 99, 900\0" + VALUE "ProductVersion", "5, 1, 0, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 0438cdff0a..83a30602a3 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,0,99,900 - PRODUCTVERSION 5,0,99,900 + FILEVERSION 5,1,0,0 + PRODUCTVERSION 5,1,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 0, 99, 900" + VALUE "FileVersion", "5, 1, 0, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 0, 99, 900" + VALUE "ProductVersion", "5, 1, 0, 0" END END BLOCK "VarFileInfo" @@ -105,10 +105,10 @@ CAPTION "MzCOM" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,76,69,50,14,BS_CENTER - CTEXT "MzCOM v. 5.0",IDC_STATIC,71,8,61,8 + CTEXT "MzCOM v. 5.1",IDC_STATIC,71,8,61,8 CTEXT "Copyright (c) 2000-2011 PLT (Paul Steckler)",IDC_STATIC, 41,20,146,9 - CTEXT "Racket v. 5.0",IDC_STATIC,64,35,75,8 + CTEXT "Racket v. 5.1",IDC_STATIC,64,35,75,8 CTEXT "Copyright (c) 1995-2011 PLT Inc.",IDC_STATIC, 30,47,143,8 ICON MZICON,IDC_STATIC,11,16,20,20 diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index c9060e92d7..12a940f440 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.0.99.900 = s 'MzObj Class' + MzCOM.MzObj.5.1.0.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.0.99.900' + CurVer = s 'MzCOM.MzObj.5.1.0.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.0.99.900' + ProgID = s 'MzCOM.MzObj.5.1.0.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index a07b1295c6..1c115cefdb 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 5f0abe42b2..06dc6565ee 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,0,99,900 - PRODUCTVERSION 5,0,99,900 + FILEVERSION 5,1,0,0 + PRODUCTVERSION 5,1,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 0, 99, 900\0" + VALUE "FileVersion", "5, 1, 0, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 0, 99, 900\0" + VALUE "ProductVersion", "5, 1, 0, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 3774e48ce9..f5000c226d 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,0,99,900 - PRODUCTVERSION 5,0,99,900 + FILEVERSION 5,1,0,0 + PRODUCTVERSION 5,1,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 0, 99, 900\0" + VALUE "FileVersion", "5, 1, 0, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 0, 99, 900\0" + VALUE "ProductVersion", "5, 1, 0, 0\0" END END BLOCK "VarFileInfo" From e20f66ef121e06b0c85c1887de6c12390ee22eea Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 14 Feb 2011 05:48:33 -0700 Subject: [PATCH 145/746] fix A4 paper description Closes PR 11734 (cherry picked from commit 6320d3207a2760f41a2e47a8feecffd6f78aa6b0) --- collects/racket/draw/private/ps-setup.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/racket/draw/private/ps-setup.rkt b/collects/racket/draw/private/ps-setup.rkt index d07ecd53da..6a1ba170b2 100644 --- a/collects/racket/draw/private/ps-setup.rkt +++ b/collects/racket/draw/private/ps-setup.rkt @@ -17,7 +17,7 @@ get-all-numerics) (define paper-sizes - '(("A4 210 x 297\n mm" 595 842) + '(("A4 210 x 297 mm" 595 842) ("A3 297 x 420 mm" 842 1191) ("Letter 8 1/2 x 11 in" 612 791) ("Legal 8 1/2 x 14 in" 612 1009))) From 982ee1e512ea7fa4c34a56851c2a0ea6040bd203 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 14 Feb 2011 07:11:45 -0700 Subject: [PATCH 146/746] doc repair for PR 11734 follow-up (cherry picked from commit da3fd90256761bc9392ad4cf5a978100624a194f) --- collects/scribblings/draw/ps-setup-class.scrbl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/collects/scribblings/draw/ps-setup-class.scrbl b/collects/scribblings/draw/ps-setup-class.scrbl index 6f98a77657..11691458ea 100644 --- a/collects/scribblings/draw/ps-setup-class.scrbl +++ b/collects/scribblings/draw/ps-setup-class.scrbl @@ -108,10 +108,9 @@ Landscaped orientation affects the size of the drawing area as @defmethod[(get-paper-name) string?]{ -Returns the name of the current paper type: @scheme["A4 210 x 297 - mm"], @scheme["A3 297 x 420 mm"], @scheme["Letter 8 1/2 x 11 in"], or - @scheme["Legal 8 1/2 x 14 in"]. The default is @scheme["Letter 8 1/2 - x 11 in"]. +Returns the name of the current paper type: @scheme["A4 210 x 297 mm"], + @scheme["A3 297 x 420 mm"], @scheme["Letter 8 1/2 x 11 in"], or + @scheme["Legal 8 1/2 x 14 in"]. The default is @scheme["Letter 8 1/2 x 11 in"]. The paper name determines the size of the drawing area as reported by @method[dc<%> get-size] (along with landscape transformations from From 0d0f67260b49467f239832b04d64177947ca76cc Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 14 Feb 2011 10:22:21 -0600 Subject: [PATCH 147/746] This is a change to paper over a bug elsewhere in the system that threatens the release. Specifically, when there is an error in the namespace require (say if one of the teachpack files gets corrupted (because you use a script that monkeys around in the installation, say, and things go wrong)) then the first-opened method does not return normally, but raises an exception. This, so far, is not a problem, but it appears that there is a bug in the implementation of the drracket repl io ports that causes them to deadlock when flushing the error port under certain conditions (I'm not sure what is really going on with this bug, but I am observing a call to flush that fails to return) and the error-display-handler for the teaching languages flushes the output port. This change just avoids printing the error and so the error display handler is not called in the fragile state. This change goes back to exactly what was happening in 5.0.2, at least as far as the teaching language's first-opened method is concerned. So, if this seems okay, I'd like to suggest it be included in the release. (cherry picked from commit 25adab8cbb90902480f1c1657829006803e6843e) --- collects/lang/htdp-langs.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/lang/htdp-langs.rkt b/collects/lang/htdp-langs.rkt index 719712085f..5dfa39c10c 100644 --- a/collects/lang/htdp-langs.rkt +++ b/collects/lang/htdp-langs.rkt @@ -439,7 +439,8 @@ (define/override (first-opened settings) (for ([tp (in-list (htdp-lang-settings-teachpacks settings))]) - (namespace-require/constant tp))) + (with-handlers ((exn:fail? void)) + (namespace-require/constant tp)))) (inherit get-module get-transformer-module get-init-code use-namespace-require/copy?) From bee619f06079372860382b211278c4d721d359fe Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 14 Feb 2011 22:04:44 -0500 Subject: [PATCH 148/746] v5.1 stuff (cherry picked from commit 2880edcb8cd131768559007e5a08261446ad3832) --- collects/meta/web/download/data.rkt | 3 ++- collects/meta/web/download/installers.txt | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/collects/meta/web/download/data.rkt b/collects/meta/web/download/data.rkt index d53ebbab9b..90f3b40a5b 100644 --- a/collects/meta/web/download/data.rkt +++ b/collects/meta/web/download/data.rkt @@ -1,7 +1,8 @@ #lang racket/base (define -versions+dates- - '(["5.0.2" "November 2010"] + '(["5.1" "February 2011"] + ["5.0.2" "November 2010"] ["5.0.1" "August 2010"] ["5.0" "June 2010"] ["4.2.5" "April 2010"] diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index 51e29f1d75..9079a6ade6 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -64,3 +64,23 @@ 16M 5.0/racket/racket-5.0-src-mac.dmg 16M 5.0/racket/racket-5.0-src-unix.tgz 20M 5.0/racket/racket-5.0-src-win.zip +11M 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-f12.sh +11M 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-ubuntu-jaunty.sh +11M 5.1/racket-textual/racket-textual-5.1-bin-i386-osx-mac.dmg +7.6M 5.1/racket-textual/racket-textual-5.1-bin-i386-win32.exe +11M 5.1/racket-textual/racket-textual-5.1-bin-ppc-darwin.sh +11M 5.1/racket-textual/racket-textual-5.1-bin-ppc-osx-mac.dmg +11M 5.1/racket-textual/racket-textual-5.1-bin-x86_64-linux-f14.sh +5.8M 5.1/racket-textual/racket-textual-5.1-src-mac.dmg +5.7M 5.1/racket-textual/racket-textual-5.1-src-unix.tgz +5.8M 5.1/racket-textual/racket-textual-5.1-src-win.zip +50M 5.1/racket/racket-5.1-bin-i386-linux-f12.sh +50M 5.1/racket/racket-5.1-bin-i386-linux-ubuntu-jaunty.sh +51M 5.1/racket/racket-5.1-bin-i386-osx-mac.dmg +32M 5.1/racket/racket-5.1-bin-i386-win32.exe +49M 5.1/racket/racket-5.1-bin-ppc-darwin.sh +52M 5.1/racket/racket-5.1-bin-ppc-osx-mac.dmg +50M 5.1/racket/racket-5.1-bin-x86_64-linux-f14.sh +16M 5.1/racket/racket-5.1-src-mac.dmg +16M 5.1/racket/racket-5.1-src-unix.tgz +18M 5.1/racket/racket-5.1-src-win.zip From d82bc3f4557d676d2686f0b1834af75265143c55 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sat, 16 Apr 2011 08:19:19 -0600 Subject: [PATCH 149/746] Alpha version number for the v5.1.1 release --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index c123e613cc..a40dc65a65 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.1.0.6" +#define MZSCHEME_VERSION "5.1.0.900" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 1 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 6 +#define MZSCHEME_VERSION_W 900 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 34678b6f724672edef80aae35b7aeebfda041746 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Apr 2011 09:14:23 -0600 Subject: [PATCH 150/746] fix gl canvas created after parent is shown Merge to 5.1.1 (cherry picked from commit 546faf8b347e822919773796ae5a8b86a9b39d92) --- collects/mred/private/wx/gtk/canvas.rkt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/collects/mred/private/wx/gtk/canvas.rkt b/collects/mred/private/wx/gtk/canvas.rkt index 988b58dd95..5f73c3153b 100644 --- a/collects/mred/private/wx/gtk/canvas.rkt +++ b/collects/mred/private/wx/gtk/canvas.rkt @@ -345,6 +345,10 @@ (let ([client-gtk (as-gtk-allocation (gtk_drawing_area_new))]) (values client-gtk client-gtk client-gtk #f #f #f #f #f #f 0))]))) + (define for-gl? (memq 'gl style)) + (when for-gl? + (prepare-widget-gl-context client-gtk gl-config)) + (super-new [parent parent] [gtk gtk] [client-gtk client-gtk] @@ -369,10 +373,6 @@ (define dc (new dc% [canvas this] [transparent? (memq 'transparent style)])) - (define for-gl? (memq 'gl style)) - (when for-gl? - (prepare-widget-gl-context client-gtk gl-config)) - (gtk_widget_realize gtk) (gtk_widget_realize client-gtk) From 0923d07acb1e0b5217e91702b25d0383cdf2e40e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 16 Apr 2011 21:09:29 -0500 Subject: [PATCH 151/746] adjust the close callback so that it knows what state the bug report window is in closes PR 11773 merge to the release, please (cherry picked from commit 95b6f149fa37dd46f75193ad6104f4972ee98ebf) --- collects/help/bug-report.rkt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collects/help/bug-report.rkt b/collects/help/bug-report.rkt index 575466d278..4c32ad1f56 100644 --- a/collects/help/bug-report.rkt +++ b/collects/help/bug-report.rkt @@ -59,6 +59,8 @@ (cond [close-box-clicked? (cond + [(eq? (send single active-child) finished-panel) + #t] [(empty-bug-report?) (no-more-saving) (unsave-bug-report bug-id) From a3ce6c184e79b5121f3a4a8c3ceef7eb5d1742eb Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 17 Apr 2011 22:00:19 -0400 Subject: [PATCH 152/746] New Racket version 5.1.0.900. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index 04f1ca609f..c577397643 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 6bd7a565df..89e40d049d 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,0,6 - PRODUCTVERSION 5,1,0,6 + FILEVERSION 5,1,0,900 + PRODUCTVERSION 5,1,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 1, 0, 6\0" + VALUE "FileVersion", "5, 1, 0, 900\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 0, 6\0" + VALUE "ProductVersion", "5, 1, 0, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index eaaf311f5a..b9919e7ccb 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,0,6 - PRODUCTVERSION 5,1,0,6 + FILEVERSION 5,1,0,900 + PRODUCTVERSION 5,1,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 1, 0, 6" + VALUE "FileVersion", "5, 1, 0, 900" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 1, 0, 6" + VALUE "ProductVersion", "5, 1, 0, 900" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index 76ef4f1bf9..3fddbb5fe7 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.1.0.6 = s 'MzObj Class' + MzCOM.MzObj.5.1.0.900 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.1.0.6' + CurVer = s 'MzCOM.MzObj.5.1.0.900' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.1.0.6' + ProgID = s 'MzCOM.MzObj.5.1.0.900' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 1dfeb4ad4d..d3da583097 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index a16ec153dd..d370cc39f1 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,0,6 - PRODUCTVERSION 5,1,0,6 + FILEVERSION 5,1,0,900 + PRODUCTVERSION 5,1,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 1, 0, 6\0" + VALUE "FileVersion", "5, 1, 0, 900\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 0, 6\0" + VALUE "ProductVersion", "5, 1, 0, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index b93f7befd6..85f353687c 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,0,6 - PRODUCTVERSION 5,1,0,6 + FILEVERSION 5,1,0,900 + PRODUCTVERSION 5,1,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 1, 0, 6\0" + VALUE "FileVersion", "5, 1, 0, 900\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 0, 6\0" + VALUE "ProductVersion", "5, 1, 0, 900\0" END END BLOCK "VarFileInfo" From 34ae8d15bf7399817f85b6de750ff20809d7e02b Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 18 Apr 2011 10:31:19 -0500 Subject: [PATCH 153/746] make the close icon clicky thingy not grab the focus closes PR 10380 (cherry picked from commit 100b4d31f12d9e90e0fcec73abb68e2cd89b8920) --- collects/mrlib/close-icon.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/mrlib/close-icon.rkt b/collects/mrlib/close-icon.rkt index cde9e95fbc..039bd253b8 100644 --- a/collects/mrlib/close-icon.rkt +++ b/collects/mrlib/close-icon.rkt @@ -113,7 +113,7 @@ [else mask1]))))) - (super-new [style '(transparent)]) + (super-new [style '(transparent no-focus)]) (min-width (+ horizontal-pad horizontal-pad (send icon get-width))) (min-height (+ vertical-pad vertical-pad (send icon get-height))) (stretchable-width #f) From 2db96988354805fdcfee5986d4513c7506872a24 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 18 Apr 2011 13:25:28 -0400 Subject: [PATCH 154/746] Optimize filter operations. (cherry picked from commit bce90e2a712dccdf0c7283abaa5be49f65d96b59) --- collects/typed-scheme/types/filter-ops.rkt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/collects/typed-scheme/types/filter-ops.rkt b/collects/typed-scheme/types/filter-ops.rkt index 954fb5e98a..bcbde39564 100644 --- a/collects/typed-scheme/types/filter-ops.rkt +++ b/collects/typed-scheme/types/filter-ops.rkt @@ -129,7 +129,9 @@ (cond [(for/or ([f (in-list (append (cdr fs) result))]) (opposite? f t)) -top] - [(for/or ([f (in-list result)]) (or (filter-equal? f t) (implied-atomic? f t))) + [(let ([t-seq (Rep-seq t)]) + (for/or ([f (in-list result)]) + (or (= (Rep-seq f) t-seq) (implied-atomic? f t)))) (loop (cdr fs) result)] [else (loop (cdr fs) (cons t result))])])))) @@ -139,7 +141,7 @@ (case-lambda [() -top] [(f) f] [fs (make-AndFilter fs)])) - (let loop ([fs (remove-duplicates args filter-equal?)] [result null]) + (let loop ([fs (remove-duplicates args equal? #:key Rep-seq)] [result null]) (if (null? fs) (match result [(list) -top] @@ -158,7 +160,9 @@ [t (cond [(for/or ([f (in-list (append (cdr fs) result))]) (opposite? f t)) -bot] - [(for/or ([f (in-list result)]) (or (filter-equal? f t) (implied-atomic? t f))) + [(let ([t-seq (Rep-seq t)]) + (for/or ([f (in-list result)]) + (or (= (Rep-seq f) t-seq) (implied-atomic? t f)))) (loop (cdr fs) result)] [else (loop (cdr fs) (cons t result))])])))) From d863ee466ba3b185245680db957ad3958d28c02e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 18 Apr 2011 13:04:23 -0600 Subject: [PATCH 155/746] fix bug in `thread'-based implementation of `place' which is used when parallel places are unavailable (cherry picked from commit 2fa35a2a5c79cfc49663320e34af38b9590aba72) --- collects/racket/place.rkt | 32 +++++++++++++++++--------------- src/racket/src/startup.rktl | 6 +++--- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/collects/racket/place.rkt b/collects/racket/place.rkt index 693d72dc04..595bde5cd2 100644 --- a/collects/racket/place.rkt +++ b/collects/racket/place.rkt @@ -21,7 +21,8 @@ processor-count (rename-out [pl-place-enabled? place-enabled?])) -(define-struct TH-place (th ch) #:property prop:evt (lambda (x) (TH-place-channel-out (TH-place-ch x)))) +(define-struct TH-place (th ch cust) + #:property prop:evt (lambda (x) (TH-place-channel-in (TH-place-ch x)))) (define (place-channel-send/receive ch msg) (place-channel-send ch msg) @@ -33,8 +34,9 @@ (thread (lambda () (let loop () - (channel-put ch (thread-receive)) - (loop)))) + (let ([v (thread-receive)]) + (channel-put ch v) + (loop))))) ch)) (define (th-place mod funcname) @@ -43,18 +45,20 @@ (unless (symbol? funcname) (raise-type-error 'place "symbol?" 1 mod funcname)) (define-values (pch cch) (th-place-channel)) - (define th (thread (lambda () - (with-continuation-mark - parameterization-key - orig-paramz - (parameterize ([current-namespace (make-base-namespace)] - [current-custodian (make-custodian-from-main)]) - ((dynamic-require mod funcname) cch)))))) - (TH-place th pch)) + (define cust (make-custodian-from-main)) + (define th (thread + (lambda () + (with-continuation-mark + parameterization-key + orig-paramz + (parameterize ([current-namespace (make-base-namespace)] + [current-custodian cust]) + ((dynamic-require mod funcname) cch)))))) + (TH-place th pch cust)) (define (th-place-sleep n) (sleep n)) (define (th-place-wait pl) (thread-wait (TH-place-th pl)) 0) -(define (th-place-kill pl) (kill-thread (TH-place-th pl))) +(define (th-place-kill pl) (custodian-shutdown-all (TH-place-cust pl))) (define (th-place-channel) (define-values (as ar) (make-th-async-channel)) (define-values (bs br) (make-th-async-channel)) @@ -94,9 +98,7 @@ [(TH-place? pl) (TH-place-channel-out (TH-place-ch pl))] [(TH-place-channel? pl) (TH-place-channel-out pl)] [else (raise-type-error 'place-channel-send "expect a place? or place-channel?" pl)])) - (sync (thread-resume-evt th)) - (thread-send th - (deep-copy msg))) + (void (thread-send th (deep-copy msg) #f))) (define (th-place-channel-receive pl) (channel-get diff --git a/src/racket/src/startup.rktl b/src/racket/src/startup.rktl index 8bc0feeb0e..bbdbd4958a 100644 --- a/src/racket/src/startup.rktl +++ b/src/racket/src/startup.rktl @@ -495,9 +495,9 @@ ;; ---------------------------------------- -;; A module that collects all the built-in modules, -;; so that it's easier to keep them attached in new -;; namespaces. +;; When places are implemented by plain old threads, +;; place channels need to be shared across namespaces, +;; so `#%place-struct' is included in builtins (module #%place-struct '#%kernel From 14ba5fb38a9ae8a3fafcb7bc512ea63cb6352818 Mon Sep 17 00:00:00 2001 From: Hari Prashanth Date: Mon, 4 Oct 2010 23:27:13 -0400 Subject: [PATCH 156/746] Added some examples to to the TR reference docs. Signed-off-by: Sam Tobin-Hochstadt (cherry picked from commit 7934ac3461830df81836dfd8113e1b2e7a915a1a) --- .../scribblings/ts-reference.scrbl | 129 ++++++++++++++++-- 1 file changed, 115 insertions(+), 14 deletions(-) diff --git a/collects/typed-scheme/scribblings/ts-reference.scrbl b/collects/typed-scheme/scribblings/ts-reference.scrbl index d70af32bdf..196e9ebef8 100644 --- a/collects/typed-scheme/scribblings/ts-reference.scrbl +++ b/collects/typed-scheme/scribblings/ts-reference.scrbl @@ -217,15 +217,25 @@ by @racket[read].} @defform[(U t ...)]{is the union of the types @racket[t ...]. @ex[(λ: ([x : Real])(if (> 0 x) "yes" 'no))]} @defform[(case-lambda fun-ty ...)]{is a function that behaves like all of - the @racket[fun-ty]s, considered in order from first to last. - The @racket[fun-ty]s must all be function - types constructed with @racket[->].} + the @racket[fun-ty]s, considered in order from first to last. The @racket[fun-ty]s must all be function + types constructed with @racket[->]. + @ex[(: add-map : (case-lambda + [(Listof Integer) -> (Listof Integer)] + [(Listof Integer) (Listof Integer) -> (Listof Integer)]))] + For the definition of @racket[add-map] look into @racket[case-lambda:].} + @defform/none[(t t1 t2 ...)]{is the instantiation of the parametric type @racket[t] at types @racket[t1 t2 ...]} @defform[(All (v ...) t)]{is a parameterization of type @racket[t], with type variables @racket[v ...]. If @racket[t] is a function type constructed with @racket[->], the outer pair of parentheses - around the function type may be omitted.} + around the function type may be omitted. + @ex[(: list-lenght : (All (A) (Listof A) -> Natural)) + (define (list-lenght lst) + (if (null? lst) + 0 + (add1 (list-lenght (cdr lst)))))]} + @defform[(values t ...)]{is the type of a sequence of multiple values, with types @racket[t ...]. This can only appear as the return type of a function. @@ -235,12 +245,15 @@ function. @defform/none[i]{where @racket[i] is an identifier can be a reference to a type name or a type variable} @defform[(Rec n t)]{is a recursive type where @racket[n] is bound to the -recursive type in the body @racket[t]} +recursive type in the body @racket[t] +@ex[(define-type IntList (Rec List (Pair Integer (U List Null)))) + + (define-type (List A) (Rec List (Pair A (U List Null))))]} @subsection{Other Types} -@defform[(Option t)]{Either @racket[t] of @racket[#f]} +@defform[(Option t)]{Either @racket[t] or @racket[#f]} @section[#:tag "special-forms"]{Special Form Reference} @@ -259,8 +272,31 @@ creating new types, and annotating expressions. Local bindings, like @racket[let], each with associated types. In the second form, @racket[_t0] is the type of the result of @racket[_loop] (and thus the result of the entire -expression as well as the final expression in @racket[body]). -Type annotations are optional.} + expression as well as the final + expression in @racket[body]). + Type annotations are optional. +@ex[(: filter-even : (Listof Natural) (Listof Natural) -> (Listof Natural)) + (define (filter-even lst accum) + (if (null? lst) + accum + (let: ([first : Natural (car lst)] + [rest : (Listof Natural) (cdr lst)]) + (if (even? first) + (filter-even rest (cons first accum)) + (filter-even rest accum))))) + (filter-even (list 1 2 3 4 5 6) null)] + +@ex[(: filter-even-loop : (Listof Natural) -> (Listof Natural)) + (define (filter-even-loop lst) + (let: loop : (Listof Natural) + ([accum : (Listof Natural) null] + [lst : (Listof Natural) lst]) + (cond + [(null? lst) accum] + [(even? (car lst)) (loop (cons (car lst) accum) (cdr lst))] + [else (loop accum (cdr lst))]))) + (filter-even-loop (list 1 2 3 4))]} + @deftogether[[ @defform[(letrec: ([v : t e] ...) . body)] @defform[(let*: ([v : t e] ...) . body)] @@ -294,7 +330,16 @@ A polymorphic function, abstracted over the type variables of the formal, and in any type expressions in the @racket[body].} @defform[(case-lambda: [formals body] ...)]{ A function of multiple arities. Note that each @racket[formals] must have a -different arity.} +different arity. +@ex[(define add-map + (case-lambda: + [([lst : (Listof Integer)]) + (map add1 lst)] + [([lst1 : (Listof Integer)] + [lst2 : (Listof Integer)]) + (map + lst1 lst2)]))] +For the type declaration of @racket[add-map] look at @racket[case-lambda].} + @defform[(pcase-lambda: (a ...) [formals body] ...)]{ A polymorphic function of multiple arities.} @defform/subs[(opt-lambda: formals . body) @@ -383,7 +428,18 @@ annotations are optional. These forms define variables, with annotated types. The first form defines @racket[v] with type @racket[t] and value @racket[e]. The second and third forms defines a function @racket[f] with appropriate -types. In most cases, use of @racket[:] is preferred to use of @racket[define:].} +types. In most cases, use of @racket[:] is preferred to use of @racket[define:]. + +@ex[(define: foo : Integer 10) + + (define: (add [first : Integer] + [rest : Integer]) : Integer + (+ first rest)) + + (define: (A) (poly-app [func : (A A -> A)] + [first : A] + [rest : A]) : A + (func first rest))]} @@ -423,7 +479,10 @@ The first form defines @racket[name] as type, with the same meaning as @racket[t]. The second form is equivalent to @racket[(define-type name (All (v ...) t))]. Type names may refer to other types defined in the same module, but -cycles among them are prohibited.} +cycles among them are prohibited. + +@ex[(define-type IntStr (U Integer String)) + (define-type (ListofPairs A) (Listof (Pair A A)))]} @subsection{Generating Predicates Automatically} @defform[(define-predicate name t)]{ @@ -436,7 +495,9 @@ Defines @racket[name] as a predicate for the type @racket[t]. @defform[(: v t)]{This declares that @racket[v] has type @racket[t]. The definition of @racket[v] must appear after this declaration. This -can be used anywhere a definition form may be used.} +can be used anywhere a definition form may be used. +@ex[(: var1 Integer) + (: var2 String)]} @defform[(provide: [v t] ...)]{This declares that the @racket[v]s have the types @racket[t], and also provides all of the @racket[v]s.} @@ -453,7 +514,14 @@ This is legal only in expression contexts.} @defform[(inst e t ...)]{Instantiate the type of @racket[e] with types @racket[t ...]. @racket[e] must have a polymorphic type with the appropriate number of type variables. This is legal only in expression -contexts.} +contexts. +@ex[(foldl (inst cons Integer Integer) null (list 1 2 3 4))] + +@ex[(: fold-list : (All (A) (Listof A) -> (Listof A))) + (define (fold-list lst) + (foldl (inst cons A A) null lst)) + + (fold-list (list "1" "2" "3" "4"))]} @litchar|{#{e @ t ...}}| This is identical to @racket[(inst e t ...)]. @@ -482,6 +550,23 @@ structure predicate has the appropriate Typed Racket filter type so that it may be used as a predicate in @racket[if] expressions in Typed Racket. + +@ex[(module UNTYPED racket/base + (define n 100) + + (define-struct IntTree + (elem left right)) + + (provide n (struct-out IntTree))) + + (module TYPED typed/racket + (require/typed 'UNTYPED + [n Natural] + [struct IntTree + ([elem : Integer] + [left : IntTree] + [right : IntTree])]))] + @index["opaque"]{The fourth case} defines a new type @racket[t]. @racket[pred], imported from module @racket[m], is a predicate for this type. The type is defined as precisely those values to which @racket[pred] produces @@ -494,8 +579,24 @@ enforce the specified types. If this contract fails, the module Some types, notably polymorphic types constructed with @racket[All], cannot be converted to contracts and raise a static error when used in -a @racket[require/typed] form.} +a @racket[require/typed] form. Here is an example of using +@racket[case-lambda] in @racket[require/typed]. +@(racketblock + (require/typed racket/base + [file-or-directory-modify-seconds + (case-lambda + [String -> Exact-Nonnegative-Integer] + [String (Option Exact-Nonnegative-Integer) + -> + (U Exact-Nonnegative-Integer Void)] + [String (Option Exact-Nonnegative-Integer) (-> Any) + -> + Any])])) + +@racket[file-or-directory-modify-seconds] has some arguments which are optional. +So we need to use @racket[case-lambda].} + @section{Libraries Provided With Typed Racket} The @racketmodname[typed/racket] language corresponds to the From d61e0e4c5c926d986f84f273a7218a341a38e8bc Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 18 Apr 2011 15:40:20 -0400 Subject: [PATCH 157/746] Remove unused code. (cherry picked from commit 187dc634933a5652746d5dcb6a263732a9a46b7a) --- collects/typed-scheme/private/colon.rkt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/collects/typed-scheme/private/colon.rkt b/collects/typed-scheme/private/colon.rkt index 58152646f6..efa4214fcf 100644 --- a/collects/typed-scheme/private/colon.rkt +++ b/collects/typed-scheme/private/colon.rkt @@ -9,18 +9,6 @@ (provide :) (define-syntax (: stx) - (define-syntax-class arr - (pattern x:id - #:fail-unless (eq? (syntax-e #'x) '->) #f - #:fail-unless (printf "id: ~a ~a\n" - (identifier-binding #'All-kw) - (identifier-transformer-binding #'All-kw)) - #f - #:fail-unless (printf "kw: ~a ~a\n" - (identifier-binding #'t:All) - (identifier-transformer-binding #'t:All)) - #f - #:fail-when #t #f)) (define stx* ;; make it possible to add another colon after the id for clarity ;; and in that case, a `->' on the RHS does not need to be From cb4ab1869e537164e26f157d41780f547717ff6b Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 18 Apr 2011 15:40:31 -0400 Subject: [PATCH 158/746] Copy properties when optimizing bodies of lambda/define-values. Closes PR 11860. (cherry picked from commit 981616d504c1c0c6f91effedc6166a324de328e3) --- collects/typed-scheme/optimizer/optimizer.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collects/typed-scheme/optimizer/optimizer.rkt b/collects/typed-scheme/optimizer/optimizer.rkt index 04bc1c790e..f9bc201792 100644 --- a/collects/typed-scheme/optimizer/optimizer.rkt +++ b/collects/typed-scheme/optimizer/optimizer.rkt @@ -37,7 +37,9 @@ ;; boring cases, just recur down (pattern ((~and op (~or (~literal #%plain-lambda) (~literal define-values))) formals e:expr ...) - #:with opt #`(op formals #,@(syntax-map (optimize) #'(e ...)))) + #:with opt (syntax-track-origin (quasisyntax/loc this-syntax (op formals #,@(syntax-map (optimize) #'(e ...)))) + this-syntax + #'op)) (pattern (case-lambda [formals e:expr ...] ...) ;; optimize all the bodies #:with (opt-parts ...) From d827278dd8a629c65de6e18142a975f66339328d Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 18 Apr 2011 16:50:35 -0400 Subject: [PATCH 159/746] Indentation in example (cherry picked from commit 49e1b47bb26a86dd4b87a44d75264a89bd00f092) --- collects/meta/web/www/index.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/meta/web/www/index.rkt b/collects/meta/web/www/index.rkt index 7adf82dc0e..82f8917aee 100644 --- a/collects/meta/web/www/index.rkt +++ b/collects/meta/web/www/index.rkt @@ -56,7 +56,7 @@ @code{#lang web-server/insta ;; A "hello world" web server (define (start request) - (response/xexpr) + (response/xexpr) '(html (body "Hello World")))} @desc{This example implements a web server using the From 67b490adb162fe9c471a46963630a0767efba7d2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 18 Apr 2011 14:44:05 -0600 Subject: [PATCH 160/746] adjust Racket release notes for 5.1.1 Merge to v5.1.1 (cherry picked from commit 4e576a8ac90b0e84e60d3c553a449ef9b086327a) --- doc/release-notes/racket/HISTORY.txt | 34 ++++++++++++---------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index 6c74f37990..19dbae47b5 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,7 +1,19 @@ -Version 5.1.0.6 +Version 5.1.1, May 2011 +Enabled single-precision floats by default +Added single-flonum? +Changed eqv? so that inexacts are equivalent only when they + have the same precision +Changed file-or-directory-permission to add 'bits mode + and permission-setting mode +Added special treatment of void as an 'inferred-name property Removed the "MrEd" compatability executable under Windows and Mac OS X, but the "mred" compatibility script remains -Removed the following (undocumented) exports from racket/contract: +racket/gui: added multi-column support to list-box% +racket/gui: added scrollbar support to panel%, vertical-panel%, + and horizontal-panel% +racket/gui: added 'wheel-left and 'wheel-right events +racket/file: add user-read-bit, etc. +racket/contract: removed the following (undocumented) exports: build-flat-contract chaperone-contract-struct? contract-struct-first-order @@ -37,24 +49,6 @@ Removed the following (undocumented) exports from racket/contract: synthesized-value unknown? -Version 5.1.0.5 -racket/gui: added 'wheel-left and 'wheel-right events - -Version 5.1.0.4 -Change file-or-directory-permission to add 'bits mode - and permission-setting mode -racket/file: add user-read-bit, etc. -Added special treatment of void as an 'inferred-name property - -Version 5.1.0.2 -Enabled single-precision floats by default -Added single-flonum? -Changed eqv? so that inexacts are equivalent only when they - have the same precision -racket/gui: added multi-column support to list-box% -racket/gui: added scrollbar support to panel%, vertical-panel%, - and horizontal-panel% - Version 5.1, February 2011 Renamed "proxy" to "impersonator" Added current-get-interaction-input-port, which enables From 6586ab120170fbf636baa3e7448426fcd26247ba Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 18 Apr 2011 15:47:52 -0600 Subject: [PATCH 161/746] fix typo Closes PR 11862 Merge to 5.1.1 (cherry picked from commit 963a8214b89a1968df11c63697bc07bb63c832e6) --- collects/scribblings/reference/module-reflect.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/reference/module-reflect.scrbl b/collects/scribblings/reference/module-reflect.scrbl index 89a8d72ae1..bf4489b037 100644 --- a/collects/scribblings/reference/module-reflect.scrbl +++ b/collects/scribblings/reference/module-reflect.scrbl @@ -355,7 +355,7 @@ above the @tech{base phase}. When @racket[provided] is a symbol, the value of the module's export with the given name is returned, and still the module is not @tech{visit}ed or made @tech{available} in higher phases. If the -module exports @racket[provide] as syntax, then a use of the binding +module exports @racket[provided] as syntax, then a use of the binding is expanded and evaluated in a fresh namespace to which the module is attached, which means that the module is @tech{visit}ed in the fresh namespace. If the module has no such exported variable or syntax, then From 8f368d8df64e0f1a426b64af0df29bfd1c322d98 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 19 Apr 2011 07:13:31 -0600 Subject: [PATCH 162/746] fix typo Closes PR 11864 Merge to 5.1.1 (cherry picked from commit 6664e20815c48e410ff7b98ad02f7559e28487ab) --- collects/scribblings/reference/stx-patterns.scrbl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/scribblings/reference/stx-patterns.scrbl b/collects/scribblings/reference/stx-patterns.scrbl index 62b29fdb90..7119199086 100644 --- a/collects/scribblings/reference/stx-patterns.scrbl +++ b/collects/scribblings/reference/stx-patterns.scrbl @@ -271,8 +271,8 @@ the individual @scheme[stx-expr]. const] [ellipsis #,lit-ellipsis])]{ -Constructs a syntax object based on a @scheme[template],which can -inlude @tech{pattern variables} bound by @scheme[syntax-case] or +Constructs a syntax object based on a @scheme[template], which can +include @tech{pattern variables} bound by @scheme[syntax-case] or @scheme[with-syntax]. Template forms produce a syntax object as follows: From 2d375a7d29d3acc42bd83adff5bee828ad7b2519 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 19 Apr 2011 07:16:10 -0600 Subject: [PATCH 163/746] doc corrections Closes PR 11865 Merge to 5.1.1 (cherry picked from commit 18e3f54fa5ce2695234aced0db675c5018afbb2e) --- collects/scribblings/guide/control.scrbl | 6 +++--- collects/scribblings/reference/cont.scrbl | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/collects/scribblings/guide/control.scrbl b/collects/scribblings/guide/control.scrbl index 32d1b85bcc..ebaad462f7 100644 --- a/collects/scribblings/guide/control.scrbl +++ b/collects/scribblings/guide/control.scrbl @@ -245,12 +245,12 @@ the continuation in @racket[saved-k] becomes @racket[(lambda (x) (+ 5 (saved-k 10) ] -A more traditional continuation operator in Racket is -@racket[call-with-current-continuation], which is often abbreviated +A more traditional continuation operator in Racket (or Scheme) is +@racket[call-with-current-continuation], which is usually abbreviated @racket[call/cc]. It is like @racket[call-with-composable-continuation], but applying the captured continuation first @tech{aborts} (to the current @tech{prompt}) before -restoring the saved continuation. In addition, Racket systems +restoring the saved continuation. In addition, Scheme systems traditionally support a single prompt at the program start, instead of allowing new prompts via @racket[call-with-continuation-prompt]. Continuations as in Racket diff --git a/collects/scribblings/reference/cont.scrbl b/collects/scribblings/reference/cont.scrbl index cdbcddc0ed..231bf29011 100644 --- a/collects/scribblings/reference/cont.scrbl +++ b/collects/scribblings/reference/cont.scrbl @@ -36,8 +36,7 @@ evaluation context protected by the barrier: ] In addition, extensions of Racket may install barriers in -additional contexts. In particular, GRacket installs a continuation -barrier around most every callback. Finally, +additional contexts. Finally, @racket[call-with-continuation-barrier] applies a thunk barrier between the application and the current continuation. From 4321a1e13c03eca104cf01486b729996653a953d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 18 Apr 2011 15:48:14 -0600 Subject: [PATCH 164/746] fix `namespace-attach-module' at phases above 0 Closes PR 11863 Merge to 5.1.1 (cherry picked from commit 586478a241dc0edfd76a16aaecb76a97c8888372) --- src/racket/src/module.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/racket/src/module.c b/src/racket/src/module.c index c67ec47819..b00eda3fdd 100644 --- a/src/racket/src/module.c +++ b/src/racket/src/module.c @@ -1421,7 +1421,7 @@ static Scheme_Object *namespace_attach_module(int argc, Scheme_Object *argv[]) while (!SCHEME_NULLP(todo)) { if (phase > max_phase) max_phase = phase; - if (phase < 0) { + if (phase < orig_phase) { /* As soon as we start traversing negative phases, stop transferring instances (i.e., transfer declarations only). This transfer-only mode should stick even even if we go back into positive phases. */ @@ -1466,7 +1466,7 @@ static Scheme_Object *namespace_attach_module(int argc, Scheme_Object *argv[]) deeper in phases (for-syntax levels) than the target namespace has ever gone, so there's definitely no conflict at this level in that case. */ - if ((phase >= 0) && SCHEME_TRUEP(to_modchain)) { + if ((phase >= orig_phase) && SCHEME_TRUEP(to_modchain)) { menv2 = (Scheme_Env *)scheme_hash_get(MODCHAIN_TABLE(to_modchain), name); if (menv2) { if (!SAME_OBJ(menv->toplevel, menv2->toplevel)) @@ -1642,7 +1642,7 @@ static Scheme_Object *namespace_attach_module(int argc, Scheme_Object *argv[]) } from_modchain = SCHEME_VEC_ELS(from_modchain)[2]; - if (phase > 0) { + if (phase > orig_phase) { to_modchain = SCHEME_CAR(past_to_modchains); past_to_modchains = SCHEME_CDR(past_to_modchains); } @@ -1669,7 +1669,7 @@ static Scheme_Object *namespace_attach_module(int argc, Scheme_Object *argv[]) } from_modchain = SCHEME_VEC_ELS(from_modchain)[1]; - if (phase >= 0) { + if (phase >= orig_phase) { past_to_modchains = cons(to_modchain, past_to_modchains); if (SCHEME_TRUEP(to_modchain)) to_modchain = SCHEME_VEC_ELS(to_modchain)[1]; @@ -1821,7 +1821,7 @@ static Scheme_Object *namespace_attach_module(int argc, Scheme_Object *argv[]) LOG_ATTACH(printf("Copying %d (%p)\n", phase, checked)); - if (phase >= 0) + if (phase >= orig_phase) check_modchain_consistency(MODCHAIN_TABLE(to_modchain), phase); for (i = checked->size; i--; ) { @@ -1837,7 +1837,7 @@ static Scheme_Object *namespace_attach_module(int argc, Scheme_Object *argv[]) menv2 = (Scheme_Env *)scheme_hash_get(MODCHAIN_TABLE(to_modchain), name); if (!menv2) { /* Clone/copy menv for the new namespace: */ - if ((phase >= 0) && !just_declare) { + if ((phase >= orig_phase) && !just_declare) { menv2 = scheme_copy_module_env(menv, to_env, to_modchain, orig_phase); if (menv->attached) menv2->attached = 1; @@ -1858,7 +1858,7 @@ static Scheme_Object *namespace_attach_module(int argc, Scheme_Object *argv[]) past_checkeds = SCHEME_CDR(past_checkeds); from_modchain = SCHEME_VEC_ELS(from_modchain)[2]; - if (phase > 0) + if (phase > orig_phase) to_modchain = SCHEME_VEC_ELS(to_modchain)[2]; --phase; } From 05260c16c248137486ba58e49f79ba5132916db7 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 18 Apr 2011 17:43:11 -0400 Subject: [PATCH 165/746] Remove useless propositional clauses. Thanks to dyoo for test case. (cherry picked from commit 0f5dfd68710bbfadb499e2ab7ff294bcd377053a) --- collects/typed-scheme/types/filter-ops.rkt | 25 ++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/collects/typed-scheme/types/filter-ops.rkt b/collects/typed-scheme/types/filter-ops.rkt index bcbde39564..7476a88f18 100644 --- a/collects/typed-scheme/types/filter-ops.rkt +++ b/collects/typed-scheme/types/filter-ops.rkt @@ -13,8 +13,9 @@ (provide (all-defined-out)) -(define (atomic-filter? e) - (or (TypeFilter? e) (NotTypeFilter? e))) +(define (atomic-filter? p) + (or (TypeFilter? p) (NotTypeFilter? p) + (Top? p) (Bot? p))) (define (opposite? f1 f2) (match* (f1 f2) @@ -40,6 +41,8 @@ (if (filter-equal? f1 f2) #t (match* (f1 f2) + [((OrFilter: fs) f2) + (memf (lambda (f) (filter-equal? f f2)) fs)] [((TypeFilter: t1 p1 i1) (TypeFilter: t2 p1 i2)) (and (name-ref=? i1 i2) @@ -60,6 +63,8 @@ ((listof Filter/c) boolean? . --> . (listof Filter/c)) (define tf-map (make-hash)) (define ntf-map (make-hash)) + ;; props: the propositions we're processing + ;; others: props that are neither TF or NTF (let loop ([props props] [others null]) (if (null? props) (append others @@ -152,7 +157,18 @@ (if (filter-equal? f1 f2) f1 (apply mk (compact (list f1 f2) #f))))] - [_ (apply mk (compact result #f))]) + [_ + ;; first, remove anything implied by the atomic propositions + ;; We commonly see: (And (Or P Q) (Or P R) (Or P S) ... P), which this fixes + (let-values ([(atomic not-atomic) (partition atomic-filter? result)]) + (define not-atomic* + (for/list ([p (in-list not-atomic)] + #:when + (not (for/or ([a (in-list atomic)]) + (implied-atomic? p a)))) + p)) + ;; `compact' takes care of implications between atomic props + (apply mk (compact (append not-atomic* atomic) #f)))]) (match (car fs) [(and t (Bot:)) t] [(AndFilter: fs*) (loop (cdr fs) (append fs* result))] @@ -162,7 +178,8 @@ -bot] [(let ([t-seq (Rep-seq t)]) (for/or ([f (in-list result)]) - (or (= (Rep-seq f) t-seq) (implied-atomic? t f)))) + (or (= (Rep-seq f) t-seq) + (implied-atomic? t f)))) (loop (cdr fs) result)] [else (loop (cdr fs) (cons t result))])])))) From 35491070d0bbfcf0cecf82365e6ba382ecde9464 Mon Sep 17 00:00:00 2001 From: Jon Rafkind Date: Mon, 18 Apr 2011 17:00:42 -0600 Subject: [PATCH 166/746] better error message when pre: or post: is used incorrectly (cherry picked from commit 3f572809c903bff453f36a48eb57994eeb1c36e0) --- collects/ffi/unsafe.rkt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/collects/ffi/unsafe.rkt b/collects/ffi/unsafe.rkt index 4cef8d2674..e3bbe8959d 100644 --- a/collects/ffi/unsafe.rkt +++ b/collects/ffi/unsafe.rkt @@ -344,7 +344,7 @@ (let loop ([t orig]) (define (next rest . args) (apply setkey! args) (loop rest)) (syntax-case* t - (type: expr: bind: 1st-arg: prev-arg: pre: post: keywords:) + (type: expr: bind: 1st-arg: prev-arg: pre: post: keywords: =>) id=? [(type: t x ...) (next #'(x ...) 'type #'t)] [(expr: e x ...) (next #'(x ...) 'expr #'e)] @@ -352,7 +352,11 @@ [(1st-arg: id x ...) (next #'(x ...) '1st (cert-id #'id) #t)] [(prev-arg: id x ...) (next #'(x ...) 'prev (cert-id #'id) #t)] ;; in the following two cases pass along orig for recertifying + ;; first explicitly check if the `(id => expr)' form left off + ;; the parentheses + [(pre: p => expr x ...) (err "bad form for `pre:'. Expected either `pre: (id => expression)' or `pre: expression'" #'(pre: p => expr))] [(pre: p x ...) (next #'(x ...) 'pre (with-arg #'p))] + [(post: p => expr x ...) (err "bad form for `post:' Expected either `post: (id => expression)' or `post: expression'" #'(post: p => expr))] [(post: p x ...) (next #'(x ...) 'post (with-arg #'p))] [(keywords: x ...) (let kloop ([ks '()] [xs #'(x ...)]) From 86b781e5bf1e0a6307b31cae4467c547a8b4b61b Mon Sep 17 00:00:00 2001 From: Jon Rafkind Date: Mon, 18 Apr 2011 17:27:07 -0600 Subject: [PATCH 167/746] show an example of define-fun-syntax and using the keywords (cherry picked from commit cdb63b9c77f0a96b4b479f309e9fa6808cbae367) --- collects/scribblings/foreign/types.scrbl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/collects/scribblings/foreign/types.scrbl b/collects/scribblings/foreign/types.scrbl index 485963cb2b..1216772024 100644 --- a/collects/scribblings/foreign/types.scrbl +++ b/collects/scribblings/foreign/types.scrbl @@ -659,8 +659,17 @@ with a function call. Binds @scheme[id] as a @tech{custom function type}. The type is expanded by applying the procedure produced by @scheme[transformer-expr] to a use of the @tech{custom function -type}.} +type}. +For instance, the following defines a new type that automatically coerces +the input number to an inexact form which is compatible with the _float type. + +@racketblock[ +(define-fun-syntax _float* + (syntax-id-rules (_float*) + [(_float*) (type: _float pre: (x => (+ 0.0 x)))])) + +(_fun _float* -> _bool)]} @defidform[_?]{ From 8ba24327c1dab6a1e9a385e9db8afc388db54d7e Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Tue, 19 Apr 2011 01:21:19 -0400 Subject: [PATCH 168/746] fix struct constructor application in lazy racket (cherry picked from commit 718b9709bc7dc1acdc138c2f67288001b328d80b) --- collects/lazy/lazy.rkt | 4 +++- collects/stepper/private/macro-unwind.rkt | 15 ++++++++------- collects/tests/lazy/lang.rkt | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/collects/lazy/lazy.rkt b/collects/lazy/lazy.rkt index 6807d2189d..d955723559 100644 --- a/collects/lazy/lazy.rkt +++ b/collects/lazy/lazy.rkt @@ -254,6 +254,8 @@ ;; `!apply': provided as `apply' (no need to provide `~!apply', since all ;; function calls are delayed by `#%app') + (define (extract-if-lazy-proc f) + (or (procedure-extract-target f) f)) (define-syntax (!*app stx) (syntax-case stx () [(_ f x ...) @@ -271,7 +273,7 @@ skipto/first)))]) (with-syntax ([(y ...) (generate-temporaries #'(x ...))]) ;; use syntax/loc for better errors etc - (with-syntax ([lazy (syntax/loc stx ((procedure-extract-target p) y ...))] + (with-syntax ([lazy (syntax/loc stx ((extract-if-lazy-proc p) y ...))] [strict (syntax/loc stx (p (hidden-! y) ...))]) (quasisyntax/loc stx ((lambda (p y ...) diff --git a/collects/stepper/private/macro-unwind.rkt b/collects/stepper/private/macro-unwind.rkt index 1a61e925c6..78bede05f7 100644 --- a/collects/stepper/private/macro-unwind.rkt +++ b/collects/stepper/private/macro-unwind.rkt @@ -59,14 +59,15 @@ [(define-values dc ...) (unwind-define stx settings)] ; STC: app special cases from lazy racket - ; procedure-extract-target - can't hide this in lazy.rkt bc it's needed + ; extract-if-lazy-proc - can't hide this in lazy.rkt bc it's needed ; to distinguish the general lazy application [(#%plain-app proc-extract p) - (or (eq? (syntax->datum #'proc-extract) 'procedure-extract-target) - (eq? (with-handlers ; for print output-style - ([(λ (e) #t) (λ (e) #f)]) - (syntax-e (second (syntax-e #'proc-extract)))) - procedure-extract-target)) + (or (eq? (syntax->datum #'proc-extract) 'extract-if-lazy-proc) + (eq? (object-name + (with-handlers ; for print output-style + ([(λ (e) #t) (λ (e) #f)]) + (syntax-e (second (syntax-e #'proc-extract))))) + 'extract-if-lazy-proc)) (unwind #'p settings)] ; lazy #%app special case: force and delay [(#%plain-app f arg) @@ -80,7 +81,7 @@ [(#%plain-app (#%plain-lambda args1 (#%plain-app (#%plain-app proc p) . args2)) . args3) - (and (eq? (syntax->datum #'proc) 'procedure-extract-target) + (and (eq? (syntax->datum #'proc) 'extract-if-lazy-proc) (equal? (syntax->datum (cdr (syntax-e #'args1))) (syntax->datum #'args2))) (recur-on-pieces #'args3 settings)] diff --git a/collects/tests/lazy/lang.rkt b/collects/tests/lazy/lang.rkt index 535745cb3b..6d579363d4 100644 --- a/collects/tests/lazy/lang.rkt +++ b/collects/tests/lazy/lang.rkt @@ -68,8 +68,21 @@ (!! (take 1 (cons 0 (error "poof")))) => '(0) )) +(define (misc-tests) + (define-struct a (b c)) + (define-struct d (e f)) + (test + (! (a-b (make-a 1 2))) => 1 + (! (a-c (make-a 1 2))) => 2 + (! (a-b (a 1 2))) => 1 + (! (a-c (a 1 2))) => 2 + (! (a? (a 1 2))) => true + (! (a? (d 1 2))) => false + )) + (provide lang-tests) (define (lang-tests) (! (begin (basic-tests) (list-tests) - (take-tests)))) + (take-tests) + (misc-tests)))) From 5030041385e1014ee41a6c94f3fc98d44ff376a9 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 19 Apr 2011 10:13:32 -0500 Subject: [PATCH 169/746] fix check syntax's stdout so that it can handle specials related to PR 11854 merge to release, please (cherry picked from commit 57b9bcfe38f1e360dde9a82205be30248c561653) --- collects/drracket/private/syncheck/gui.rkt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collects/drracket/private/syncheck/gui.rkt b/collects/drracket/private/syncheck/gui.rkt index 2a82e6540f..0539652b6a 100644 --- a/collects/drracket/private/syncheck/gui.rkt +++ b/collects/drracket/private/syncheck/gui.rkt @@ -1277,11 +1277,13 @@ If the namespace does not, they are colored the unbound color. (cleanup) (custodian-shutdown-all user-custodian)))))] [error-port (send (send the-tab get-error-report-text) get-err-port)] + [output-port (send (send the-tab get-error-report-text) get-out-port)] [init-proc (λ () ; =user= (send the-tab set-breakables (current-thread) (current-custodian)) (set-directory definitions-text) (current-error-port error-port) + (current-output-port output-port) (error-display-handler (λ (msg exn) ;; =user= (parameterize ([current-eventspace drs-eventspace]) From 8c26521524a0e9fff25c1153d4b5481c229f9fdf Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Tue, 19 Apr 2011 14:32:17 -0400 Subject: [PATCH 170/746] fix typo in guide sec 17.3.3 (cherry picked from commit 3e08a611902960c099dab8915a3632f219dac21f) --- collects/scribblings/guide/hash-languages.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/guide/hash-languages.scrbl b/collects/scribblings/guide/hash-languages.scrbl index 4eb2ddcdc5..7d89a19648 100644 --- a/collects/scribblings/guide/hash-languages.scrbl +++ b/collects/scribblings/guide/hash-languages.scrbl @@ -177,7 +177,7 @@ implements and exports the @racket[identity] function, since The @racketmodname[syntax/module-reader] language accepts many optional specifications to adjust other features of the language. For example, an alternate @racketidfont{read} and @racketidfont{read-syntax} for -parsing the language can be spcified with @racket[#:read] and +parsing the language can be specified with @racket[#:read] and @racket[#:read-syntax], respectively. The following @filepath{dollar-racket.rkt} language uses @filepath{dollar.rkt} (see @secref["readtable"]) to build a language that is like From d938e0c9b0cb8eacb6d8ae993432ff30b1f43c6a Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 18 Apr 2011 20:50:15 -0400 Subject: [PATCH 171/746] Refactor to avoid duplicated code. (cherry picked from commit 05d9e1a871de7d68d5ae878b7dc1b3bdd7be28fb) --- collects/typed-scheme/typed-scheme.rkt | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/collects/typed-scheme/typed-scheme.rkt b/collects/typed-scheme/typed-scheme.rkt index 2425f6d66b..5de02dd741 100644 --- a/collects/typed-scheme/typed-scheme.rkt +++ b/collects/typed-scheme/typed-scheme.rkt @@ -3,8 +3,8 @@ (require (for-syntax racket/base ;; these requires are needed since their code ;; appears in the residual program - "typecheck/renamer.rkt" "types/type-table.rkt") - "private/base-special-env.rkt") + "typecheck/renamer.rkt" "types/type-table.rkt" profile) + "private/base-special-env.rkt" ) (provide (rename-out [module-begin #%module-begin] [top-interaction #%top-interaction] @@ -21,14 +21,11 @@ ((dynamic-require 'typed-scheme/private/base-env 'init)) ((dynamic-require 'typed-scheme/private/base-env-numeric 'init))) -(define-syntax (module-begin stx) - (do-standard-inits) - ((dynamic-require 'typed-scheme/core 'mb-core) stx)) +(define-syntax-rule (drivers [name sym] ...) + (begin + (define-syntax (name stx) + (do-standard-inits) + ((dynamic-require 'typed-scheme/core 'sym) stx)) + ...)) -(define-syntax (top-interaction stx) - (do-standard-inits) - ((dynamic-require 'typed-scheme/core 'ti-core) stx)) - -(define-syntax (with-type stx) - (do-standard-inits) - ((dynamic-require 'typed-scheme/core 'wt-core) stx)) +(drivers [module-begin mb-core] [top-interaction ti-core] [with-type wt-core]) From 0d898db859d2379be15978b3383d17c7c5727ba4 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 18 Apr 2011 20:51:24 -0400 Subject: [PATCH 172/746] Remove unused macro. Convert function to macro for inlining. (cherry picked from commit e7beef3f4fd407c7ba7f8d6c46e4f9f37fced091) --- collects/typed-scheme/env/lexical-env.rkt | 27 ++++++++--------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/collects/typed-scheme/env/lexical-env.rkt b/collects/typed-scheme/env/lexical-env.rkt index 1445435d90..6f339ee89d 100644 --- a/collects/typed-scheme/env/lexical-env.rkt +++ b/collects/typed-scheme/env/lexical-env.rkt @@ -16,7 +16,7 @@ (typecheck tc-metafunctions) (except-in (types utils convenience) -> ->*)) -(provide lexical-env with-lexical-env with-lexical-env/extend with-update-type/lexical +(provide lexical-env with-lexical-env with-lexical-env/extend with-lexical-env/extend/props) (p/c [lookup-type/lexical ((identifier?) (prop-env? #:fail (or/c #f (-> any/c #f))) . ->* . (or/c Type/c #f))] @@ -44,26 +44,17 @@ ;; refine the type of i in the lexical env ;; (identifier type -> type) identifier -> environment -(define (update-type/lexical f i [env (lexical-env)]) - ;; do the updating on the given env - ;; (identifier type -> type) identifier environment -> environment - (define (update f k env) - (parameterize - ([current-orig-stx k]) - (let* ([v (lookup-type/lexical k env #:fail (lambda _ Univ))] - [new-v (f k v)] - [new-env (extend env k new-v)]) - new-env))) +;; a macro for inlining :( +(define-syntax-rule (update-type/lexical f i env) ;; check if i is ever the target of a set! (if (is-var-mutated? i) ;; if it is, we do nothing env ;; otherwise, refine the type - (update f i env))) - -;; convenience macro for typechecking in the context of an updated env -(define-syntax with-update-type/lexical - (syntax-rules () - [(_ f i . b) - (with-lexical-env (update-type/lexical f i) . b)])) + (parameterize + ([current-orig-stx i]) + (let* ([v (lookup-type/lexical i env #:fail (lambda _ Univ))] + [new-v (f i v)] + [new-env (extend env i new-v)]) + new-env)))) From 0a8ad31a478c203c86d7940450be71582bcc5357 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 18 Apr 2011 20:52:33 -0400 Subject: [PATCH 173/746] Fix typo. (cherry picked from commit 7ba2b6e100a9075779bdbdc0a540c8b3044587a5) --- collects/typed-scheme/types/subtype.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/typed-scheme/types/subtype.rkt b/collects/typed-scheme/types/subtype.rkt index 4757dfa81c..c182d8752c 100644 --- a/collects/typed-scheme/types/subtype.rkt +++ b/collects/typed-scheme/types/subtype.rkt @@ -294,7 +294,7 @@ [(s (Poly: vs b)) (=> unmatch) (if (null? (fv b)) (subtype* A0 s b) (unmatch))] - ;; rec types, applications and names (that aren't the same + ;; rec types, applications and names (that aren't the same) [((? needs-resolving? s) other) (let ([s* (resolve-once s)]) (if (Type? s*) ;; needed in case this was a name that hasn't been resolved yet From 2da100ba8f95916c8ca9c2d021b7e0225c07fc18 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 18 Apr 2011 20:53:51 -0400 Subject: [PATCH 174/746] Remove useless requires. (cherry picked from commit 51083dbce6bc66305a7d3809097bdaba07c78313) --- collects/typed-scheme/infer/constraints.rkt | 1 - collects/typed-scheme/infer/infer-unit.rkt | 2 +- collects/typed-scheme/private/parse-type.rkt | 2 +- collects/typed-scheme/private/with-types.rkt | 2 +- collects/typed-scheme/rep/type-rep.rkt | 2 +- collects/typed-scheme/typecheck/check-subforms-unit.rkt | 2 +- collects/typed-scheme/typecheck/provide-handling.rkt | 2 +- collects/typed-scheme/typecheck/tc-app.rkt | 2 +- collects/typed-scheme/typecheck/tc-envops.rkt | 2 +- collects/typed-scheme/typecheck/tc-expr-unit.rkt | 2 +- collects/typed-scheme/typecheck/tc-if.rkt | 2 +- collects/typed-scheme/typecheck/tc-lambda-unit.rkt | 2 +- collects/typed-scheme/typecheck/tc-let-unit.rkt | 4 ++-- collects/typed-scheme/typecheck/tc-structs.rkt | 2 +- collects/typed-scheme/typecheck/tc-subst.rkt | 2 +- collects/typed-scheme/typecheck/tc-toplevel.rkt | 2 +- collects/typed-scheme/types/abbrev.rkt | 6 +++--- collects/typed-scheme/types/convenience.rkt | 4 ++-- collects/typed-scheme/types/filter-ops.rkt | 4 ++-- collects/typed-scheme/types/remove-intersect.rkt | 2 +- 20 files changed, 24 insertions(+), 25 deletions(-) diff --git a/collects/typed-scheme/infer/constraints.rkt b/collects/typed-scheme/infer/constraints.rkt index 9b8b5048b1..853dba30e8 100644 --- a/collects/typed-scheme/infer/constraints.rkt +++ b/collects/typed-scheme/infer/constraints.rkt @@ -6,7 +6,6 @@ (utils tc-utils) unstable/sequence unstable/hash "signatures.rkt" "constraint-structs.rkt" - unstable/debug racket/match racket/list) diff --git a/collects/typed-scheme/infer/infer-unit.rkt b/collects/typed-scheme/infer/infer-unit.rkt index 9ea79cec6a..73d7703177 100644 --- a/collects/typed-scheme/infer/infer-unit.rkt +++ b/collects/typed-scheme/infer/infer-unit.rkt @@ -14,7 +14,7 @@ racket/match mzlib/etc racket/trace racket/contract - unstable/sequence unstable/list unstable/debug unstable/hash + unstable/sequence unstable/list unstable/hash racket/list) (import dmap^ constraints^ promote-demote^) diff --git a/collects/typed-scheme/private/parse-type.rkt b/collects/typed-scheme/private/parse-type.rkt index 905c4ece64..d622ef9a57 100644 --- a/collects/typed-scheme/private/parse-type.rkt +++ b/collects/typed-scheme/private/parse-type.rkt @@ -7,7 +7,7 @@ syntax/stx (prefix-in c: scheme/contract) syntax/parse (env type-env-structs tvar-env type-name-env type-alias-env lexical-env index-env) - racket/match unstable/debug + racket/match (for-template scheme/base "colon.ss") ;; needed at this phase for tests (combine-in (prefix-in t: "base-types-extra.ss") "colon.ss") diff --git a/collects/typed-scheme/private/with-types.rkt b/collects/typed-scheme/private/with-types.rkt index 2733010b09..d334893dd6 100644 --- a/collects/typed-scheme/private/with-types.rkt +++ b/collects/typed-scheme/private/with-types.rkt @@ -7,7 +7,7 @@ (prefix-in c: (combine-in racket/contract/regions racket/contract/base))) "extra-procs.rkt" "prims.rkt" syntax/parse racket/block racket/match - unstable/sequence unstable/debug "base-types-extra.rkt" + unstable/sequence "base-types-extra.rkt" (except-in (path-up "env/type-name-env.rkt" "env/type-alias-env.rkt" "infer/infer-dummy.rkt" diff --git a/collects/typed-scheme/rep/type-rep.rkt b/collects/typed-scheme/rep/type-rep.rkt index 7c542d4e5a..feb057b8e3 100644 --- a/collects/typed-scheme/rep/type-rep.rkt +++ b/collects/typed-scheme/rep/type-rep.rkt @@ -4,7 +4,7 @@ (require (utils tc-utils) "rep-utils.rkt" "object-rep.rkt" "filter-rep.rkt" "free-variance.rkt" mzlib/trace racket/match mzlib/etc - scheme/contract unstable/debug + scheme/contract (for-syntax scheme/base syntax/parse)) (define name-table (make-weak-hasheq)) diff --git a/collects/typed-scheme/typecheck/check-subforms-unit.rkt b/collects/typed-scheme/typecheck/check-subforms-unit.rkt index 83b342898e..d05954be31 100644 --- a/collects/typed-scheme/typecheck/check-subforms-unit.rkt +++ b/collects/typed-scheme/typecheck/check-subforms-unit.rkt @@ -3,7 +3,7 @@ (require "../utils/utils.rkt" syntax/kerncase syntax/parse - racket/match unstable/debug + racket/match "signatures.rkt" "tc-metafunctions.rkt" (types utils convenience union subtype) (utils tc-utils) diff --git a/collects/typed-scheme/typecheck/provide-handling.rkt b/collects/typed-scheme/typecheck/provide-handling.rkt index 980a4ac8fb..3fc563fd15 100644 --- a/collects/typed-scheme/typecheck/provide-handling.rkt +++ b/collects/typed-scheme/typecheck/provide-handling.rkt @@ -11,7 +11,7 @@ (utils tc-utils) (for-syntax syntax/parse racket/base) racket/contract/private/provide unstable/list - unstable/debug syntax/id-table racket/dict + syntax/id-table racket/dict racket/syntax scheme/struct-info racket/match "def-binding.rkt" syntax/parse (for-template scheme/base "def-export.rkt" scheme/contract)) diff --git a/collects/typed-scheme/typecheck/tc-app.rkt b/collects/typed-scheme/typecheck/tc-app.rkt index f96c228283..3f58464021 100644 --- a/collects/typed-scheme/typecheck/tc-app.rkt +++ b/collects/typed-scheme/typecheck/tc-app.rkt @@ -5,7 +5,7 @@ "tc-app-helper.rkt" "find-annotation.rkt" "tc-funapp.rkt" "tc-subst.rkt" (prefix-in c: racket/contract) syntax/parse racket/match racket/trace scheme/list - unstable/sequence unstable/debug unstable/list + unstable/sequence unstable/list ;; fixme - don't need to be bound in this phase - only to make tests work scheme/bool racket/unsafe/ops diff --git a/collects/typed-scheme/typecheck/tc-envops.rkt b/collects/typed-scheme/typecheck/tc-envops.rkt index de799dc420..b438e3b21e 100644 --- a/collects/typed-scheme/typecheck/tc-envops.rkt +++ b/collects/typed-scheme/typecheck/tc-envops.rkt @@ -12,7 +12,7 @@ (only-in (env type-env-structs lexical-env) env? update-type/lexical env-map env-props replace-props) scheme/contract racket/match - mzlib/trace unstable/debug unstable/struct + mzlib/trace unstable/struct (typecheck tc-metafunctions) (for-syntax scheme/base)) diff --git a/collects/typed-scheme/typecheck/tc-expr-unit.rkt b/collects/typed-scheme/typecheck/tc-expr-unit.rkt index 2462bec2d9..d42355a8e4 100644 --- a/collects/typed-scheme/typecheck/tc-expr-unit.rkt +++ b/collects/typed-scheme/typecheck/tc-expr-unit.rkt @@ -11,7 +11,7 @@ (only-in (infer infer) restrict) (except-in (utils tc-utils stxclass-util)) (env lexical-env type-env-structs tvar-env index-env) - racket/private/class-internal unstable/debug + racket/private/class-internal (except-in syntax/parse id) unstable/function (only-in srfi/1 split-at)) diff --git a/collects/typed-scheme/typecheck/tc-if.rkt b/collects/typed-scheme/typecheck/tc-if.rkt index f897a9b0a6..3a31c32d76 100644 --- a/collects/typed-scheme/typecheck/tc-if.rkt +++ b/collects/typed-scheme/typecheck/tc-if.rkt @@ -10,7 +10,7 @@ (typecheck tc-envops tc-metafunctions) (types type-table) syntax/kerncase - racket/trace unstable/debug + racket/trace racket/match) ;; if typechecking diff --git a/collects/typed-scheme/typecheck/tc-lambda-unit.rkt b/collects/typed-scheme/typecheck/tc-lambda-unit.rkt index b7a45de271..17772aa724 100644 --- a/collects/typed-scheme/typecheck/tc-lambda-unit.rkt +++ b/collects/typed-scheme/typecheck/tc-lambda-unit.rkt @@ -15,7 +15,7 @@ (types abbrev utils) (env type-env-structs lexical-env tvar-env index-env) (utils tc-utils) - unstable/debug + racket/match) (require (for-template scheme/base "internal-forms.rkt")) diff --git a/collects/typed-scheme/typecheck/tc-let-unit.rkt b/collects/typed-scheme/typecheck/tc-let-unit.rkt index b9da5f9ab8..4a92aca975 100644 --- a/collects/typed-scheme/typecheck/tc-let-unit.rkt +++ b/collects/typed-scheme/typecheck/tc-let-unit.rkt @@ -8,11 +8,11 @@ (env lexical-env type-alias-env global-env type-env-structs) (rep type-rep) syntax/free-vars - ;racket/trace unstable/debug + ;racket/trace racket/match (prefix-in c: racket/contract) (except-in racket/contract -> ->* one-of/c) syntax/kerncase syntax/parse unstable/syntax - unstable/debug + (for-template racket/base "internal-forms.rkt")) diff --git a/collects/typed-scheme/typecheck/tc-structs.rkt b/collects/typed-scheme/typecheck/tc-structs.rkt index 7aa506ef5a..6edcf4eca3 100644 --- a/collects/typed-scheme/typecheck/tc-structs.rkt +++ b/collects/typed-scheme/typecheck/tc-structs.rkt @@ -10,7 +10,7 @@ syntax/kerncase syntax/struct mzlib/trace - unstable/debug + racket/function racket/match (only-in racket/contract diff --git a/collects/typed-scheme/typecheck/tc-subst.rkt b/collects/typed-scheme/typecheck/tc-subst.rkt index f784ba05dc..bb5582d259 100644 --- a/collects/typed-scheme/typecheck/tc-subst.rkt +++ b/collects/typed-scheme/typecheck/tc-subst.rkt @@ -6,7 +6,7 @@ [->* -->*] [one-of/c -one-of/c]) (rep type-rep filter-rep rep-utils) scheme/list - scheme/contract racket/match unstable/match unstable/debug + scheme/contract racket/match unstable/match (for-syntax scheme/base) "tc-metafunctions.rkt") diff --git a/collects/typed-scheme/typecheck/tc-toplevel.rkt b/collects/typed-scheme/typecheck/tc-toplevel.rkt index 1e9cc7623e..ae4a0a6efc 100644 --- a/collects/typed-scheme/typecheck/tc-toplevel.rkt +++ b/collects/typed-scheme/typecheck/tc-toplevel.rkt @@ -2,7 +2,7 @@ (require (rename-in "../utils/utils.rkt" [infer r:infer]) syntax/kerncase - unstable/list racket/syntax syntax/parse unstable/debug + unstable/list racket/syntax syntax/parse mzlib/etc racket/match "signatures.rkt" diff --git a/collects/typed-scheme/types/abbrev.rkt b/collects/typed-scheme/types/abbrev.rkt index d5194b7bfa..7e41e0db3f 100644 --- a/collects/typed-scheme/types/abbrev.rkt +++ b/collects/typed-scheme/types/abbrev.rkt @@ -8,10 +8,10 @@ racket/list racket/match unstable/function - (except-in racket/contract ->* ->) - (prefix-in c: racket/contract) + (except-in racket/contract/base ->* ->) + (prefix-in c: racket/contract/base) (for-syntax racket/base syntax/parse) - (for-template racket/base racket/contract racket/promise racket/tcp racket/flonum) + (for-template racket/base racket/contract/base racket/promise racket/tcp racket/flonum) ;; for base type predicates racket/promise racket/tcp racket/flonum) diff --git a/collects/typed-scheme/types/convenience.rkt b/collects/typed-scheme/types/convenience.rkt index 3c76f116df..7ff5ee56f9 100644 --- a/collects/typed-scheme/types/convenience.rkt +++ b/collects/typed-scheme/types/convenience.rkt @@ -4,9 +4,9 @@ (utils tc-utils) "abbrev.rkt" "numeric-tower.rkt" (only-in scheme/contract current-blame-format) (types comparison printer union subtype utils substitute) - scheme/list racket/match scheme/promise + scheme/list racket/match (for-syntax syntax/parse scheme/base) - unstable/debug syntax/id-table scheme/dict + syntax/id-table scheme/dict racket/trace (for-template scheme/base)) diff --git a/collects/typed-scheme/types/filter-ops.rkt b/collects/typed-scheme/types/filter-ops.rkt index 7476a88f18..3f7832bf0e 100644 --- a/collects/typed-scheme/types/filter-ops.rkt +++ b/collects/typed-scheme/types/filter-ops.rkt @@ -5,9 +5,9 @@ (utils tc-utils) (only-in (infer infer) restrict) "abbrev.rkt" (only-in scheme/contract current-blame-format [-> -->] listof) (types comparison printer union subtype utils remove-intersect) - scheme/list racket/match scheme/promise + scheme/list racket/match (for-syntax syntax/parse scheme/base) - unstable/debug syntax/id-table scheme/dict + syntax/id-table scheme/dict racket/trace (for-template scheme/base)) diff --git a/collects/typed-scheme/types/remove-intersect.rkt b/collects/typed-scheme/types/remove-intersect.rkt index 554a89b9f5..f65229821f 100644 --- a/collects/typed-scheme/types/remove-intersect.rkt +++ b/collects/typed-scheme/types/remove-intersect.rkt @@ -3,7 +3,7 @@ (require "../utils/utils.rkt" (rep type-rep rep-utils) (types union subtype resolve convenience utils) - racket/match mzlib/trace unstable/debug) + racket/match mzlib/trace) (provide (rename-out [*remove remove]) overlap) From 4380e6d01ccc7388ecd8e1b78e1bfb5acf59dac3 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 18 Apr 2011 20:54:17 -0400 Subject: [PATCH 175/746] Use eq? on sequence numbers. (cherry picked from commit 0f30f5d8de67bb80f4873a25228afbd7069d2ad1) --- collects/typed-scheme/types/filter-ops.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/typed-scheme/types/filter-ops.rkt b/collects/typed-scheme/types/filter-ops.rkt index 3f7832bf0e..7621c2a7b1 100644 --- a/collects/typed-scheme/types/filter-ops.rkt +++ b/collects/typed-scheme/types/filter-ops.rkt @@ -146,7 +146,7 @@ (case-lambda [() -top] [(f) f] [fs (make-AndFilter fs)])) - (let loop ([fs (remove-duplicates args equal? #:key Rep-seq)] [result null]) + (let loop ([fs (remove-duplicates args eq? #:key Rep-seq)] [result null]) (if (null? fs) (match result [(list) -top] From 5255446653ce4e46aa946e78154768c38ef929a7 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 18 Apr 2011 20:54:45 -0400 Subject: [PATCH 176/746] Add cache for `resolve-once'. Substantial speedups on "new-metrics.rkt" test. (cherry picked from commit 79061150efbc304ac6b9c3f74ba0ac0df342857e) --- collects/typed-scheme/types/resolve.rkt | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/collects/typed-scheme/types/resolve.rkt b/collects/typed-scheme/types/resolve.rkt index 73767a04ae..8ece6d6bc9 100644 --- a/collects/typed-scheme/types/resolve.rkt +++ b/collects/typed-scheme/types/resolve.rkt @@ -1,7 +1,7 @@ #lang scheme/base (require "../utils/utils.rkt") -(require (rep type-rep) +(require (rep type-rep rep-utils) (env type-name-env) (utils tc-utils) (types utils) @@ -46,12 +46,20 @@ (define (needs-resolving? t) (or (Mu? t) (App? t) (Name? t))) +(define resolver-cache (make-hasheq)) + (define (resolve-once t) - (match t - [(Mu: _ _) (unfold t)] - [(App: r r* s) - (resolve-app r r* s)] - [(Name: _) (resolve-name t)])) + (define seq (Rep-seq t)) + (define r (hash-ref resolver-cache seq #f)) + (or r + (let ([r* (match t + [(Mu: _ _) (unfold t)] + [(App: r r* s) + (resolve-app r r* s)] + [(Name: _) (resolve-name t)])]) + (when r* + (hash-set! resolver-cache seq r*)) + r*))) (define (resolve t) (if (needs-resolving? t) (resolve-once t) t)) From 6a906b01b0a010d6ca6682564384b03310e68db2 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 19 Apr 2011 15:46:19 -0400 Subject: [PATCH 177/746] Add debugging parameter, and wrappers for unstable/debug. (cherry picked from commit eaa63f2d1ef6c0fdec45b504aa6f2f7bcd07b2b5) --- collects/typed-scheme/tc-setup.rkt | 3 ++- collects/typed-scheme/utils/utils.rkt | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/collects/typed-scheme/tc-setup.rkt b/collects/typed-scheme/tc-setup.rkt index 04f05fdb09..0fc8b3013d 100644 --- a/collects/typed-scheme/tc-setup.rkt +++ b/collects/typed-scheme/tc-setup.rkt @@ -57,7 +57,8 @@ (do-time "Local Expand Done") (parameterize ([mutated-vars (find-mutated-vars fully-expanded-stx)] [orig-module-stx (or (orig-module-stx) orig-stx)] - [expanded-module-stx fully-expanded-stx]) + [expanded-module-stx fully-expanded-stx] + [debugging? #f]) (let ([result (checker fully-expanded-stx)]) (do-time "Typechecking Done") . body))))))) diff --git a/collects/typed-scheme/utils/utils.rkt b/collects/typed-scheme/utils/utils.rkt index 47712145bf..2ac08d1f8f 100644 --- a/collects/typed-scheme/utils/utils.rkt +++ b/collects/typed-scheme/utils/utils.rkt @@ -7,11 +7,11 @@ at least theoretically. (require (for-syntax racket/base syntax/parse racket/string) racket/contract racket/require-syntax - racket/provide-syntax racket/unit + racket/provide-syntax racket/unit (prefix-in d: unstable/debug) racket/pretty mzlib/pconvert syntax/parse) ;; to move to unstable -(provide reverse-begin list-update list-set) +(provide reverse-begin list-update list-set debugf debugging? dprintf) (provide ;; optimization @@ -226,3 +226,7 @@ at least theoretically. (if (zero? k) (cons v (cdr l)) (cons (car l) (list-set (cdr l) (sub1 k) v)))) + +(define debugging? (make-parameter #f)) +(define-syntax-rule (debugf f . args) (if (debugging?) (d:debugf f . args) (f . args))) +(define (dprintf . args) (when (debugging?) (apply d:dprintf args))) From a191a15bca1528315fc631650f4704dedf580191 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 19 Apr 2011 18:30:19 -0400 Subject: [PATCH 178/746] Add clever comments. (cherry picked from commit 6c17b01f99473deecea91ffe3435fd6b11819f37) --- collects/typed-scheme/types/abbrev.rkt | 1 + collects/typed-scheme/types/union.rkt | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/collects/typed-scheme/types/abbrev.rkt b/collects/typed-scheme/types/abbrev.rkt index 7e41e0db3f..397f56c471 100644 --- a/collects/typed-scheme/types/abbrev.rkt +++ b/collects/typed-scheme/types/abbrev.rkt @@ -62,6 +62,7 @@ (foldr -pair b l)) (define (untuple t) + ;; FIXME - do we really need resolution here? (match (resolve t) [(Value: '()) null] [(Pair: a b) (cond [(untuple b) => (lambda (l) (cons a l))] diff --git a/collects/typed-scheme/types/union.rkt b/collects/typed-scheme/types/union.rkt index 35a81a51b2..4b2590111e 100644 --- a/collects/typed-scheme/types/union.rkt +++ b/collects/typed-scheme/types/union.rkt @@ -39,7 +39,8 @@ (let ([types (remove-dups (sort (apply append (map flat args)) type Date: Tue, 19 Apr 2011 18:30:42 -0400 Subject: [PATCH 179/746] Add type keys for Struct and StructTop. (cherry picked from commit fe60793b4de78f80e0f12605e9853b6ab6638a6d) --- collects/typed-scheme/rep/type-rep.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/typed-scheme/rep/type-rep.rkt b/collects/typed-scheme/rep/type-rep.rkt index feb057b8e3..37feedd275 100644 --- a/collects/typed-scheme/rep/type-rep.rkt +++ b/collects/typed-scheme/rep/type-rep.rkt @@ -292,7 +292,7 @@ pred-id cert maker-id)] - [#:key #f]) + [#:key 'struct]) ;; A structure type descriptor ;; s : struct @@ -304,7 +304,7 @@ (dt VectorTop () [#:fold-rhs #:base] [#:key 'vector]) (dt HashtableTop () [#:fold-rhs #:base] [#:key 'hash]) (dt MPairTop () [#:fold-rhs #:base] [#:key 'mpair]) -(dt StructTop ([name Struct?]) [#:key #f]) +(dt StructTop ([name Struct?]) [#:key 'struct]) ;; v : Scheme Value (dt Value (v) [#:frees #f] [#:fold-rhs #:base] [#:key (cond [(number? v) 'number] From cf5516849630f6d28b59619e32e43bb2ff9c751c Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 19 Apr 2011 18:33:28 -0400 Subject: [PATCH 180/746] Use `in-hash' explicitly. (cherry picked from commit d459ad47b897fed0c106f78f357744c2558f7819) --- collects/typed-scheme/types/substitute.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/typed-scheme/types/substitute.rkt b/collects/typed-scheme/types/substitute.rkt index e5fcc5abfc..3cedb1f2f9 100644 --- a/collects/typed-scheme/types/substitute.rkt +++ b/collects/typed-scheme/types/substitute.rkt @@ -142,7 +142,7 @@ ;; subst-all : substitution Type -> Type (d/c (subst-all s t) (substitution/c Type? . -> . Type?) - (for/fold ([t t]) ([(v r) s]) + (for/fold ([t t]) ([(v r) (in-hash s)]) (match r [(t-subst img) (substitute img v t)] From f858496f14854df9600806884d468c0bfe7bd37f Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 19 Apr 2011 18:35:55 -0400 Subject: [PATCH 181/746] Avoid resolving types when checking subtyping on structs. This fixes problems with caching, because sometimes we were giving the wrong answer for nested calls to `subtype'. (cherry picked from commit 82e6e9d19eb277be03ffd7b91d4549a61bcd723a) --- collects/typed-scheme/types/subtype.rkt | 43 +++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/collects/typed-scheme/types/subtype.rkt b/collects/typed-scheme/types/subtype.rkt index c182d8752c..e76654ceec 100644 --- a/collects/typed-scheme/types/subtype.rkt +++ b/collects/typed-scheme/types/subtype.rkt @@ -195,6 +195,13 @@ [else (make-arr (apply map (lambda args (make-Union (sort args type List[(cons Number Number)] ;; potentially raises exn:subtype, when the algorithm fails @@ -236,6 +263,18 @@ [((Value: v) (Base: _ _ pred _)) (if (pred v) A0 (fail! s t))] ;; tvars are equal if they are the same variable [((F: t) (F: t*)) (if (eq? t t*) A0 (fail! s t))] + ;; Avoid needing to resolve things that refer to different structs. + ;; Saves us from non-termination + ;; Must happen *before* the sequence cases, which sometimes call `resolve' in match expanders + [((or (? Struct? s1) (NameStruct: s1)) (or (? Struct? s2) (NameStruct: s2))) + (=> unmatch) + (cond [(unrelated-structs s1 s2) + (dprintf "found unrelated structs: ~a ~a\n" s1 s2) + (fail! s t)] + [else (unmatch)])] + ;; just checking if s/t is a struct misses recursive/union/etc cases + [((? (lambda (_) (eq? ks 'struct))) (Base: _ _ _ _)) (fail! s t)] + [((Base: _ _ _ _) (? (lambda (_) (eq? kt 'struct)))) (fail! s t)] ;; sequences are covariant [((Sequence: ts) (Sequence: ts*)) (subtypes* A0 ts ts*)] @@ -328,7 +367,7 @@ [((Hashtable: _ _) (HashtableTop:)) A0] ;; subtyping on structs follows the declared hierarchy [((Struct: nm (? Type? parent) flds proc _ _ _ _) other) - ;(printf "subtype - hierarchy : ~a ~a ~a\n" nm parent other) + ;(dprintf "subtype - hierarchy : ~a ~a ~a\n" nm parent other) (subtype* A0 parent other)] ;; Promises are covariant [((Struct: (== promise-sym) _ (list t) _ _ _ _ _) (Struct: (== promise-sym) _ (list t*) _ _ _ _ _)) (subtype* A0 t t*)] @@ -354,7 +393,7 @@ (cond [(assq n s) => (lambda (spec) (subtype* A (cadr spec) m))] [else (fail! s t)]))] ;; otherwise, not a subtype - [(_ _) (fail! s t) #;(printf "failed")])))])))) + [(_ _) (fail! s t) #;(dprintf "failed")])))])))) (define (type-compare? a b) (and (subtype a b) (subtype b a))) From 5957da6bd9bc604a7420bfd3d2c7ffd2e0d3e75b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 20 Apr 2011 14:25:53 -0600 Subject: [PATCH 182/746] fix typos (cherry picked from commit 499800d96e353b81a87059326fa1a1de5ea303f0) --- collects/scribblings/reference/class.scrbl | 17 +++++++++-------- .../scribblings/reference/serialization.scrbl | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/collects/scribblings/reference/class.scrbl b/collects/scribblings/reference/class.scrbl index d7e04ac10d..f00e97203c 100644 --- a/collects/scribblings/reference/class.scrbl +++ b/collects/scribblings/reference/class.scrbl @@ -1,8 +1,9 @@ #lang scribble/doc @(require "mz.ss" racket/class - (for-syntax racket/base) - (for-label racket/trait)) + (for-syntax racket/base + racket/serialize + racket/trait)) @(begin @@ -369,7 +370,7 @@ calling subclass augmentations of methods (see @defform[(class superclass-expr class-clause ...)]{ -Like @scheme[class*], but omits the @scheme[interface-expr]s, for the case that none are needed. +Like @scheme[class*], but omits the @scheme[_interface-expr]s, for the case that none are needed. @defexamples[ #:eval class-eval @@ -639,20 +640,20 @@ Each @scheme[public], @scheme[override], @scheme[augment], @scheme[public-final], @scheme[override-final], @scheme[augment-final], and @scheme[private] clause in a class declares one or more method names. Each method name must have a -corresponding @scheme[method-definition]. The order of +corresponding @scheme[_method-definition]. The order of @scheme[public], @|etc|, clauses and their corresponding definitions (among themselves, and with respect to other clauses in the class) does not matter. As shown in the grammar for @scheme[class*], a method definition is syntactically restricted to certain procedure forms, as defined by the -grammar for @scheme[method-procedure]; in the last two forms of -@scheme[method-procedure], the body @scheme[id] must be one of the +grammar for @scheme[_method-procedure]; in the last two forms of +@scheme[_method-procedure], the body @scheme[id] must be one of the @scheme[id]s bound by @scheme[let-values] or @scheme[letrec-values]. A -@scheme[method-procedure] expression is not evaluated +@scheme[_method-procedure] expression is not evaluated directly. Instead, for each method, a class-specific method procedure is created; it takes an initial object argument, in addition to the -arguments the procedure would accept if the @scheme[method-procedure] +arguments the procedure would accept if the @scheme[_method-procedure] expression were evaluated directly. The body of the procedure is transformed to access methods and fields through the object argument. diff --git a/collects/scribblings/reference/serialization.scrbl b/collects/scribblings/reference/serialization.scrbl index 3a7ffa4d64..09344bc7b8 100644 --- a/collects/scribblings/reference/serialization.scrbl +++ b/collects/scribblings/reference/serialization.scrbl @@ -110,7 +110,7 @@ elements: @tech{unreadable symbol}. These two are used with either @scheme[namespace-variable-binding] or @scheme[dynamic-require] to obtain deserialization information. See - @scheme[make-deserialization-info] for more information on the + @scheme[make-deserialize-info] for more information on the binding's value. See also @scheme[deserialize-module-guard].} @item{A non-negative exact integer, @scheme[_g-count] that represents the From 1601f8b73edf8acedf87e9f4b2cb99f6971e2827 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 20 Apr 2011 14:25:58 -0600 Subject: [PATCH 183/746] fix gc of ps/pdf/svg cairo-surface stream (cherry picked from commit aed7bdf0c9cd2080911bdf732c4f2e52d2603004) --- collects/racket/draw/unsafe/cairo.rkt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/collects/racket/draw/unsafe/cairo.rkt b/collects/racket/draw/unsafe/cairo.rkt index dfa1d93e5d..876596ccdb 100644 --- a/collects/racket/draw/unsafe/cairo.rkt +++ b/collects/racket/draw/unsafe/cairo.rkt @@ -279,9 +279,11 @@ (lambda (proc w h) (let* ([new-proc (lambda (null bytes len) (proc bytes len))] + [free-cell-box (box #f)] [s (p new-proc #f w h)] - [b (malloc-immobile-cell new-proc)]) - (cairo_surface_set_user_data s cell-key b free-immobile-cell) + [b (malloc-immobile-cell (cons new-proc free-cell-box))]) + (parameterize ([current-sud-box free-cell-box]) + (cairo_surface_set_user_data s cell-key b free-immobile-cell)) s))))) (define-cairo cairo_ps_surface_create_for_stream _stream-surface-proc @@ -293,8 +295,11 @@ _stream-surface-proc #:wrap stream-surface-allocator) +(define current-sud-box (make-parameter #f)) (define-cairo cairo_surface_set_user_data - (_fun _cairo_surface_t _pointer _pointer (_fun #:atomic? #t _pointer -> _void) + (_fun _cairo_surface_t _pointer _pointer + (_fun #:atomic? #t #:keep (lambda (v) (set-box! (current-sud-box) v)) + _pointer -> _void) -> _int)) (define-cairo cairo_ps_surface_set_eps (_fun _cairo_surface_t _bool -> _void) From 45d06c58a65fc201a6f165f0d870c27992d6b0ce Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 21 Apr 2011 00:20:37 -0400 Subject: [PATCH 184/746] Fix undocumented binding. (cherry picked from commit 295cb191cffbfdf0cc4bfd3840994d45cef9747c) --- collects/typed-scheme/scribblings/ts-reference.scrbl | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/typed-scheme/scribblings/ts-reference.scrbl b/collects/typed-scheme/scribblings/ts-reference.scrbl index 196e9ebef8..af6677c826 100644 --- a/collects/typed-scheme/scribblings/ts-reference.scrbl +++ b/collects/typed-scheme/scribblings/ts-reference.scrbl @@ -84,6 +84,7 @@ default in Racket. @defidform[PRegexp] @defidform[Bytes] @defidform[Namespace] +@defidform[Null] @defidform[EOF] @defidform[Continuation-Mark-Set] @defidform[Char] From 4895b6fe267a63c3d4c91d8e2bfea05eaab68576 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 21 Apr 2011 19:37:08 -0500 Subject: [PATCH 185/746] added in recent changes (cherry picked from commit 8655c4a55e50b79b914e04c2c0b4f95c3a56d756) --- doc/release-notes/drracket/HISTORY.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/release-notes/drracket/HISTORY.txt b/doc/release-notes/drracket/HISTORY.txt index 92e3e0e854..f698f2a0b4 100644 --- a/doc/release-notes/drracket/HISTORY.txt +++ b/doc/release-notes/drracket/HISTORY.txt @@ -4,6 +4,12 @@ . Removed the "DrScheme" compatability program. + . Improved the speed of the module browser drawing + + . Added search to the standalone module browser window + + . Minor bug fixes + ------------------------------ Version 5.1 ------------------------------ From 548866996ff72179539567a699da918a14bb530f Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 21 Apr 2011 19:38:30 -0500 Subject: [PATCH 186/746] removed drscheme man page merge to release branch (cherry picked from commit 22e08dde07c78c3315e6217876c8f4e0298b9e89) --- man/man1/drscheme.1 | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 man/man1/drscheme.1 diff --git a/man/man1/drscheme.1 b/man/man1/drscheme.1 deleted file mode 100644 index 371e88ba88..0000000000 --- a/man/man1/drscheme.1 +++ /dev/null @@ -1,24 +0,0 @@ -.\" dummy line -.TH DRSCHEME 1 "May 2010" -.UC 4 -.SH NAME -drscheme \- the Racket programming environment -.SH SYNOPSIS -.B drscheme -[ -.I Xoption ... -] -[ -.I file ... -] -.SH DESCRIPTION -DrScheme is the old name for the Racket programming environment. - -.PP -Running -.B drscheme -is the same as running -.BR drracket . - -.SH SEE ALSO -.BR drracket(1) From 61f3f31b0a2376b917ee31a95f5f593d292310b5 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 21 Apr 2011 21:37:35 -0500 Subject: [PATCH 187/746] fixed a bug in the way PR 11775 was fixed related to PR 11775 pls. merge to release branch (cherry picked from commit 7f9bd528573ddbe5c3b4607e0b9d842e93662427) --- collects/test-engine/test-engine.rkt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/collects/test-engine/test-engine.rkt b/collects/test-engine/test-engine.rkt index 6e9dbb983a..0f7c388594 100644 --- a/collects/test-engine/test-engine.rkt +++ b/collects/test-engine/test-engine.rkt @@ -143,6 +143,7 @@ (define display-event-space #f) (define silent-mode #t) (define test-run-since-last-display? #f) + (define first-test-since-run? #t) (super-instantiate ()) @@ -153,6 +154,7 @@ (define/public (add-analysis a) (send test-info add-analysis a)) (define/public (setup-info style) + (set! first-test-since-run? #t) (set! test-info (make-object (info-class) style))) (define/pubment (setup-display cur-rep event-space) (set! test-display (make-object display-class cur-rep)) @@ -173,7 +175,8 @@ (define/public (summarize-results port) (cond - ((not test-run-since-last-display?)) + ((and (not test-run-since-last-display?) + (not first-test-since-run?))) ((test-execute) (unless test-display (setup-display #f #f)) (send test-display install-info test-info) @@ -191,6 +194,7 @@ (display-results display-rep display-event-space)])))) (else (display-disabled port))) + (set! first-test-since-run? #f) (set! test-run-since-last-display? #f)) (define/private (display-success port event-space count) From fef878523ee42a769cbc50ff5cdd0a4ba14c22fb Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 21 Apr 2011 23:33:07 -0400 Subject: [PATCH 188/746] Fix typo (cherry picked from commit 3f94c3dcfc609de6eadf41e2495a0cb77a2b0b09) --- collects/meta/web/www/index.rkt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/meta/web/www/index.rkt b/collects/meta/web/www/index.rkt index 82f8917aee..ea9d7f7ddd 100644 --- a/collects/meta/web/www/index.rkt +++ b/collects/meta/web/www/index.rkt @@ -56,9 +56,9 @@ @code{#lang web-server/insta ;; A "hello world" web server (define (start request) - (response/xexpr) - '(html - (body "Hello World")))} + (response/xexpr + '(html + (body "Hello World"))))} @desc{This example implements a web server using the @elemcode{web-server/insta} language. Each time a connection is made to the server, the @elemcode{start} function is called to get the HTML to From 72aae5241afc3d7e78e4ee2f04b76d19a602b475 Mon Sep 17 00:00:00 2001 From: John Clements Date: Fri, 22 Apr 2011 14:27:56 -0700 Subject: [PATCH 189/746] updates to history merge to 5.1.1 release (cherry picked from commit b228316a8ad6c7f4676dc71dc95e8eb2523732bd) --- collects/tests/stepper/manual-tests.txt | 2 -- doc/release-notes/stepper/HISTORY.txt | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/collects/tests/stepper/manual-tests.txt b/collects/tests/stepper/manual-tests.txt index b72d6949d7..4b92518e40 100644 --- a/collects/tests/stepper/manual-tests.txt +++ b/collects/tests/stepper/manual-tests.txt @@ -10,8 +10,6 @@ warning when the program window disappears. Try stepping backward and forward through programs with correct and erroneous (syntax errors, runtime errors) executions. -Test programs with syntax errors - Try programs which print snips (print-convert-test.ss) try programs that contain test cases; make sure that the popups behave sensibly. diff --git a/doc/release-notes/stepper/HISTORY.txt b/doc/release-notes/stepper/HISTORY.txt index c47a687563..640c6e0320 100644 --- a/doc/release-notes/stepper/HISTORY.txt +++ b/doc/release-notes/stepper/HISTORY.txt @@ -1,5 +1,10 @@ Stepper ------- + +Changes for v5.1.1: + +None. + Changes for v5.1: Quite a bit of rackety, retabbing, refactoring. There's no longer a closure From baca1d620baa58d8b440957e552858b449527258 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 23 Apr 2011 08:12:56 -0400 Subject: [PATCH 190/746] Fix the bgcolor on the mailman pages. IE misparses a three-digit specification, so use 6 digits there. (cherry picked from commit 7f57fcec7e850e5516b65f515add19b1704c6f63) --- collects/meta/web/stubs/mailman.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/meta/web/stubs/mailman.rkt b/collects/meta/web/stubs/mailman.rkt index 705c71fe24..ec5af6a810 100644 --- a/collects/meta/web/stubs/mailman.rkt +++ b/collects/meta/web/stubs/mailman.rkt @@ -28,7 +28,7 @@ }}) (define (subp . body) (apply div class: 'subp body)) -(define (graytd . body) (apply td bgcolor: "#ddd" body)) +(define (graytd . body) (apply td bgcolor: "#dddddd" body)) (define listinfo @page[#:title @list{Mailing lists: @MM{List-Name}} From aba5580b80e535f74f3f213dbf0b0cd3abe0fe13 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 23 Apr 2011 08:41:15 -0400 Subject: [PATCH 191/746] Add `-j 1' to builds, and `--disable-libffi' to configure. (cherry picked from commit 22603f3f15e761f3c26b74ec52dc5430f952f8fb) --- collects/meta/build/build | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index 4573527f55..bc2353c871 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -1121,7 +1121,7 @@ DO_BUILD() { # inputs -- releasing if [[ "$renice" != "" ]]; then dont_exit _run renice "$renice" "$$"; fi export PLTHOME="$workdir/$installdir" PATH="$PLTHOME/bin:$PATH" - export SETUP_ARGS="-N raco -l- raco setup -U" + export SETUP_ARGS="-N raco -l- raco setup -j 1 -U" # make sure we don't use any planet caches (PLTPLANETDIR is set globally) _rm "$PLTPLANETDIR" @@ -1156,7 +1156,9 @@ DO_BUILD() { # inputs -- releasing else _mcd "$PLTHOME/src/build" machineget LDFLAGS; export LDFLAGS - build_step "configure" ../configure ${configure_args} + # use --disable-libffi so we get the internal copy to build and link + # since not all distros have libffi + build_step "configure" ../configure --disable-libffi ${configure_args} build_step "make both" make both build_step "make install" make plain-install-both build_step "raco setup" "$PLTHOME/bin/racket" $SETUP_ARGS From 498b5d5bf5e292853f77bf32bfb0c86b024f4709 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 23 Apr 2011 08:51:05 -0400 Subject: [PATCH 192/746] Disable xdg-open, since it seems like it suffers from the same problem gnome-open does. Relevant (but not really a solution) to PR 11869. (cherry picked from commit 020946cb2af57a4948ea40f25657c876beeafaab) --- collects/net/sendurl.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/net/sendurl.rkt b/collects/net/sendurl.rkt index 6728deca50..70c60a0471 100644 --- a/collects/net/sendurl.rkt +++ b/collects/net/sendurl.rkt @@ -18,7 +18,7 @@ ;; order matters: the default will be the first of these that is found (define all-unix-browsers '(;; common browsers - xdg-open + ;; xdg-open firefox google-chrome galeon opera mozilla konqueror seamonkey epiphany ;; known browsers camino skipstone From 4f1faf5617d048eced52c9b6eb386f255db70ca8 Mon Sep 17 00:00:00 2001 From: Casey Klein Date: Fri, 22 Apr 2011 04:42:24 -0500 Subject: [PATCH 193/746] Updates Redex history for v5.1.1 release (cherry picked from commit 0414b5e6de771ca05b9a3acba267052ba3168205) --- doc/release-notes/redex/HISTORY.txt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/doc/release-notes/redex/HISTORY.txt b/doc/release-notes/redex/HISTORY.txt index 5e477c17d9..1ff0e43d84 100644 --- a/doc/release-notes/redex/HISTORY.txt +++ b/doc/release-notes/redex/HISTORY.txt @@ -1,3 +1,31 @@ +v5.1.1 + + * changed pattern language to disallow unquote + + * fixed matching of ..._x and ..._!_x within ellipses + + * fixed bugs in stepper's diff highlighting + + * improved rendering of arrows in typesetting + + * added support for unioned metafunction codomains + + * fixed typesetting of the pattern (hole p_0 p_1 ...) + + * added arrow->pict, which shows how reduction relation are rendered + in typesetting + + * added a parameter that provides the default for redex-check's + #:attempts argument + + * changed the random term generator to produce shorter sequences + + * added a Redex model of the system in Jay McCarthy's ICFP '09 paper + "Automatically RESTful Web Applications Or, Marking Modular + Serializable Continuations" to the examples directory + + * resolved PRs 10665, 11174, 11579, 11041, 10837, and 11853 + v5.1 * adds an optional #:pred keyword argument to `test-->>' form From 07269cd0b61e90b3c29cc314ad4583375500653f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 24 Apr 2011 16:35:12 -0600 Subject: [PATCH 194/746] x86 JIT: keep call & ret paired even for a non-tail call from native code to native code; this change provides huge performance improvements for some microbenchmarks Merge to 5.1.1 (cherry picked from commit ac5d4cd40106dbd9e540494b5270354050a00181) --- src/racket/src/jitcall.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/racket/src/jitcall.c b/src/racket/src/jitcall.c index fbe44aa48d..42ddcf7117 100644 --- a/src/racket/src/jitcall.c +++ b/src/racket/src/jitcall.c @@ -614,15 +614,26 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc /* Fast inlined-native jump ok (proc will check argc, if necessary) */ { GC_CAN_IGNORE jit_insn *refr; +#ifdef MZ_USE_JIT_I386 + GC_CAN_IGNORE jit_insn *refxr; +#endif if (num_rands < 0) { /* We need to save argc to manually pop the runstack. So move V1 to R2 and move R0 to V1: */ jit_movr_p(JIT_R2, JIT_V1); jit_movr_p(JIT_V1, JIT_R0); } - refr = jit_patchable_movi_p(JIT_R1, jit_forward()); jit_shuffle_saved_regs(); /* maybe copies V registers to be restored */ +#ifdef MZ_USE_JIT_I386 + /* keep call & ret paired by jumping to where we really + want to return,then back here: */ + refr = jit_jmpi(jit_forward()); + refxr = _jit.x.pc; + jit_base_prolog(); +#else + refr = jit_patchable_movi_p(JIT_R1, jit_forward()); _jit_prolog_again(jitter, 3, JIT_R1); /* saves V registers (or copied V registers) */ +#endif if (num_rands >= 0) { if (nontail_self) { jit_movr_p(JIT_R1, JIT_R0); } jit_movr_p(JIT_R0, JIT_V1); /* closure */ @@ -661,7 +672,12 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc /* self-call function pointer is in R1 */ jit_jmpr(JIT_R1); } +#ifdef MZ_USE_JIT_I386 + mz_patch_ucbranch(refr); + (void)jit_calli(refxr); +#else jit_patch_movi(refr, (_jit.x.pc)); +#endif jit_unshuffle_saved_regs(); /* maybe uncopies V registers */ /* If num_rands < 0, then V1 has argc */ } From 8061414c1a1519076e98019b7e6b65601c20cf43 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 24 Apr 2011 19:05:07 -0600 Subject: [PATCH 195/746] fix configure error that can cause CFLAGS to be ignored Merge to 5.1.1 (cherry picked from commit 4aabaeb7af40006c882eb71ffb830ab6ba7ac157) --- src/configure | 2 +- src/racket/configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/configure b/src/configure index ed1af281db..84f8cddb4f 100755 --- a/src/configure +++ b/src/configure @@ -5201,7 +5201,7 @@ echo "${ECHO_T}$have_libffi" >&6; } else CFLAGS="${OLD_CFLAGS}" PREFLAGS="${PREFLAGS} ${libffi_config_preflags}" - CFLAGS="${COMPFLAGS} ${libffi_config_cflags}" + COMPFLAGS="${COMPFLAGS} ${libffi_config_cflags}" echo "Using installed libffi" OWN_LIBFFI="OFF" fi diff --git a/src/racket/configure.ac b/src/racket/configure.ac index 270737f6ce..6fe1caf674 100644 --- a/src/racket/configure.ac +++ b/src/racket/configure.ac @@ -896,7 +896,7 @@ if test "${enable_libffi}" = "yes" ; then else CFLAGS="${OLD_CFLAGS}" PREFLAGS="${PREFLAGS} ${libffi_config_preflags}" - CFLAGS="${COMPFLAGS} ${libffi_config_cflags}" + COMPFLAGS="${COMPFLAGS} ${libffi_config_cflags}" echo "Using installed libffi" OWN_LIBFFI="OFF" fi From 8e723f1721559b5eb37ede50d0b6dacc5292176a Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Fri, 18 Feb 2011 13:32:28 -0500 Subject: [PATCH 196/746] open output files in text mode (cherry picked from commit 88e0631c7184e5873a1407c7f1cb4289b1588b4c) --- collects/2htdp/batch-io.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/2htdp/batch-io.rkt b/collects/2htdp/batch-io.rkt index 663d087388..b4af560368 100644 --- a/collects/2htdp/batch-io.rkt +++ b/collects/2htdp/batch-io.rkt @@ -124,6 +124,7 @@ (let ([result (not (file-exists? f))]) (with-output-to-file f (lambda () (printf "~a" str)) + #:mode 'text #:exists 'replace) f)) From bd94b49c0dcc1a0ccbce4eafe9c88154f4a9fa48 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 25 Apr 2011 11:05:18 -0400 Subject: [PATCH 197/746] critical bug fix in registration process; please propagate (cherry picked from commit f2a475eb43a894d27aa8c230e8e47cbc154e4b85) --- collects/2htdp/private/check-aux.rkt | 3 ++- collects/2htdp/private/universe.rkt | 6 +++--- collects/2htdp/uchat/server.rkt | 10 +++++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/collects/2htdp/private/check-aux.rkt b/collects/2htdp/private/check-aux.rkt index 35a0408e35..896ae61614 100644 --- a/collects/2htdp/private/check-aux.rkt +++ b/collects/2htdp/private/check-aux.rkt @@ -136,7 +136,8 @@ ;; InPort OutPort (U #f String) -> Void ;; register with the server (define (tcp-register in out name) - (tcp-send out `(REGISTER ((name ,(if name name (symbol->string (gensym 'world))))))) + (define msg `(REGISTER ((name ,(if name name (symbol->string (gensym 'world))))))) + (tcp-send out msg) (define ackn (tcp-receive in)) (unless (equal? ackn '(OKAY)) (raise tcp-eof))) diff --git a/collects/2htdp/private/universe.rkt b/collects/2htdp/private/universe.rkt index 5e77845d5c..f4eca8f378 100644 --- a/collects/2htdp/private/universe.rkt +++ b/collects/2htdp/private/universe.rkt @@ -234,9 +234,9 @@ ;; IPort OPort Sexp -> IWorld (define (create-iworld i o info) - (if (and (pair? info) (string? (car info))) - (make-iworld i o (car info) (cdr info)) - (make-iworld i o (symbol->string (gensym 'iworld)) info))) + (if (string? info) + (make-iworld i o info "info field not available") + (make-iworld i o (symbol->string (gensym 'iworld)) "info field not available"))) ;; Player S-exp -> Void (define (iworld-send p sexp) diff --git a/collects/2htdp/uchat/server.rkt b/collects/2htdp/uchat/server.rkt index 0049cc31cf..0fe94178a8 100644 --- a/collects/2htdp/uchat/server.rkt +++ b/collects/2htdp/uchat/server.rkt @@ -1,6 +1,6 @@ -;; The first three lines of this file were inserted by DrScheme. They record metadata +;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. -#reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname server) (read-case-sensitive #f) (teachpacks ()) (htdp-settings #(#f constructor repeating-decimal #f #t none #f ()))) +#reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname server) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) (require 2htdp/universe) ;; UniState = [Listof IWorld] @@ -91,10 +91,10 @@ ;; Any -> Universe ;; run the chat server -(define (run _) +(define (run debug) (universe '() - (state true) + (state debug) (on-new new-chatter) (on-msg forward))) -(run 0) +(run #true) From 947b39d09b4679ca630ef45db53546fd89f9bcc9 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 25 Apr 2011 11:07:47 -0400 Subject: [PATCH 198/746] history updated (cherry picked from commit 6b7e8442545fbfb068cc7f36e804b26642e11eb3) --- doc/release-notes/teachpack/HISTORY.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/release-notes/teachpack/HISTORY.txt b/doc/release-notes/teachpack/HISTORY.txt index 8eaff4b18f..237bd8cf90 100644 --- a/doc/release-notes/teachpack/HISTORY.txt +++ b/doc/release-notes/teachpack/HISTORY.txt @@ -1,3 +1,8 @@ +------------------------------------------------------------------------ +Version 5.2 [Mon Apr 25 11:07:14 EDT 2011] + +* tiny bug fix in registration process for universe + ------------------------------------------------------------------------ Version 5.1 [Tue Feb 8 13:05:17 EST 2011] From 659cb91c2d43adcb7966ae3a4ef46034e674738d Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 25 Apr 2011 09:30:05 -0400 Subject: [PATCH 199/746] Remove file that was accidentally committed. (cherry picked from commit 7e491392e13a75cd59c476cdcec33e8e1292c3de) --- collects/tests/typed-scheme/dump | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 collects/tests/typed-scheme/dump diff --git a/collects/tests/typed-scheme/dump b/collects/tests/typed-scheme/dump deleted file mode 100644 index 9b6354c716..0000000000 --- a/collects/tests/typed-scheme/dump +++ /dev/null @@ -1,3 +0,0 @@ -676 success(es) 0 failure(s) 0 error(s) 676 test(s) run -fixnum-bounded-expr.rkt failed: optimization log mismatch - From 7b604f37c22bd02d60f388f47b98f7b01b3a065c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 25 Apr 2011 15:49:00 -0600 Subject: [PATCH 200/746] fix CGC ephemeron bug Merge to 5.1.1 (cherry picked from commit 5ae4b0016820e33195066a0d3956102f51991f3f) --- src/racket/src/list.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/racket/src/list.c b/src/racket/src/list.c index b4c3cb045d..186b510e72 100644 --- a/src/racket/src/list.c +++ b/src/racket/src/list.c @@ -3259,7 +3259,7 @@ Scheme_Object *scheme_make_ephemeron(Scheme_Object *key, Scheme_Object *val) Scheme_Ephemeron *e; int can_gc = 1; - if (SCHEME_INTP(val) || !GC_base(val)) + if (SCHEME_INTP(key) || !GC_base(key)) can_gc = 0; if (can_gc) { @@ -3268,12 +3268,12 @@ Scheme_Object *scheme_make_ephemeron(Scheme_Object *key, Scheme_Object *val) e = (Scheme_Ephemeron *)scheme_malloc(sizeof(Scheme_Ephemeron)); } e->so.type = scheme_ephemeron_type; + e->key = key; + e->val = val; if (can_gc) { e->next = ephemerons; ephemerons = e; } - e->key = key; - e->val = val; return (Scheme_Object *)e; #endif From 197eef5b91681f287e7304175639c61f658f2581 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Tue, 26 Apr 2011 20:59:04 -0400 Subject: [PATCH 201/746] protocol damage noted (cherry picked from commit 19937716525af815cb562de08527b9fd8ff42efd) --- doc/release-notes/teachpack/HISTORY.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/release-notes/teachpack/HISTORY.txt b/doc/release-notes/teachpack/HISTORY.txt index 237bd8cf90..d883e3aa67 100644 --- a/doc/release-notes/teachpack/HISTORY.txt +++ b/doc/release-notes/teachpack/HISTORY.txt @@ -2,6 +2,8 @@ Version 5.2 [Mon Apr 25 11:07:14 EDT 2011] * tiny bug fix in registration process for universe + implies incompatibility of protocols between 5.1 programs and + predecessors ------------------------------------------------------------------------ Version 5.1 [Tue Feb 8 13:05:17 EST 2011] From d61b573eb38bb5ec3fd91f66344b57d8cf4cf6c9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 27 Apr 2011 06:09:30 -0600 Subject: [PATCH 202/746] remove `define-wish' from BSL for now Merge to 5.1.1 (cherry picked from commit 4cd0ba277eceb76dc93b34f2defabcd0d9fadde6) --- collects/lang/htdp-beginner.rkt | 2 +- collects/scribblings/htdp-langs/beginner.scrbl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/lang/htdp-beginner.rkt b/collects/lang/htdp-beginner.rkt index 0ea60daa6c..350e0bbf08 100644 --- a/collects/lang/htdp-beginner.rkt +++ b/collects/lang/htdp-beginner.rkt @@ -40,7 +40,7 @@ check-error check-member-of check-range - define-wish + ;; define-wish #%datum #%top-interaction empty true false diff --git a/collects/scribblings/htdp-langs/beginner.scrbl b/collects/scribblings/htdp-langs/beginner.scrbl index 4c91595190..814d7f927e 100644 --- a/collects/scribblings/htdp-langs/beginner.scrbl +++ b/collects/scribblings/htdp-langs/beginner.scrbl @@ -111,7 +111,7 @@ extraction, and type-like queries: The created names must not be the same as a primitive or another defined name.} @; ---------------------------------------------------------------------- - +@;{ ------- COMMENTED OUT FOR NOW --------- @section{@scheme[define-wish]} @defform[(define-wish id)]{ @@ -127,7 +127,7 @@ Wished-for functions are reported in the test report for the current program.} Similar to the above form, defines a wished-for function named @racket[id]. If the wished-for function is called with one value, the result of @scheme[expr] is returned as the default value. } - +} @; ---------------------------------------------------------------------- @section[#:tag "beginner-call"]{Function Calls} From da5e39bb39b11ed89312aba38fb76a632b985195 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 29 Apr 2011 23:46:57 -0400 Subject: [PATCH 203/746] Update version number for the v5.1.1 release --- src/racket/src/schvers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index a40dc65a65..c4dd78f63b 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.1.0.900" +#define MZSCHEME_VERSION "5.1.1" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 1 -#define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 900 +#define MZSCHEME_VERSION_Z 1 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From e5bfc20771e48908c3d6bd3ea98d59d540e2a678 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 29 Apr 2011 23:47:00 -0400 Subject: [PATCH 204/746] New Racket version 5.1.1. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index c577397643..81f8553de1 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 89e40d049d..3e9084d09b 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,0,900 - PRODUCTVERSION 5,1,0,900 + FILEVERSION 5,1,1,0 + PRODUCTVERSION 5,1,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 1, 0, 900\0" + VALUE "FileVersion", "5, 1, 1, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 0, 900\0" + VALUE "ProductVersion", "5, 1, 1, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index b9919e7ccb..97988a213e 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,0,900 - PRODUCTVERSION 5,1,0,900 + FILEVERSION 5,1,1,0 + PRODUCTVERSION 5,1,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 1, 0, 900" + VALUE "FileVersion", "5, 1, 1, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 1, 0, 900" + VALUE "ProductVersion", "5, 1, 1, 0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index 3fddbb5fe7..96ab979e2f 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.1.0.900 = s 'MzObj Class' + MzCOM.MzObj.5.1.1.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.1.0.900' + CurVer = s 'MzCOM.MzObj.5.1.1.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.1.0.900' + ProgID = s 'MzCOM.MzObj.5.1.1.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index d3da583097..4ed96b9150 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index d370cc39f1..4bb7d570d7 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,0,900 - PRODUCTVERSION 5,1,0,900 + FILEVERSION 5,1,1,0 + PRODUCTVERSION 5,1,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 1, 0, 900\0" + VALUE "FileVersion", "5, 1, 1, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 0, 900\0" + VALUE "ProductVersion", "5, 1, 1, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 85f353687c..f5a81f8f50 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,0,900 - PRODUCTVERSION 5,1,0,900 + FILEVERSION 5,1,1,0 + PRODUCTVERSION 5,1,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 1, 0, 900\0" + VALUE "FileVersion", "5, 1, 1, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 0, 900\0" + VALUE "ProductVersion", "5, 1, 1, 0\0" END END BLOCK "VarFileInfo" From 6f8817d06345d21231c5a3263fb3cfb435add7a5 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 30 Apr 2011 02:57:12 -0400 Subject: [PATCH 205/746] v5.1.1 stuff (cherry picked from commit 1f7ac35d8e4207f30afaee22cd83575b44f99cde) --- collects/meta/web/download/data.rkt | 3 ++- collects/meta/web/download/installers.txt | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/collects/meta/web/download/data.rkt b/collects/meta/web/download/data.rkt index 90f3b40a5b..33439f7faa 100644 --- a/collects/meta/web/download/data.rkt +++ b/collects/meta/web/download/data.rkt @@ -1,7 +1,8 @@ #lang racket/base (define -versions+dates- - '(["5.1" "February 2011"] + '(["5.1.1" "April 2011"] + ["5.1" "February 2011"] ["5.0.2" "November 2010"] ["5.0.1" "August 2010"] ["5.0" "June 2010"] diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index 9079a6ade6..5090d8cddf 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -64,6 +64,26 @@ 16M 5.0/racket/racket-5.0-src-mac.dmg 16M 5.0/racket/racket-5.0-src-unix.tgz 20M 5.0/racket/racket-5.0-src-win.zip +11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-linux-f12.sh +11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-linux-ubuntu-jaunty.sh +11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-osx-mac.dmg +7.6M 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-win32.exe +11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-ppc-darwin.sh +11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-ppc-osx-mac.dmg +11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-x86_64-linux-f14.sh +5.9M 5.1.1/racket-textual/racket-textual-5.1.1-src-mac.dmg +5.7M 5.1.1/racket-textual/racket-textual-5.1.1-src-unix.tgz +6.8M 5.1.1/racket-textual/racket-textual-5.1.1-src-win.zip +50M 5.1.1/racket/racket-5.1.1-bin-i386-linux-f12.sh +50M 5.1.1/racket/racket-5.1.1-bin-i386-linux-ubuntu-jaunty.sh +51M 5.1.1/racket/racket-5.1.1-bin-i386-osx-mac.dmg +32M 5.1.1/racket/racket-5.1.1-bin-i386-win32.exe +49M 5.1.1/racket/racket-5.1.1-bin-ppc-darwin.sh +52M 5.1.1/racket/racket-5.1.1-bin-ppc-osx-mac.dmg +50M 5.1.1/racket/racket-5.1.1-bin-x86_64-linux-f14.sh +16M 5.1.1/racket/racket-5.1.1-src-mac.dmg +16M 5.1.1/racket/racket-5.1.1-src-unix.tgz +19M 5.1.1/racket/racket-5.1.1-src-win.zip 11M 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-f12.sh 11M 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-ubuntu-jaunty.sh 11M 5.1/racket-textual/racket-textual-5.1-bin-i386-osx-mac.dmg From 5ed722e14478e2adeed14f1d85686951a61972a9 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 7 Jul 2011 23:37:24 -0600 Subject: [PATCH 206/746] Alpha version number for the v5.1.2 release --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 287f1dfd9a..55caba2563 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.1.1.9" +#define MZSCHEME_VERSION "5.1.1.900" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 1 #define MZSCHEME_VERSION_Z 1 -#define MZSCHEME_VERSION_W 9 +#define MZSCHEME_VERSION_W 900 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 06f42651f5462ab627856abeaf06cd804c77209a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 7 Jul 2011 15:30:45 -0600 Subject: [PATCH 207/746] optimizer repair; `unsafe-c{a,d}r' can be dropped (cherry picked from commit 848bba80a3c9f92052e09bf1737a213233161bb2) --- src/racket/src/list.c | 8 +++++--- src/racket/src/optimize.c | 6 ++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/racket/src/list.c b/src/racket/src/list.c index 4030f86e87..70951b03fb 100644 --- a/src/racket/src/list.c +++ b/src/racket/src/list.c @@ -724,11 +724,13 @@ scheme_init_unsafe_list (Scheme_Env *env) scheme_null->type = scheme_null_type; p = scheme_make_folding_prim(unsafe_car, "unsafe-car", 1, 1, 1); - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_UNARY_INLINED + | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); scheme_add_global_constant ("unsafe-car", p, env); p = scheme_make_folding_prim(unsafe_cdr, "unsafe-cdr", 1, 1, 1); - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_UNARY_INLINED + | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); scheme_add_global_constant ("unsafe-cdr", p, env); p = scheme_make_immed_prim(unsafe_mcar, "unsafe-mcar", 1, 1); @@ -748,7 +750,7 @@ scheme_init_unsafe_list (Scheme_Env *env) scheme_add_global_constant ("unsafe-set-mcdr!", p, env); p = scheme_make_immed_prim(unsafe_unbox, "unsafe-unbox", 1, 1); - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; scheme_add_global_constant("unsafe-unbox", p, env); p = scheme_make_immed_prim(unsafe_unbox_star, "unsafe-unbox*", 1, 1); diff --git a/src/racket/src/optimize.c b/src/racket/src/optimize.c index 9f5a287c49..cf52296c68 100644 --- a/src/racket/src/optimize.c +++ b/src/racket/src/optimize.c @@ -390,6 +390,12 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved, note_match(1, vals, warn_info); if ((vals == 1) || (vals < 0)) { /* can omit an unsafe op */ + int i; + for (i = app->num_args; i--; ) { + if (!scheme_omittable_expr(app->args[i + 1], 1, fuel - 1, resolved, warn_info, + deeper_than + (resolved ? app->num_args : 0))) + return 0; + } return 1; } } From 7fc99aa0b3b4b7513c6628674abbc1c457c0a475 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 8 Jul 2011 06:28:43 -0600 Subject: [PATCH 208/746] make weak taint table actually weak (cherry picked from commit 4392ab7636100493e521cab8def320a574935a0c) --- src/racket/src/syntax.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/racket/src/syntax.c b/src/racket/src/syntax.c index 887af427fe..c37049d23c 100644 --- a/src/racket/src/syntax.c +++ b/src/racket/src/syntax.c @@ -2432,10 +2432,9 @@ static Scheme_Object *taint_intern(Scheme_Object *v) Scheme_Bucket *b; b = scheme_bucket_from_table(taint_intern_table, (const char *)v); - if (b->val) - v = b->val; - else - b->val = v; + if (!b->val) + b->val = scheme_true; + v = (Scheme_Object *)HT_EXTRACT_WEAK(b->key); return v; } From 7d32a27700b722cb5e17eb5db9ec46472712442c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 8 Jul 2011 13:52:08 -0600 Subject: [PATCH 209/746] update Racket release notes for v5.1.2 Merge to v5.1.2 (cherry picked from commit fb5c62d9d7c8705959a8ceef95adce78277560c1) --- doc/release-notes/racket/HISTORY.txt | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index cb0009f39a..23885360dd 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,8 +1,4 @@ -Version 5.1.1.8 -slideshow/pict: added rotate function, and added sxy anf syx - fields to a child structure - -Version 5.1.1.7 +Version 5.1.2, July 2011 Replaced syntax certificates with syntax taints: Added syntax-tainted?, syntax-arm, syntax-disarm, syntax-rearm, syntax-taint, and syntax-protect @@ -12,15 +8,8 @@ Replaced syntax certificates with syntax taints: syntax-protect implicitly Changed the way inspectors are associated to syntax objects and variable references in compiled code -compiler/zo-struct: removed certificate structures; changed - wrapper to have a tamper-status field instead of certs - -Version 5.1.1.5 -racket/function: added identity, thunk, compose1 - -Version 5.1.1.2 Changed "sequence" to include exact nonnegative integers -mzlib/contract: removed following (undocumented) exports: +mzlib/contract: removed (undocumented) exports: chaperone-contract-struct? contract-struct-first-order contract-struct-name @@ -34,7 +23,12 @@ mzlib/contract: removed following (undocumented) exports: opt-contract/info-id synthesized-value unknown? -compiler/zo-struct: added toplevel-map field to lam +racket/function: added identity, thunk, compose1 +slideshow/pict: added rotate function, and added sxy anf syx + fields to a child structure +compiler/zo-struct: removed certificate structures; changed + wrapper to have a tamper-status field instead of certs; + added toplevel-map field to lam Version 5.1.1, May 2011 Enabled single-precision floats by default From fe3ee8cbc5649c3520de0a043ad13282d0c505b4 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 8 Jul 2011 02:21:38 -0600 Subject: [PATCH 210/746] removed merge conflict artifact Merge to release branch (cherry picked from commit 73230537baf50466956b79289729b8e69c4ace9e) --- collects/scribblings/reference/contracts.scrbl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/collects/scribblings/reference/contracts.scrbl b/collects/scribblings/reference/contracts.scrbl index 06c3183706..c71b9c3cc2 100644 --- a/collects/scribblings/reference/contracts.scrbl +++ b/collects/scribblings/reference/contracts.scrbl @@ -2013,8 +2013,3 @@ makes a binary search tree contract, but one that is struct and returns a projection function that checks the contract. } -<<<<<<< HEAD - -======= - ->>>>>>> 0b337dc... rejiggered things to make sure all mzlib/contract exports are documented From 4fbf087e171f23c24ebbe2f30ba78fa0973675d0 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 8 Jul 2011 03:38:33 -0600 Subject: [PATCH 211/746] syntax/parse: add expr/c to main module Merge to release branch (cherry picked from commit 0aecbf97ffc50f4879f5d75d5acc6e2aa15b6aa7) --- collects/syntax/parse.rkt | 6 +- .../syntax/parse/experimental/contract.rkt | 2 +- .../syntax/scribblings/parse/ex-exprc.scrbl | 5 +- .../scribblings/parse/experimental.scrbl | 19 +---- collects/syntax/scribblings/parse/lib.scrbl | 71 +++++++++++++++++++ collects/unstable/scribblings/wrapc.scrbl | 49 +------------ 6 files changed, 81 insertions(+), 71 deletions(-) diff --git a/collects/syntax/parse.rkt b/collects/syntax/parse.rkt index cd71a6b25b..337481d76f 100644 --- a/collects/syntax/parse.rkt +++ b/collects/syntax/parse.rkt @@ -3,11 +3,13 @@ "parse/private/sc.rkt" "parse/private/litconv.rkt" "parse/private/lib.rkt" - "parse/experimental/provide.rkt") + "parse/experimental/provide.rkt" + "parse/experimental/contract.rkt") (provide (except-out (all-from-out "parse/private/sc.rkt") syntax-parser/template parser/rhs) (all-from-out "parse/private/litconv.rkt") (except-out (all-from-out "parse/private/lib.rkt") - static)) + static) + expr/c) (provide-syntax-class/contract [static (syntax-class/c [(-> any/c any/c) (or/c string? symbol? #f)])]) diff --git a/collects/syntax/parse/experimental/contract.rkt b/collects/syntax/parse/experimental/contract.rkt index 4e8e847718..d0d7064e34 100644 --- a/collects/syntax/parse/experimental/contract.rkt +++ b/collects/syntax/parse/experimental/contract.rkt @@ -29,7 +29,7 @@ (#:positive (or/c syntax? string? module-path-index? 'from-macro 'use-site 'unknown) #:negative (or/c syntax? string? module-path-index? - 'from-macro 'same-as-use-site 'unknown) + 'from-macro 'use-site 'unknown) #:name (or/c identifier? string? symbol? #f) #:macro (or/c identifier? string? symbol? #f) #:context (or/c syntax? #f)))]) diff --git a/collects/syntax/scribblings/parse/ex-exprc.scrbl b/collects/syntax/scribblings/parse/ex-exprc.scrbl index d7b7d50dbf..3db0d746ad 100644 --- a/collects/syntax/scribblings/parse/ex-exprc.scrbl +++ b/collects/syntax/scribblings/parse/ex-exprc.scrbl @@ -6,10 +6,7 @@ "parse-common.rkt" (for-label racket/class)) -@title[#:tag "exprc"]{Experimental: Contracts on macro sub-expressions} - -@emph{This section involves facilities that are experimental and -subject to change.} +@title[#:tag "exprc"]{Contracts on macro sub-expressions} Just as procedures often expect certain kinds of values as arguments, macros often have expectations about the expressions they are diff --git a/collects/syntax/scribblings/parse/experimental.scrbl b/collects/syntax/scribblings/parse/experimental.scrbl index e545185f6d..20f079436e 100644 --- a/collects/syntax/scribblings/parse/experimental.scrbl +++ b/collects/syntax/scribblings/parse/experimental.scrbl @@ -13,23 +13,8 @@ The following facilities are experimental. @defmodule[syntax/parse/experimental/contract] -Macros can apply contracts to their sub-expressions using the -@racket[expr/c] syntax class. - -@defproc[(expr/c [contract-expr syntax?] - [#:positive pos-blame 'use-site] - [#:negative neg-blame 'from-macro] - [#:name expr-name #f] - [#:macro macro-name #f] - [#:context ctx #f]) - (attributes c)]{ - -Accepts an expression (@racket[expr]) and computes an attribute -@racket[c] that represents the expression wrapped with the contract -represented by @racket[contract-expr]. - -See @secref{exprc} for an example. -} +This module is deprecated; it reprovides @racket[expr/c] for backward +compatibility. @section{Contracts for syntax classes} diff --git a/collects/syntax/scribblings/parse/lib.scrbl b/collects/syntax/scribblings/parse/lib.scrbl index e9f20d530a..1114c1b930 100644 --- a/collects/syntax/scribblings/parse/lib.scrbl +++ b/collects/syntax/scribblings/parse/lib.scrbl @@ -58,6 +58,77 @@ When used outside of the dynamic extent of a macro transformer (see The attribute @var[value] contains the value the name is bound to. } +@defproc[(expr/c [contract-expr syntax?] + [#:positive pos-blame + (or/c syntax? string? module-path-index? 'from-macro 'use-site 'unknown) + 'use-site] + [#:negative neg-blame + (or/c syntax? string? module-path-index? 'from-macro 'use-site 'unknown) + 'from-macro] + [#:name expr-name (or/c identifier? string? symbol?) #f] + [#:macro macro-name (or/c identifier? string? symbol?) #f] + [#:context ctx (or/c syntax? #f) #, @elem{determined automatically}]) + (attributes c)]{ + +Accepts an expression (@racket[expr]) and computes an attribute +@racket[c] that represents the expression wrapped with the contract +represented by @racket[contract-expr]. + +The contract's positive blame represents the obligations of the +expression being wrapped. The negative blame represents the +obligations of the macro imposing the contract---the ultimate user +of @racket[expr/c]. By default, the positive blame is taken as +the module currently being expanded, and the negative blame is +inferred from the definition site of the macro (itself inferred from +the @racket[context] argument), but both blame locations can be +overridden. + +The @racket[pos-blame] and @racket[neg-blame] arguments are turned +into blame locations as follows: +@itemize[ +@item{If the argument is a string, it is used directly as the blame + label.} +@item{If the argument is syntax, its source location is used + to produce the blame label.} +@item{If the argument is a module path index, its resolved module path + is used.} +@item{If the argument is @racket['from-macro], the macro is inferred + from either the @racket[macro-name] argument (if @racket[macro-name] + is an identifier) or the @racket[context] argument, and the module + where it is @emph{defined} is used as the blame location. If + neither an identifier @racket[macro-name] nor a @racket[context] + argument is given, the location is @racket["unknown"].} +@item{If the argument is @racket['use-site], the module being + expanded is used.} +@item{If the argument is @racket['unknown], the blame label is + @racket["unknown"].} +] + +The @racket[macro-name] argument is used to determine the macro's +binding, if it is an identifier. If @racket[expr-name] is given, +@racket[macro-name] is also included in the contract error message. If +@racket[macro-name] is omitted or @racket[#f], but @racket[context] is +a syntax object, then @racket[macro-name] is determined from +@racket[context]. + +If @racket[expr-name] is not @racket[#f], it is used in the contract's +error message to describe the expression the contract is applied to. + +The @racket[context] argument is used, when necessary, to infer the +macro name for the negative blame party and the contract error +message. The @racket[context] should be either an identifier or a +syntax pair with an identifer in operator position; in either case, +that identifier is taken as the macro ultimately requesting the +contract wrapping. + +See @secref{exprc} for an example. + +@bold{Important:} Make sure when using @racket[expr/c] to use the +@racket[c] attribute. The @racket[expr/c] syntax class does not change how +pattern variables are bound; it only computes an attribute that +represents the checked expression. +} + @section{Literal sets} diff --git a/collects/unstable/scribblings/wrapc.scrbl b/collects/unstable/scribblings/wrapc.scrbl index 9c05bb10de..99cdcd7200 100644 --- a/collects/unstable/scribblings/wrapc.scrbl +++ b/collects/unstable/scribblings/wrapc.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual @(require scribble/struct scribble/decode scribble/eval "utils.rkt" - (for-label racket/base racket/contract unstable/wrapc racket/syntax)) + (for-label racket/base racket/contract unstable/wrapc racket/syntax syntax/parse)) @(define the-eval (make-base-eval)) @(the-eval '(require racket/contract (for-syntax racket/base unstable/wrapc))) @@ -35,52 +35,7 @@ Returns a syntax object representing an expression that applies the contract represented by @racket[contract-expr] to the value produced by @racket[expr]. -The contract's positive blame represents the obligations of the -expression being wrapped. The negative blame represents the -obligations of the macro imposing the contract---the ultimate caller -of @racket[wrap-expr/c]. By default, the positive blame is taken as -the module currently being expanded, and the negative blame is -inferred from the definition site of the macro (itself inferred from -the @racket[context] argument). But both blame locations can be -overridden. - -Positive and negative blame locations are determined from -@racket[pos-blame] and @racket[neg-blame], respectively, as follows: -@itemize[ -@item{If the argument is a string, it is used directly as the blame -label.} -@item{If the argument is syntax, its source location is used -to produce the blame label.} -@item{If the argument is a module path index, its resolved module path -is used.} -@item{If the argument is @racket['from-macro], the macro is inferred -from either the @racket[macro-name] argument (if @racket[macro-name] -is an identifier) or the @racket[context] argument, and the module -where it is @emph{defined} is used as the negative blame location. If -neither an identifier @racket[macro-name] nor a @racket[context] -argument is given, the location is @racket["unknown"].} -@item{If the argument is @racket['use-site], the module being -expanded is used.} -@item{If the argument is @racket['unknown], the blame label is -@racket["unknown"].} -] - -The @racket[macro-name] argument is used to determine the macro's -binding, if it is an identifier. If @racket[expr-name] is given, -@racket[macro-name] is also included in the contract error message. If -@racket[macro-name] is omitted or @racket[#f], but @racket[context] is -a syntax object, then @racket[macro-name] is determined from -@racket[context]. - -If @racket[expr-name] is not @racket[#f], it is used in the contract's -error message to describe the expression the contract is applied to. - -The @racket[context] argument is used, when necessary, to infer the -macro name for the negative blame party and the contract error -message. The @racket[context] should be either an identifier or a -syntax pair with an identifer in operator position; in either case, -that identifier is taken as the macro ultimately requesting the -contract wrapping. +The other arguments have the same meaning as for @racket[expr/c]. @examples[#:eval the-eval (define-syntax (myparameterize1 stx) From f468769a75a9c8043ff4881b1b1e8e881490f0ce Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Thu, 7 Jul 2011 00:39:30 -0400 Subject: [PATCH 212/746] Catches another way images prints. (cherry picked from commit ff1ab35a12d9a3360cbbffd21bf62bc26aa8a59e) --- collects/lang/private/rewrite-error-message.rkt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collects/lang/private/rewrite-error-message.rkt b/collects/lang/private/rewrite-error-message.rkt index 514ac3ebe5..8ac58a7340 100755 --- a/collects/lang/private/rewrite-error-message.rkt +++ b/collects/lang/private/rewrite-error-message.rkt @@ -78,6 +78,8 @@ (lambda (all one) "expects a ")) (list #rx"list or cyclic list" (lambda (all) "list")) + (list (regexp-quote "#(struct:object:image% ...)") + (lambda (all) "an image")) (list (regexp-quote "#(struct:object:image-snip% ...)") (lambda (all) "an image")) (list (regexp-quote "#(struct:object:cache-image-snip% ...)") From ae6cf4da07b7b92432eaedafd115eea72d0c0adb Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Thu, 7 Jul 2011 00:41:11 -0400 Subject: [PATCH 213/746] Little tweaks to the *SL documentation (cherry picked from commit 91d5c924158250e39a3a555a5416c3ab591c40c3) --- collects/scribblings/htdp-langs/advanced.scrbl | 5 ++++- collects/scribblings/htdp-langs/beginner-abbr.scrbl | 7 +++++-- collects/scribblings/htdp-langs/beginner.scrbl | 2 +- collects/scribblings/htdp-langs/htdp-langs.scrbl | 2 +- collects/scribblings/htdp-langs/intermediate-lambda.scrbl | 5 ++++- collects/scribblings/htdp-langs/intermediate.scrbl | 5 ++++- collects/teachpack/error-composition.scrbl | 5 +++-- 7 files changed, 22 insertions(+), 9 deletions(-) diff --git a/collects/scribblings/htdp-langs/advanced.scrbl b/collects/scribblings/htdp-langs/advanced.scrbl index bfff957080..1edfd1eafc 100644 --- a/collects/scribblings/htdp-langs/advanced.scrbl +++ b/collects/scribblings/htdp-langs/advanced.scrbl @@ -2,7 +2,7 @@ @(require "common.rkt" "std-grammar.rkt" "prim-ops.rkt" (for-label lang/htdp-advanced)) -@title[#:style 'toc #:tag "advanced"]{Advanced Student} +@title[#:tag "advanced"]{Advanced Student} @declare-exporting[lang/htdp-advanced] @@ -266,6 +266,9 @@ Like @racket[when], but the @racket[body-expression] is evaluated when the @section[#:tag "advanced-common-syntax"]{Common Syntax} +The following syntaxes behave the same in the @emph{Advanced} +level as they did in the @secref["intermediate-lam"] level. + @(intermediate-forms lambda quote diff --git a/collects/scribblings/htdp-langs/beginner-abbr.scrbl b/collects/scribblings/htdp-langs/beginner-abbr.scrbl index 300ebdc800..9fa8c600e3 100644 --- a/collects/scribblings/htdp-langs/beginner-abbr.scrbl +++ b/collects/scribblings/htdp-langs/beginner-abbr.scrbl @@ -4,7 +4,7 @@ -@title[#:style 'toc #:tag "beginner-abbr"]{Beginning Student with List Abbreviations} +@title[#:tag "beginner-abbr"]{Beginning Student with List Abbreviations} @declare-exporting[lang/htdp-beginner-abbr] @@ -108,7 +108,10 @@ also be written with @racket[unquote-splicing].} @; ---------------------------------------------------------------------- -@section[#:tag "beginner-abbr-common-syntax"]{Common Syntax} +@section[#:tag "beginner-abbr-common-syntax"]{Common Syntaxes} + +The following syntaxes behave the same in the @emph{Beginner with List +Abbreviations} level as they did in the @secref["beginner"] level. @(define-forms/normal define) @(define-form/explicit-lambda define lambda) diff --git a/collects/scribblings/htdp-langs/beginner.scrbl b/collects/scribblings/htdp-langs/beginner.scrbl index e989a85f04..00d23b408e 100644 --- a/collects/scribblings/htdp-langs/beginner.scrbl +++ b/collects/scribblings/htdp-langs/beginner.scrbl @@ -3,7 +3,7 @@ (for-label lang/htdp-beginner)) -@title[#:style 'toc #:tag "beginner"]{Beginning Student} +@title[#:tag "beginner"]{Beginning Student} @declare-exporting[lang/htdp-beginner #:use-sources (lang/htdp-beginner lang/private/teachprims)] diff --git a/collects/scribblings/htdp-langs/htdp-langs.scrbl b/collects/scribblings/htdp-langs/htdp-langs.scrbl index 2e3131b163..345de96d32 100644 --- a/collects/scribblings/htdp-langs/htdp-langs.scrbl +++ b/collects/scribblings/htdp-langs/htdp-langs.scrbl @@ -1,7 +1,7 @@ #lang scribble/doc @(require "common.rkt" (for-label lang/htdp-beginner)) -@title[#:tag "top"]{@italic{How to Design Programs} Languages} +@title[#:style 'toc #:tag "top"]{@italic{How to Design Programs} Languages} The languages documented in this manual are provided by DrRacket to be used with the @italic{@link["http://www.htdp.org/"]{How to Design diff --git a/collects/scribblings/htdp-langs/intermediate-lambda.scrbl b/collects/scribblings/htdp-langs/intermediate-lambda.scrbl index 979ba4ad2c..c4946f79df 100644 --- a/collects/scribblings/htdp-langs/intermediate-lambda.scrbl +++ b/collects/scribblings/htdp-langs/intermediate-lambda.scrbl @@ -2,7 +2,7 @@ @(require "common.rkt" "std-grammar.rkt" "prim-ops.rkt" (for-label lang/htdp-intermediate-lambda)) -@title[#:style 'toc #:tag "intermediate-lam"]{Intermediate Student with Lambda} +@title[#:tag "intermediate-lam"]{Intermediate Student with Lambda} @declare-exporting[lang/htdp-intermediate-lambda] @@ -92,6 +92,9 @@ the function.} @section[#:tag "intm-w-lambda-common-syntax"]{Common Syntax} +The following syntaxes behave the same in the @emph{Intermediate with Lambda} +level as they did in the @secref["intermediate"] level. + @(define-forms/normal define) @(prim-forms ("intermediate-lam") diff --git a/collects/scribblings/htdp-langs/intermediate.scrbl b/collects/scribblings/htdp-langs/intermediate.scrbl index f6d006c662..f3321fde37 100644 --- a/collects/scribblings/htdp-langs/intermediate.scrbl +++ b/collects/scribblings/htdp-langs/intermediate.scrbl @@ -3,7 +3,7 @@ (for-label lang/htdp-intermediate)) -@title[#:style 'toc #:tag "intermediate"]{Intermediate Student} +@title[#:tag "intermediate"]{Intermediate Student} @declare-exporting[lang/htdp-intermediate] @@ -65,6 +65,9 @@ @section[#:tag "intermediate-common-syntax"]{Common Syntax} +The following syntaxes behave the same in the @emph{Intermediate} level as they +did in the @secref["beginner-abbr"] level. + @(define-forms/normal define) @(define-form/explicit-lambda define lambda) diff --git a/collects/teachpack/error-composition.scrbl b/collects/teachpack/error-composition.scrbl index aea7e1e251..7e901ac114 100755 --- a/collects/teachpack/error-composition.scrbl +++ b/collects/teachpack/error-composition.scrbl @@ -101,9 +101,10 @@ not appreciate anyway). @list[@para{function header} @para{@samp{after define}, @samp{after the name}, @samp{after the first argument}, ...}] - @list[@para{keyword} + @list[@para{keyword, form, syntax} @para{mention the construct directly by name, such as - @samp{expected a variable but found a cond}}] + @samp{expected a variable but found a cond}. Use @samp{syntax} + only when talking about many constructs in aggregate.}] @list[@para{built-in} @para{Nothing --- avoid this term}] @list[@para{macro} @para{Nothing --- avoid this term}]]] From cd153042db136a685ee4470e6fb1507541e7c289 Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Fri, 8 Jul 2011 16:55:21 -0400 Subject: [PATCH 214/746] Merged htdp-lib.scblr and teachpacks/error-composition.scrbl into htdp/htdp.scrbl, to form a single manual titled "Implementing HtDP Teachpacks, Libraries, and Customized Teaching Languages" (cherry picked from commit 2c075978fdc4e28be8689300a5d6f8421f3c3447) --- collects/htdp/htdp.scrbl | 94 ++++------ collects/lang/htdp-lib.scrbl | 174 ------------------- collects/lang/info.rkt | 1 - collects/meta/dist-specs.rkt | 1 - collects/meta/web/www/old-techreports.rkt | 1 - collects/teachpack/error-composition.scrbl | 190 --------------------- collects/teachpack/teachpack.scrbl | 2 - 7 files changed, 33 insertions(+), 430 deletions(-) delete mode 100644 collects/lang/htdp-lib.scrbl delete mode 100755 collects/teachpack/error-composition.scrbl diff --git a/collects/htdp/htdp.scrbl b/collects/htdp/htdp.scrbl index c2f02b2441..3b74e16618 100644 --- a/collects/htdp/htdp.scrbl +++ b/collects/htdp/htdp.scrbl @@ -1,75 +1,47 @@ #lang scribble/doc -@(require scribble/manual (for-label scheme)) +@(require scribble/manual + (for-label [except-in racket require] + [only-in lang/htdp-beginner require])) -@title[#:style '(toc) #:tag "htdp"]{How to Design HtDP TeachPacks} +@title[#:style 'toc #:tag "htdp"]{Implementing HtDP Teachpacks, Libraries, and Customized Teaching Languages} -@section{What are TeachPacks} +DrRacket has two different mechanisms for making available additional functions +and functionality to students using the teaching languages. -TeachPacks for "How to Design Programs" provide functionality that extends - the teaching languages for specific exercises. The extensions fit smoothly - to the teaching languages so that students don't get nonsensical error - messages or undocumented language features through the backdoor. -@; ----------------------------------------------------------------------------- -@section{Errors} +@itemize[ +@item{HTdP Teachpacks are added to a student's program by clicking on the +``Language'' menu and selecting ``add Teachpack''. Students can then install a +new Teachpack by clicking ``Add Teachpack to List'' and choosing the Teachpack +file from the filesystem.} -@defmodule[htdp/error] +@item{HTdP Libraries are brought into the student's program using a +@racket[require] statement.}] -To provide uniform error messages from the TeachPacks, this module -provides several functions: +Under the hood, HTdP Teachpacks and HTdP Libraries are implemented the same way, +using normal Racket @secref[#:doc '(lib "scribblings/guide/module.scrbl") "modules"]. -@defproc[(check-arg) void?]{ - } +When implementing an extension intended for students, pay a special attention to +the error messages. The error messages of DrRacket's teaching languages go to +great length to ensure that students are never confronted with messages that +uses vocabulary or phrases the students has not learned yet. The teaching languages +also ensure that students cannot stumble by accident onto challenging or +confusing features intended for professional or for higher-level students. -@defproc[(check-arity) void?]{ - } +This manual describes library support for authors of HTdP Teachpacks, libraries, +and customized teaching languages. Use the HTdP +@seclink["error-reporting"]{error reporting functions} to create error messages +that integrate smoothly with those of the teaching languages. Before composing +new error messages, we recommend you read the @seclink["error-guidelines"]{error +message composition guidelines} that informed the design of the error messages +of DrRacket's teaching languages. -@defproc[(check-proc) void?]{ - } +@local-table-of-contents[#:style 'immediate-only] -@defproc[(check-result) void?]{ - } -@defproc[(check-list-list) void?]{ - } +@include-section["error-composition.scrbl"] -@defproc[(check-color) void?]{ - } - -@defproc[(check-fun-res) void?]{ - } - -@defproc[(check-dependencies) void?]{ - } - -@defproc[(natural?) void?]{ - } - -@defproc[(find-non) void?]{ - } - -@defproc[(tp-exn?) void?]{ - } - -@defproc[(number->ord) void?]{ - } - -@section{Testing} - -@; ----------------------------------------------------------------------------- -@defmodule[htdp/testing #:use-sources (test-engine/scheme-tests)] - -The library re-exports the following identifiers from test-engine/scheme-tests: - - @racket[build-test-engine] - @racket[builder] - @racket[display-results] - @racket[error-handler] - @racket[exn:fail:wish] - @racket[generate-report] - @racket[get-test-engine] - @racket[reset-tests] - @racket[run-tests] - @racket[scheme-test-data] - @racket[signature-test-info%] +@include-section["error-reporting.scrbl"] +@include-section["testing.scrbl"] +@include-section["htdp-lib.scrbl"] diff --git a/collects/lang/htdp-lib.scrbl b/collects/lang/htdp-lib.scrbl deleted file mode 100644 index 611a2d2b60..0000000000 --- a/collects/lang/htdp-lib.scrbl +++ /dev/null @@ -1,174 +0,0 @@ -#lang scribble/doc -@(require scribble/manual - scribble/eval - (for-label scheme/base - scheme/contract - scheme/class - scheme/gui/base - lang/posn - lang/imageeq - lang/prim)) - -@(define htdp @italic{How to Design Programs}) -@(define (htdp-ref s) @secref[#:doc '(lib "scribblings/htdp-langs/htdp-langs.scrbl") s]) - -@title{HtDP Languages as Libraries} - -@; ------------------------------------------------------------ -@section{@italic{HtDP} Beginning Student} - -@defmodule[lang/htdp-beginner] - -The @racketmodname[lang/htdp-beginner] module provides the Beginning -Student language for @|htdp|; see @htdp-ref["beginner"]. - -@; ------------------------------------------------------------ -@section{@italic{HtDP} Beginning Student with Abbreviations} - -@defmodule[lang/htdp-beginner-abbr] - -The @racketmodname[lang/htdp-beginner-abbr] module provides the -Beginning Student with Abbreviations language for @|htdp|; see -@htdp-ref["beginner-abbr"]. - -@; ------------------------------------------------------------ -@section{@italic{HtDP} Intermediate Student} - -@defmodule[lang/htdp-intermediate] - -The @racketmodname[lang/htdp-intermediate] module provides the -Intermediate Student language for @|htdp|; see -@htdp-ref["intermediate"]. - -@; ------------------------------------------------------------ -@section{@italic{HtDP} Intermediate Student with Lambda} - -@defmodule[lang/htdp-intermediate-lambda] - -The @racketmodname[lang/htdp-intermediate-lambda] module provides the -Intermediate Student with Lambda language for @|htdp|; see -@htdp-ref["intermediate-lam"]. - -@; ------------------------------------------------------------ -@section{@italic{HtDP} Advanced Student} - -@defmodule[lang/htdp-advanced] - -The @racketmodname[lang/htdp-advanced] module provides the Advanced -Student language for @|htdp|; see @htdp-ref["advanced"]. - -@; ------------------------------------------------------------ -@section{Pretty Big Text (Legacy Language)} - -@defmodule[lang/plt-pretty-big-text] - -The @racketmodname[lang/plt-pretty-big-text] module is similar to the -@italic{HtDP} Advanced Student language, but with more of Racket's -libraries in legacy form. It provides the bindings of -@racketmodname[mzscheme], -@racketmodname[mzlib/etc], @racketmodname[mzlib/file], -@racketmodname[mzlib/list], @racketmodname[mzlib/class], -@racketmodname[mzlib/unit], @racketmodname[mzlib/include], -@racketmodname[mzlib/defmacro], @racketmodname[mzlib/pretty], -@racketmodname[mzlib/string], @racketmodname[mzlib/thread], -@racketmodname[mzlib/math], @racketmodname[mzlib/match], -@racketmodname[mzlib/shared], and @racketmodname[lang/posn]. - -@; ------------------------------------------------------------ - -@section{Pretty Big (Legacy Language)} - -@defmodule[lang/plt-pretty-big] - -The @racketmodname[lang/plt-pretty-big] module extends -@racket[lang/plt-pretty-big-text] with @racketmodname[scheme/gui/base] -and @racketmodname[lang/imageeq]. This language corresponds to the -@onscreen{Pretty Big} legacy language in DrRacket. - -@; ---------------------------------------------------------------------- - -@section{@racket[posn]s in @italic{HtDP} Languages} - -@defmodule[lang/posn] - -@defstruct[posn ([x any/c] [y any/c])]{ - -The @racket[posn] structure type that is also provided by -@racket[lang/htdp-beginner].} - - -@; ---------------------------------------------------------------------- - -@section{Image Equality in @italic{HtDP} Languages} - -@defmodule[lang/imageeq] - -@defproc[(image=? [i1 (is-a?/c image-snip%)] - [i2 (is-a?/c image-snip%)]) - boolean?]{ - -The image-comparison operator that is also provided by -@racket[lang/htdp-beginner].} - -@; ---------------------------------------------------------------------- - -@section{Primitives in @italic{HtDP} Beginner} - -@defmodule[lang/prim] - -The @racketmodname[lang/prim] module several syntactic forms for -use by the implementors of teachpacks, when the teachpack is to be -used with the @|htdp| Beginner Student -languages. In Beginner Student, primitive names (for built-in -procedures) are distinguished from other types of expressions, so that -they can be syntactically restricted to application positions. - -@defform[(define-primitive id proc-id)]{ - - Defines @racket[id] to be a primitive operator whose implementation - is @racket[proc-id], and that takes no procedures as - arguments. Normally, @racket[id] is exported from the teachpack and - @racket[proc-id] is not.} - -@defform[(provide-primitive id)]{ - - Like @racket[define-primitive], but the existing function @racket[id] is - exported as the primitive operator named @racket[id]. An alternative - to @racket[define-primitive].} - -@defform[(provide-primitives id ...)]{ - - Multiple-identifier version of @racket[provide-primitive].} - -@defform[(define-higher-order-primitive id proc-id (arg ...))]{ - - Defines @racket[id] to be a primitive operator whose implementation is - @racket[proc-id]. Normally, @racket[id] is exported from the teachpack and - @racket[proc-id] is not. - - For each non-procedure argument, the corresponding @racket[arg] should be - an underscore. For each procedure argument, the corresponding @racket[arg] - should be the usual name of the procedure. - - @as-examples[ - @racketblock[ - (define-higher-order-primitive convert-gui convert-gui/proc (f2c)) - ]] -} - -@defform[(provide-higher-order-primitive id (arg ...))]{ - - Like @racket[define-higher-order-primitive], but the existing function - @racket[id] is exported as the primitive operator named - @racket[id]. An alternative to @racket[define-higher-order-primitive].} - -@defform[(first-order->higher-order expr)]{ - -If @racket[expr] is an identifier for a first-order function (either a -primitive or a function defined within Beginner Student), produces the -function as a value; otherwise, the form is equivalent to -@racket[expr]. - -This form is mainly useful for implementing syntactic forms that, like -the application of a higher-order primitive, allow first-order bindings -to be used in an expression position.} diff --git a/collects/lang/info.rkt b/collects/lang/info.rkt index 58ca64b515..57d5102af0 100644 --- a/collects/lang/info.rkt +++ b/collects/lang/info.rkt @@ -18,4 +18,3 @@ (string-constant how-to-design-programs) (string-constant beginning-student)))) -(define scribblings '(("htdp-lib.scrbl"))) diff --git a/collects/meta/dist-specs.rkt b/collects/meta/dist-specs.rkt index 08d6f99247..13fa0f72f9 100644 --- a/collects/meta/dist-specs.rkt +++ b/collects/meta/dist-specs.rkt @@ -564,7 +564,6 @@ plt-extras :+= (package: "lang/" #:docs "htdp-langs/") ;; -------------------- htdp, tests, teachpacks plt-extras :+= (package: "htdp/") - (doc: "htdp-lib") (- (package: "teachpack/") (collects: "teachpack/deinprogramm/")) (- (package: "2htdp/") "uchat/") ; Matthias doesn't want this in now diff --git a/collects/meta/web/www/old-techreports.rkt b/collects/meta/web/www/old-techreports.rkt index b062e71658..5129478488 100644 --- a/collects/meta/web/www/old-techreports.rkt +++ b/collects/meta/web/www/old-techreports.rkt @@ -176,7 +176,6 @@ (mysterx "*...!" steck "MysterX: Using Windows COM Objects in Scheme") (mzcom "*...!" steck "MzCOM: Scheme as a Windows COM Object") (srfi "*...!" plt "SRFIs: Libraries") - (htdp-lib "*...!" plt "HtDP: Languages as Libraries") (swindle "*...!" plt "Swindle") (syntax "*...!" plt "Syntax: Meta-Programming Helpers") (typed-scheme "*...!" samth "Typed Scheme: Scheme with Static Types") diff --git a/collects/teachpack/error-composition.scrbl b/collects/teachpack/error-composition.scrbl deleted file mode 100755 index 7e901ac114..0000000000 --- a/collects/teachpack/error-composition.scrbl +++ /dev/null @@ -1,190 +0,0 @@ -#lang scribble/doc -@(require scribble/manual scribble/decode (for-label racket/base)) - -@title[#:tag "error-guidelines"]{ - Error Message Composition Guidelines for Student Languages} - -This section lists some guidelines for writing good error messages for -novices, as informed by @seclink["research"]{our research}. Please -follow these guidelines when you write code that is intended for -beginners, including libraries and teachpacks. It ensures that error -messages from your code fits messages from the student languages and -from other teachpacks. - -@(define (samp . text) @splice[@list{@emph{``@splice[text]''}}]) -@(define (word . text) @splice[@list{‘@splice[text]’}]) - -@section{General Guidelines} - -@itemize[ - @item{Frustrated students will peer at the error message for clues on - how to proceed. Avoid offering hints, and avoid proposing any - specific modification. Students will follow well-meaning-but-wrong - advice uncritically, if only because they have no reason to doubt - the authoritative voice of the tool.} - - @item{Be concise and clear. Students give up reading error messages - if the text is too long, uses obscure words, or employs difficult - grammar.}] - -@section{Message Structure and Form} - -@itemize[ - @item{Start the message with the name of the construct whose - constraint is being violated, followed by a colon.} - - @item{State the constraint that was violated (@samp{expected a...}), - then contrast with what was found. For example, @samp{this function - expects two arguments, but found only one}. If needed, explain how - what was found fails to satisfy the constraint. Write somewhat - anthropomorphically with an objective voice that is neither friendly - nor antagonistic.} - - @item{If an expression contains multiple errors, report the leftmost - error first. E.g., the error in @racket{(define 1 2 3)} is - @samp{expected the variable name, but found a number}, not - @samp{expected 2 parts after define, but found 3}. Before raising - an error about a sub-part of a macro, call - @racket[syntax-local-expand-expression] on sub-expressions to its - left, so that such errors are shown first.} - - @item{State the number of parts instead of saying @samp{found too many - parts}. Write the code necessary to make plurals agree.}] - -@section{Vocabulary} - -@subsection{Permitted Words} - -Use only the following vocabulary words to describe code: - -@nested{@word{function}, @word{variable}, @word{argument}, - @word{function body}, @word{expression}, @word{part}, @word{clause}, - @word{top level}, @word{structure name}, @word{type name}, @word{field - name}, @word{binding}.} - -@itemize[ - @item{Use @word{binding} for the square-braced pair in a @racket{let} - and similar binding forms.} - - @item{Use @word{argument} for actual arguments and @word{variable} for - formal arguments in the body of a definition.} - - @item{Use @word{part} when speaking about an s-expression that is not - an expression, either because it is malformed, because it occurs in - a non-expression position, or because it is a valid piece of syntax - for a macro invocation. A well-formed and well-placed call to a - function, primitive, or macro is not a @word{part}, it is an - @word{expression}.}] - -@subsection{Prohibited Words} - -These guidelines use few terms intentionally, emphasizing commonality -among concepts rather than technical precision (which most students do -not appreciate anyway). - -@tabular[ -@list[ - @list[@para{@bold{Instead of}} - @para{@bold{Use}}] - @list[@para{procedure, primitive name, primitive operator, predicate, - selector, constructor} - @para{@samp{function}''}] - @list[@para{s-expression} - @para{@samp{expression}}] - @list[@para{identifier} - @para{@samp{argument} or @samp{variable}, depending on the use - in the program}] - @list[@para{defined name} - @para{@samp{function} or @samp{variable}}] - @list[@para{sequence} - @para{@samp{at least one (in parentheses)}}] - @list[@para{function header} - @para{@samp{after define}, @samp{after the name}, - @samp{after the first argument}, ...}] - @list[@para{keyword, form, syntax} - @para{mention the construct directly by name, such as - @samp{expected a variable but found a cond}. Use @samp{syntax} - only when talking about many constructs in aggregate.}] - @list[@para{built-in} @para{Nothing --- avoid this term}] - @list[@para{macro} @para{Nothing --- avoid this term}]]] - -@subsection{General Vocabulary Guidelines} - -@itemize[ - @item{Avoid modifiers that are not necessary to disambiguate. Write - @word{variable} instead of @word{local variable}, @word{defined - variable}, or @word{input variable}. Write @word{clause} instead of - @word{question-answer clause}. If they appear necessary for - disambiguation, try to find some other way to achieve this (and drop - the modifier).} - - @item{When introducing macros with sub-parts, reuse existing - vocabulary words, such as @word{clause} or @word{binding} (if - appropriate), or just @word{part}, instead of defining new terms.} - - @item{Use @word{name} only when describing the syntax of a definition - form. For example, the define form in BSL should say @samp{expected - at least one variable after the function name}. Outside of the - definition form, simply use the word @word{function} rather than - distinguish between (1) a function, (2) the variable that binds the - function, and (3) the name of that variable. - - [Rationale: Students learn this distinction when they learn about - lambda. The first is the lambda implicit in the definition, the - second is the variable introduced by the definition that can appear - as the first argument to @racket{set!}, the third is the particular - sequence of letters. But BSL should avoid this complexity, and - ASL’s error messages should maintain consistency with BSL.]} - - @item{Avoid introducing technical vocabulary, even if well-known to a - mathematician.}] - -@section{Punctuation} - -@itemize[ - @item{Do not use any punctuation beyond those of the normal English - language. Do not write @litchar{<>} around type names, and do not - write quotes around keywords.}] - -@section{Runtime Behavior} - -@itemize[ - @item{When specifying a function's behavior, say @samp{the function - takes ... and returns ...}} - - @item{When describing a contract violation, say @samp{the function - expects ... but received ...}} - - @item{As much as possible, identify expressions by the value they - evaluate to, e.g. @samp{the value of @racket{(f x)} is 5}. If it is - necessary to explicate evaluation times, the context discusses - mutable state or order of evaluation, then say that the expressions - @samp{evaluate to} a value. Function calls are a special case of - expression. Prefer @samp{the function call returns}, instead of - @samp{it evaluates to}, except when trying to draw attention to the - evaluation of the arguments.}] - -@section[#:tag "research"]{Supporting Research} - -These guidelines arose from a collections of research studies held at -the Worcester Polytechnic Institute, Brown University, and Northeastern -University. Further experiment details and results are described in: -@itemize[ - @item{@hyperlink["http://www.cs.brown.edu/~sk/Publications/Papers/Published/mfk-mind-lang-novice-inter-error-msg/"]{ - Mind Your Language: On Novices' Interactions with Error - Messages} - - This paper reports on a series of studies that explore beginning - students' interactions with the vocabulary and source-expression - highlighting in DrRacket. Our findings demonstrate that the error - message DrRacket's old error messages significantly failed to convey - information accurately to students.} - - @item{@hyperlink["http://www.cs.brown.edu/~sk/Publications/Papers/Published/mfk-measur-effect-error-msg-novice-sigcse/"]{ - Measuring the Effectiveness of Error Messages Designed for - Novice Programmers} - - This paper presents a fine-grained grading rubric for evaluating the - performance of individual error messages. We applied the rubric to - a course worth of student work, which allowed us to characterize - some ways error messages fail.}] diff --git a/collects/teachpack/teachpack.scrbl b/collects/teachpack/teachpack.scrbl index 43c3f5926e..b7efae7404 100644 --- a/collects/teachpack/teachpack.scrbl +++ b/collects/teachpack/teachpack.scrbl @@ -27,5 +27,3 @@ This chapter covers the teachpacks for @italic{How to Design Programs}. @; removed: @include-section["htdc/scribblings/htdc.scrbl"] @include-section["2htdp/scribblings/2htdp.scrbl"] - -@include-section["error-composition.scrbl"] \ No newline at end of file From ec185e60720d43687fe7c673c5fa13765af4f00d Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Fri, 8 Jul 2011 18:36:24 -0400 Subject: [PATCH 215/746] Adding files missing in the previous commit. (cherry picked from commit 9d465ed2987c4fa70aa2be96ff82a09467b5bc3f) --- collects/htdp/error-composition.scrbl | 199 ++++++++++++++++++++++++++ collects/htdp/error-reporting.scrbl | 47 ++++++ collects/htdp/htdp-lib.scrbl | 165 +++++++++++++++++++++ collects/htdp/testing.scrbl | 34 +++++ 4 files changed, 445 insertions(+) create mode 100755 collects/htdp/error-composition.scrbl create mode 100755 collects/htdp/error-reporting.scrbl create mode 100755 collects/htdp/htdp-lib.scrbl create mode 100755 collects/htdp/testing.scrbl diff --git a/collects/htdp/error-composition.scrbl b/collects/htdp/error-composition.scrbl new file mode 100755 index 0000000000..1d3107a898 --- /dev/null +++ b/collects/htdp/error-composition.scrbl @@ -0,0 +1,199 @@ +#lang scribble/doc + +@(require scribble/manual + (for-label [only-in lang/htdp-advanced set!] + [only-in lang/htdp-intermediate let] + [only-in lang/htdp-beginner define] + [only-in racket/base syntax-local-expand-expression] + )) + +@(require scribble/decode) + +@(require [only-in scribble/core table style]) + + +@title[#:tag "error-guidelines"]{Error Message Composition Guidelines} + +This section lists some guidelines for writing good error messages for +novices, as informed by @seclink["research"]{our research}. Please +follow these guidelines when you write code that is intended for +beginners, including libraries and teachpacks. It ensures that error +messages from your code fits messages from the student languages and +from other teachpacks. + +@(define (samp . text) @splice[@list{@emph{``@splice[text]''}}]) +@(define (word . text) @splice[@list{‘@splice[text]’}]) + +@section{General Guidelines} + +@itemize[ + @item{Frustrated students will peer at the error message for clues on + how to proceed. Avoid offering hints, and avoid proposing any + specific modification. Students will follow well-meaning-but-wrong + advice uncritically, if only because they have no reason to doubt + the authoritative voice of the tool.} + + @item{Be concise and clear. Students give up reading error messages + if the text is too long, uses obscure words, or employs difficult + grammar.}] + +@section{Message Structure and Form} + +@itemize[ + @item{Start the message with the name of the construct whose + constraint is being violated, followed by a colon.} + + @item{State the constraint that was violated (@samp{expected a...}), + then contrast with what was found. For example, @samp{this function + expects two arguments, but found only one}. If needed, explain how + what was found fails to satisfy the constraint. Write somewhat + anthropomorphically with an objective voice that is neither friendly + nor antagonistic.} + + @item{If an expression contains multiple errors, report the leftmost + error first. E.g., the error in @racket{(define 1 2 3)} is + @samp{expected the variable name, but found a number}, not + @samp{expected 2 parts after define, but found 3}. Before raising + an error about a sub-part of a macro, call + @racket[syntax-local-expand-expression] on sub-expressions to its + left, so that such errors are shown first.} + + @item{State the number of parts instead of saying @samp{found too many + parts}. Write the code necessary to make plurals agree.}] + +@section{Words For Describing Code} + +Use only the following vocabulary words to describe code: + +@table[(style 'boxed '()) +@list[@list[@para{function} @para{variable} @para{argument} @para{function body}] + @list[@para{expression} @para{part} @para{clause} @para{top level}] + @list[@para{structure name} @para{type name} @para{field name} @para{binding}]]] + +@itemize[ + @item{Use binding for the square-braced pair in a @racket{let} + and similar binding forms.} + + @item{Use @word{argument} for actual arguments and @word{variable} for + formal arguments in the header and body of a definition.} + + @item{Use @word{part} when speaking about an s-expression that is not + an expression, either because it is malformed, because it occurs in + a non-expression position, or because it is a valid piece of syntax + for a macro invocation. A well-formed and well-placed call to a + function, primitive, or macro is not a @word{part}, it is an + @word{expression}.}] + +@section{Words For Describing Runtime Behavior} + +@itemize[ + @item{When specifying a function's behavior, say @samp{the function + takes ... and returns ...}} + + @item{When describing a contract violation, say @samp{the function + expects ... but received ...}} + + @item{As much as possible, identify expressions and the value they evaluate + to, e.g. @samp{the value of @racket{(f x)} is 5}. If it is necessary to + mention evaluation order, such as when the context discusses mutable state, + say that the expression @samp{evaluates to} a value. Function calls + are a special case of expression. Prefer @samp{the function call returns ...} + to @samp{the function call evaluates to ...}, except when trying to draw attention to + the evaluation of the arguments.}] + + +@section{Prohibited Words} + +These guidelines use few terms intentionally, emphasizing commonality +among concepts rather than technical precision (which most students do +not appreciate anyway). + +@table[(style 'boxed '()) +@list[ + @list[@para{@bold{Instead of}} + @para{@bold{Use}}] + @list[@para{procedure, primitive name, primitive operator, predicate, + selector, constructor} + @para{@samp{function}''}] + @list[@para{s-expression} + @para{@samp{expression}}] + @list[@para{identifier} + @para{@samp{argument} or @samp{variable}, depending on the use + in the program}] + @list[@para{defined name} + @para{@samp{function} or @samp{variable}}] + @list[@para{sequence} + @para{@samp{at least one (in parentheses)}}] + @list[@para{function header} + @para{@samp{after define}, @samp{after the name}, + @samp{after the first argument}, ...}] + @list[@para{keyword} + @para{mention the construct directly by name, such as + @samp{expected a variable but found a cond}}] + @list[@para{built-in} @para{Nothing --- avoid this term}] + @list[@para{macro} @para{Nothing --- avoid this term}]]] + +@section{General Vocabulary Guidelines} + +@itemize[ + @item{Avoid modifiers that are not necessary to disambiguate. Write + @word{variable} instead of @word{local variable}, @word{defined + variable}, or @word{input variable}. Write @word{clause} instead of + @word{question-answer clause}. If they appear necessary for + disambiguation, try to find some other way to achieve this (and drop + the modifier).} + + @item{When introducing macros with sub-parts, reuse existing + vocabulary words, such as @word{clause} or @word{binding} (if + appropriate), or just @word{part}, instead of defining new terms.} + + @item{Use @word{name} only when describing the syntax of a definition + form. For example, the define form in BSL should say @samp{expected + at least one variable after the function name}. Outside of the + definition form, simply use the word @word{function} rather than + distinguish between (1) a function, (2) the variable that binds the + function, and (3) the name of that variable. + + [Rationale: Students learn this distinction when they learn about + lambda. The first is the lambda implicit in the definition, the + second is the variable introduced by the definition that can appear + as the first argument to @racket{set!}, the third is the particular + sequence of letters. But BSL should avoid this complexity, and + ASL’s error messages should maintain consistency with BSL.]} + + @item{Avoid introducing technical vocabulary, even if well-known to a + mathematician.}] + +@section{Punctuation} + +@itemize[ + @item{Do not use any punctuation beyond those of the normal English + language. Do not write @litchar{<>} around type names, and do not + write quotes around keywords.}] + +@section[#:tag "research"]{Supporting Research} + +These guidelines arose from a collections of research studies held at +the Worcester Polytechnic Institute, Brown University, and Northeastern +University. Further experiment details and results are described in: +@itemize[ + @item{@hyperlink["http://www.cs.brown.edu/~sk/Publications/Papers/Published/mfk-mind-lang-novice-inter-error-msg/"]{ + Mind Your Language: On Novices' Interactions with Error + Messages} + + This paper reports on a series of studies that explore beginning + students' interactions with the vocabulary and source-expression + highlighting in DrRacket. Our findings demonstrate that the error + message DrRacket's old error messages significantly failed to convey + information accurately to students.} + + @item{@hyperlink["http://www.cs.brown.edu/~sk/Publications/Papers/Published/mfk-measur-effect-error-msg-novice-sigcse/"]{ + Measuring the Effectiveness of Error Messages Designed for + Novice Programmers} + + This paper presents a fine-grained grading rubric for evaluating the + performance of individual error messages. We applied the rubric to + a course worth of student work, which allowed us to characterize + some ways error messages fail.}] + +@; ----------------------------------------------------------------------------- diff --git a/collects/htdp/error-reporting.scrbl b/collects/htdp/error-reporting.scrbl new file mode 100755 index 0000000000..4d46e46f47 --- /dev/null +++ b/collects/htdp/error-reporting.scrbl @@ -0,0 +1,47 @@ +#lang scribble/doc + +@(require scribble/manual) + +@title[#:tag "error-reporting"]{Error Reporting Functions} + +@defmodule[htdp/error] + +To provide uniform error messages from the TeachPacks, this module +provides several functions: + +@defproc[(check-arg) void?]{ + } + +@defproc[(check-arity) void?]{ + } + +@defproc[(check-proc) void?]{ + } + +@defproc[(check-result) void?]{ + } + +@defproc[(check-list-list) void?]{ + } + +@defproc[(check-color) void?]{ + } + +@defproc[(check-fun-res) void?]{ + } + +@defproc[(check-dependencies) void?]{ + } + +@defproc[(natural?) void?]{ + } + +@defproc[(find-non) void?]{ + } + +@defproc[(tp-exn?) void?]{ + } + +@defproc[(number->ord) void?]{ + } + diff --git a/collects/htdp/htdp-lib.scrbl b/collects/htdp/htdp-lib.scrbl new file mode 100755 index 0000000000..7d84f4abf4 --- /dev/null +++ b/collects/htdp/htdp-lib.scrbl @@ -0,0 +1,165 @@ +#lang scribble/doc + +@(require scribble/manual scribble/eval) +@(define (htdp-ref s) @secref[#:doc '(lib "scribblings/htdp-langs/htdp-langs.scrbl") s]) + +@title{HtDP Languages as Libraries} + +@; ------------------------------------------------------------ +@section{@italic{HtDP} Beginning Student} + +@defmodule[lang/htdp-beginner] + +The @racketmodname[lang/htdp-beginner] module provides the Beginning +Student Language; see @htdp-ref["beginner"]. + +@; ------------------------------------------------------------ +@section{@italic{HtDP} Beginning Student with Abbreviations} + +@defmodule[lang/htdp-beginner-abbr] + +The @racketmodname[lang/htdp-beginner-abbr] module provides the +Beginning Student with Abbreviations language; see +@htdp-ref["beginner-abbr"]. + +@; ------------------------------------------------------------ +@section{@italic{HtDP} Intermediate Student} + +@defmodule[lang/htdp-intermediate] + +The @racketmodname[lang/htdp-intermediate] module provides the +Intermediate Student language; see +@htdp-ref["intermediate"]. + +@; ------------------------------------------------------------ +@section{@italic{HtDP} Intermediate Student with Lambda} + +@defmodule[lang/htdp-intermediate-lambda] + +The @racketmodname[lang/htdp-intermediate-lambda] module provides the +Intermediate Student with Lambda language; see +@htdp-ref["intermediate-lam"]. + +@; ------------------------------------------------------------ +@section{@italic{HtDP} Advanced Student} + +@defmodule[lang/htdp-advanced] + +The @racketmodname[lang/htdp-advanced] module provides the Advanced +Student language; see @htdp-ref["advanced"]. + +@; ------------------------------------------------------------ +@section{Pretty Big Text (Legacy Language)} + +@defmodule[lang/plt-pretty-big-text] + +The @racketmodname[lang/plt-pretty-big-text] module is similar to the +@italic{HtDP} Advanced Student language, but with more of Racket's +libraries in legacy form. It provides the bindings of +@racketmodname[mzscheme], +@racketmodname[mzlib/etc], @racketmodname[mzlib/file], +@racketmodname[mzlib/list], @racketmodname[mzlib/class], +@racketmodname[mzlib/unit], @racketmodname[mzlib/include], +@racketmodname[mzlib/defmacro], @racketmodname[mzlib/pretty], +@racketmodname[mzlib/string], @racketmodname[mzlib/thread], +@racketmodname[mzlib/math], @racketmodname[mzlib/match], +@racketmodname[mzlib/shared], and @racketmodname[lang/posn]. + +@; ------------------------------------------------------------ + +@section{Pretty Big (Legacy Language)} + +@defmodule[lang/plt-pretty-big] + +The @racketmodname[lang/plt-pretty-big] module extends +@racket[lang/plt-pretty-big-text] with @racketmodname[scheme/gui/base] +and @racketmodname[lang/imageeq]. This language corresponds to the +@onscreen{Pretty Big} legacy language in DrRacket. + +@; ---------------------------------------------------------------------- + +@section{@racket[posn]s in @italic{HtDP} Languages} + +@defmodule[lang/posn] + +@defstruct[posn ([x any/c] [y any/c])]{ + +The @racket[posn] structure type that is also provided by +@racket[lang/htdp-beginner].} + + +@; ---------------------------------------------------------------------- + +@section{Image Equality in @italic{HtDP} Languages} + +@defmodule[lang/imageeq] + +@defproc[(image=? [i1 (is-a?/c image-snip%)] + [i2 (is-a?/c image-snip%)]) + boolean?]{ + +The image-comparison operator that is also provided by +@racket[lang/htdp-beginner].} + +@; ---------------------------------------------------------------------- + +@section{Primitives in @italic{HtDP} Beginner} + +@defmodule[lang/prim] + +The @racketmodname[lang/prim] module several syntactic forms for +use by the implementors of teachpacks, when the teachpack is to be +used with the Beginner Student +Language. In Beginner Student, primitive names (for built-in +procedures) are distinguished from other types of expressions, so that +they can be syntactically restricted to application positions. + +@defform[(define-primitive id proc-id)]{ + + Defines @racket[id] to be a primitive operator whose implementation + is @racket[proc-id], and that takes no procedures as + arguments. Normally, @racket[id] is exported from the teachpack and + @racket[proc-id] is not.} + +@defform[(provide-primitive id)]{ + + Like @racket[define-primitive], but the existing function @racket[id] is + exported as the primitive operator named @racket[id]. An alternative + to @racket[define-primitive].} + +@defform[(provide-primitives id ...)]{ + + Multiple-identifier version of @racket[provide-primitive].} + +@defform[(define-higher-order-primitive id proc-id (arg ...))]{ + + Defines @racket[id] to be a primitive operator whose implementation is + @racket[proc-id]. Normally, @racket[id] is exported from the teachpack and + @racket[proc-id] is not. + + For each non-procedure argument, the corresponding @racket[arg] should be + an underscore. For each procedure argument, the corresponding @racket[arg] + should be the usual name of the procedure. + + @as-examples[ + @racketblock[ + (define-higher-order-primitive convert-gui convert-gui/proc (f2c)) + ]] +} + +@defform[(provide-higher-order-primitive id (arg ...))]{ + + Like @racket[define-higher-order-primitive], but the existing function + @racket[id] is exported as the primitive operator named + @racket[id]. An alternative to @racket[define-higher-order-primitive].} + +@defform[(first-order->higher-order expr)]{ + +If @racket[expr] is an identifier for a first-order function (either a +primitive or a function defined within Beginner Student), produces the +function as a value; otherwise, the form is equivalent to +@racket[expr]. + +This form is mainly useful for implementing syntactic forms that, like +the application of a higher-order primitive, allow first-order bindings +to be used in an expression position.} diff --git a/collects/htdp/testing.scrbl b/collects/htdp/testing.scrbl new file mode 100755 index 0000000000..43caa5f74d --- /dev/null +++ b/collects/htdp/testing.scrbl @@ -0,0 +1,34 @@ +#lang scribble/doc + +@(require scribble/manual) + +@title{Testing} + +@; ----------------------------------------------------------------------------- +@defmodule[htdp/testing #:use-sources (test-engine/scheme-tests)] + +The library re-exports the following identifiers from test-engine/scheme-tests: + + @racket[build-test-engine] + @racket[builder] + @racket[display-results] + @racket[error-handler] + @racket[exn:fail:wish] + @racket[generate-report] + @racket[get-test-engine] + @racket[reset-tests] + @racket[run-tests] + @racket[scheme-test-data] + @racket[signature-test-info%] + + +@(require scribble/eval + (for-label racket/contract + racket/class + racket/gui/base + lang/posn + lang/imageeq + lang/prim)) + +@(define (htdp-ref s) @secref[#:doc '(lib "scribblings/htdp-langs/htdp-langs.scrbl") s]) + From ec279b706efc2c73e222d01b122d7f51b0622306 Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Fri, 8 Jul 2011 23:34:29 -0400 Subject: [PATCH 216/746] Fixed documentations bugs in scribblings/htdp-langs (cherry picked from commit 9053f8f99b79545cfac54fb77fbcdc555bdb7f7c) --- .../scribblings/htdp-langs/advanced.scrbl | 24 +- .../htdp-langs/beginner-abbr.scrbl | 66 +---- .../scribblings/htdp-langs/beginner.scrbl | 10 +- .../htdp-langs/intermediate-lambda.scrbl | 13 +- .../scribblings/htdp-langs/intermediate.scrbl | 16 +- collects/scribblings/htdp-langs/prim-ops.rkt | 249 ++++++++++-------- 6 files changed, 174 insertions(+), 204 deletions(-) diff --git a/collects/scribblings/htdp-langs/advanced.scrbl b/collects/scribblings/htdp-langs/advanced.scrbl index 1edfd1eafc..2402c36abc 100644 --- a/collects/scribblings/htdp-langs/advanced.scrbl +++ b/collects/scribblings/htdp-langs/advanced.scrbl @@ -91,8 +91,9 @@ @; ---------------------------------------------------------------------- @section[#:tag "advanced-syntax"]{Syntax for Advanced} -In Advanced, @racket[define] and @racket[lambda] can define functions of zero -arguments, and (naturally) function calls can invoke functions of zero arguments. +In Advanced, @racket[set!] can be used to change variables. @racket[define] and +@racket[lambda] can define functions of zero arguments, and function calls can +invoke functions of zero arguments. @defform[(lambda (variable ...) expression)]{ @@ -155,8 +156,8 @@ the @racket[begin] expression is the value of the first @racket[expression].} @defform[(set! variable expression)]{ Evaluates @racket[expression], and then changes the definition @racket[variable] -to have @racket[expression]'s value. The @racket[variable] must be defined or -bound by @racket[define], @racket[letrec], @racket[let*], or @racket[let].} +to have @racket[expression]'s value. The @racket[variable] must be defined +by @racket[define], @racket[letrec], @racket[let*], or @racket[let].} @defform[(delay expression)]{ @@ -243,7 +244,7 @@ and its value is matched against the pattern in each clause, where the clauses a considered in order. The first clause that contains a matching pattern provides an answer @racket[expression] whose value is the result of the whole @racket[match] expression. This @racket[expression] may reference identifiers -bound in the matching pattern. If none of the clauses contains a matching +defined in the matching pattern. If none of the clauses contains a matching pattern, it is an error.} @; ---------------------------------------------------------------------- @@ -264,22 +265,20 @@ Like @racket[when], but the @racket[body-expression] is evaluated when the @racket[test-expression] produces @racket[false] instead of @racket[true].} -@section[#:tag "advanced-common-syntax"]{Common Syntax} +@section[#:tag "advanced-common-syntax"]{Common Syntaxes} The following syntaxes behave the same in the @emph{Advanced} level as they did in the @secref["intermediate-lam"] level. @(intermediate-forms lambda - quote - quasiquote - unquote - unquote-splicing local letrec let* let - time) + time + define + define-struct) @(define-forms/normal define) @@ -305,7 +304,8 @@ level as they did in the @secref["intermediate-lam"] level. check-member-of check-range require - true false) + true false + #:with-beginner-function-call #f) @; ---------------------------------------- diff --git a/collects/scribblings/htdp-langs/beginner-abbr.scrbl b/collects/scribblings/htdp-langs/beginner-abbr.scrbl index 9fa8c600e3..8c44194bf6 100644 --- a/collects/scribblings/htdp-langs/beginner-abbr.scrbl +++ b/collects/scribblings/htdp-langs/beginner-abbr.scrbl @@ -42,69 +42,10 @@ @; ---------------------------------------- -@section[#:tag "beginner-abbr-syntax"]{Syntax for Abbreviations} +@section[#:tag "beginner-abbr-syntax"]{Syntaxes for Beginning Student with List Abbreviations} +@(beginner-abbr-forms quote quasiquote unquote unquote-splicing) -@deftogether[( -@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[name]})] -@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[part]})] -@defform[(quote name)] -@defform/none[(quote part)] -)]{ - -A quoted name is a symbol. A quote part is an abbreviation for a nested lists. - -Normally, this quotation is written with a @litchar{'}, like -@racket['(apple banana)], but it can also be written with @racket[quote], like -@racket[(@#,racket[quote] (apple banana))].} - - -@deftogether[( -@defform/none[(unsyntax @elem{@racketvalfont{`}@racket[name]})] -@defform/none[(unsyntax @elem{@racketvalfont{`}@racket[part]})] -@defform[(quasiquote name)] -@defform/none[(quasiquote part)] -)]{ - -Like @racket[quote], but also allows escaping to expression ``unquotes.'' - -Normally, quasi-quotations are written with a backquote, @litchar{`}, like -@racket[`(apple ,(+ 1 2))], but they can also be written with -@racket[quasiquote], like -@racket[(@#,racket[quasiquote] (apple ,(+ 1 2)))].} - - -@deftogether[( -@defform/none[(unsyntax @elem{@racketvalfont{,}@racket[expression]})] -@defform[(unquote expression)] -)]{ - -Under a single quasiquote, @racketfont{,}@racket[expression] escapes from -the quote to include an evaluated expression whose value is inserted -into the abbreviated list. - -Under multiple quasiquotes, @racketfont{,}@racket[expression] is really -the literal @racketfont{,}@racket[expression], decrementing the quasiquote count -by one for @racket[expression]. - -Normally, an unquote is written with @litchar{,}, but it can also be -written with @racket[unquote].} - - -@deftogether[( -@defform/none[(unsyntax @elem{@racketvalfont[",@"]@racket[expression]})] -@defform[(unquote-splicing expression)] -)]{ - -Under a single quasiquote, @racketfont[",@"]@racket[expression] escapes from -the quote to include an evaluated expression whose result is a list to -splice into the abbreviated list. - -Under multiple quasiquotes, a splicing unquote is like an unquote; -that is, it decrements the quasiquote count by one. - -Normally, a splicing unquote is written with @litchar{,}, but it can -also be written with @racket[unquote-splicing].} @; ---------------------------------------------------------------------- @@ -133,7 +74,8 @@ Abbreviations} level as they did in the @secref["beginner"] level. check-member-of check-range require - true false] + true false + #:with-beginner-function-call #t] @; ---------------------------------------- diff --git a/collects/scribblings/htdp-langs/beginner.scrbl b/collects/scribblings/htdp-langs/beginner.scrbl index 00d23b408e..b14dbbdc49 100644 --- a/collects/scribblings/htdp-langs/beginner.scrbl +++ b/collects/scribblings/htdp-langs/beginner.scrbl @@ -41,6 +41,9 @@ @section[#:tag "beginner-syntax"]{Syntax} +@(define-forms/normal define) +@(define-form/explicit-lambda define lambda) + @deftogether[( @defform/none[(unsyntax @elem{@racketvalfont{'}@racket[name]})] @defform[(quote name)] @@ -49,9 +52,6 @@ A quoted @racket[name] is a symbol. A symbol is a value, just like @racket[0] or @racket[empty].} -@(define-forms/normal define) -@(define-form/explicit-lambda define lambda) - @(prim-forms ("beginner") define lambda @@ -68,7 +68,9 @@ A quoted @racket[name] is a symbol. A symbol is a value, just like check-member-of check-range require - true false) + true false + #:with-beginner-function-call #t + ) @; -------------------------------------------------- diff --git a/collects/scribblings/htdp-langs/intermediate-lambda.scrbl b/collects/scribblings/htdp-langs/intermediate-lambda.scrbl index c4946f79df..8ebd883d1a 100644 --- a/collects/scribblings/htdp-langs/intermediate-lambda.scrbl +++ b/collects/scribblings/htdp-langs/intermediate-lambda.scrbl @@ -76,21 +76,19 @@ the function.} @(intermediate-forms lambda - quote - quasiquote - unquote - unquote-splicing local letrec let* let - time) + time + define + define-struct) @; ---------------------------------------------------------------------- -@section[#:tag "intm-w-lambda-common-syntax"]{Common Syntax} +@section[#:tag "intm-w-lambda-common-syntax"]{Common Syntaxes} The following syntaxes behave the same in the @emph{Intermediate with Lambda} level as they did in the @secref["intermediate"] level. @@ -113,7 +111,8 @@ level as they did in the @secref["intermediate"] level. check-member-of check-range require - true false) + true false + #:with-beginner-function-call #f) @section[#:tag "intm-w-lambda-pre-defined"]{Pre-defined Functions} diff --git a/collects/scribblings/htdp-langs/intermediate.scrbl b/collects/scribblings/htdp-langs/intermediate.scrbl index f3321fde37..c53c14c8c5 100644 --- a/collects/scribblings/htdp-langs/intermediate.scrbl +++ b/collects/scribblings/htdp-langs/intermediate.scrbl @@ -50,24 +50,25 @@ @section[#:tag "intermediate-syntax"]{Syntax for Intermediate} + @(intermediate-forms lambda - quote - quasiquote - unquote - unquote-splicing local letrec let* let - time) + time + define + define-struct) @; ---------------------------------------------------------------------- -@section[#:tag "intermediate-common-syntax"]{Common Syntax} +@section[#:tag "intermediate-common-syntax"]{Common Syntaxes} The following syntaxes behave the same in the @emph{Intermediate} level as they did in the @secref["beginner-abbr"] level. +@(beginner-abbr-forms quote quasiquote unquote unquote-splicing) + @(define-forms/normal define) @(define-form/explicit-lambda define lambda) @@ -88,7 +89,8 @@ did in the @secref["beginner-abbr"] level. check-member-of check-range require - true false) + true false + #:with-beginner-function-call #t) diff --git a/collects/scribblings/htdp-langs/prim-ops.rkt b/collects/scribblings/htdp-langs/prim-ops.rkt index d65998efd5..1c7b46d5ea 100644 --- a/collects/scribblings/htdp-langs/prim-ops.rkt +++ b/collects/scribblings/htdp-langs/prim-ops.rkt @@ -14,6 +14,7 @@ prim-forms define-forms/normal define-form/explicit-lambda + beginner-abbr-forms intermediate-forms prim-ops prim-op-defns) @@ -135,7 +136,8 @@ check-range require true - false) + false + #:with-beginner-function-call with-beginner-function-call) (gen-prim-forms #'define-struct @racket[define-struct] (list ds-extra ...) #'cond @racket[cond] #'else @racket[else] @@ -148,7 +150,8 @@ #'check-member-of @racket[check-member-of] #'check-range @racket[check-range] #'require @racket[require] - @racket[true] @racket[false])) + @racket[true] @racket[false] + with-beginner-function-call)) (define (gen-prim-forms define-struct-id define-struct-elem ds-extras cond-id cond-elem @@ -162,28 +165,29 @@ check-member-of-id check-member-of-elem check-range-id check-range-elem require-id require-elem - true-elem false-elem) + true-elem false-elem + with-beginner-function-call) (list @; ---------------------------------------------------------------------- @defform*[#:id [define-struct define-struct-id] [(define-struct structure-name (field-name ...))]]{ - Defines a new structure called @racket[field-name]. The structure's fields are + Defines a new structure called @racket[structure-name]. The structure's fields are named by the @racket[field-name]s. After the @define-struct-elem, the following new functions are available: @itemize[ - @item{@racketidfont{make-}@racket[structure-name] : takes in a number of + @item{@racketidfont{make-}@racket[structure-name] : takes a number of arguments equal to the number of fields in the structure, and creates a new instance of that structure.} - @item{@racket[structure-name]@racketidfont{-}@racket[field-name] : takes in an + @item{@racket[structure-name]@racketidfont{-}@racket[field-name] : takes an instance of the structure and returns the value in the field named by @racket[field-name].} - @item{@racket[structure-name]@racketidfont{?} : takes in any value, and returns + @item{@racket[structure-name]@racketidfont{?} : takes any value, and returns @true-elem if the value is an instance of the structure.} ] @@ -212,16 +216,17 @@ @; ---------------------------------------------------------------------- - @defform/none[(name expression expression ...)]{ - - Calls the function named @racket[name]. The value of the call is the - value of @racket[name]'s body when every one of the function's - variables are replaced by the values of the corresponding - @racket[expression]s. - - The function named @racket[name] must defined before it can be called. The - number of argument @racket[expression]s must be the same as the number of arguments - expected by the function.} + @(if with-beginner-function-call + @defform/none[(name expression expression ...)]{ + Calls the function named @racket[name]. The value of the call is the + value of @racket[name]'s body when every one of the function's + variables are replaced by the values of the corresponding + @racket[expression]s. + + The function named @racket[name] must defined before it can be called. The + number of argument @racket[expression]s must be the same as the number of arguments + expected by the function.} + @elem[]) @; ---------------------------------------------------------------------- @@ -232,7 +237,7 @@ ... [#,else-elem answer-expression])]]{ - Chooses a clause base on a condition by finding the first + Chooses a clause based on some condition. @racket[cond] finds the first @racket[question-expression] that evaluates to @true-elem, then evaluates the corresponding @racket[answer-expression]. @@ -241,8 +246,8 @@ @else-elem clause. If there is no @else-elem, @cond-elem reports an error. If the result of a @racket[question-expression] is neither @true-elem nor @false-elem, @cond-elem also reports an error. - - An @defidform/inline[#,else-id] cannot be used outside of @|cond-elem|.} + + @defidform/inline[#,else-id] cannot be used outside of @|cond-elem|.} @; ---------------------------------------------------------------------- @@ -262,7 +267,7 @@ [(and expression expression expression ...)]]{ Evaluates to @true-elem if all the @racket[expression]s are - @|true-elem|. If any @racket[expression] is false, the @and-elem + @|true-elem|. If any @racket[expression] is @|false-elem|, the @and-elem expression immediately evaluates to @false-elem (and the expressions to the right of that expression are not evaluated.) @@ -277,14 +282,15 @@ Evaluates to @true-elem as soon as one of the @racket[expression]s is @true-elem (and the expressions to the right of that - expression are not evaluated.) If all of the @racket[expression]s are false, - the @or-elem expression evaluates to @racket[false]. + expression are not evaluated.) If all of the @racket[expression]s are @|false-elem|, + the @or-elem expression evaluates to @|false-elem|. If any of the expressions evaluate to a value other than @true-elem or @false-elem, @or-elem reports an error.} @; ---------------------------------------------------------------------- + @defform*[#:id [check-expect check-expect-id] [(check-expect expression expected-expression)]]{ @@ -302,12 +308,12 @@ @defform*[#:id [check-error check-error-id] - [(check-error expression expression) + [(check-error expression match-expression) (#,check-error-elem expression)]]{ - Checks that the first @racket[expression] reports an error, - where the error messages matches the string produced by the second - @racket[expression], if it is present.} + Checks that the @racket[expression] reports an error, + where the error messages matches the string produced by the + @racket[matchexpression], if it is present.} @defform*[#:id [check-member-of check-member-of-id] @@ -318,11 +324,11 @@ @defform*[#:id [check-range check-range-id] - [(check-range expression expression expression)]]{ + [(check-range expression low-expression high-expression)]]{ Checks that the first @racket[expression] produces a number in - between the numbers produced by the second and third - @racket[expression]s, inclusive.} + between the numbers produced by @racket[low-expression] and + @racket[high-expression], inclusive.} @; ---------------------------------------------------------------------- @@ -369,111 +375,122 @@ ;; ---------------------------------------- +(define-syntax-rule + (beginner-abbr-forms quote quasiquote unquote unquote-splicing) + (gen-beginner-abbr-forms #'quote @racket[quote] + #'quasiquote @racket[quasiquote] + #'unquote @racket[unquote] + #'unquote-splicing @racket[unquote-splicing])) + +(define (gen-beginner-abbr-forms quote-id quote-elem + quasiquote-id quasiquote-elem + unquote-id unquote-elem + unquote-splicing-id unquote-splicing-elem) + + (list + @deftogether[( + @defform/none[(unsyntax @elem{@racketvalfont{'}@racket[name]})] + @defform/none[(unsyntax @elem{@racketvalfont{'}@racket[part]})] + @defform[#:id [quote quote-id] (quote name)] + @defform/none[(#,quote-elem part)] + )]{ + + A quoted name is a symbol. A quoted part is an abbreviation for a nested lists. + + Normally, this quotation is written with a @litchar{'}, like + @racket['(apple banana)], but it can also be written with + @quote-elem, like @racket[(@#,quote-elem (apple banana))].} + + + @deftogether[( + @defform/none[(unsyntax @elem{@racketvalfont{`}@racket[name]})] + @defform/none[(unsyntax @elem{@racketvalfont{`}@racket[part]})] + @defform[#:id [quasiquote quasiquote-id] + (quasiquote name)] + @defform/none[(#,quasiquote-elem part)] + )]{ + + Like @quote-elem, but also allows escaping to expression + ``unquotes.'' + + Normally, quasi-quotations are written with a backquote, + @litchar{`}, like @racket[`(apple ,(+ 1 2))], but they can also be + written with @quasiquote-elem, like + @racket[(@quasiquote-elem (apple ,(+ 1 2)))].} + + + @deftogether[( + @defform/none[(unsyntax @elem{@racketvalfont{,}@racket[expression]})] + @defform[#:id [unquote unquote-id] + (unquote expression)] + )]{ + + Under a single quasiquote, @racketfont{,}@racket[expression] + escapes from the quote to include an evaluated expression whose + result is inserted into the abbreviated list. + + Under multiple quasiquotes, @racketfont{,}@racket[expression] is + really the literal @racketfont{,}@racket[expression], decrementing + the quasiquote count by one for @racket[expression]. + + Normally, an unquote is written with @litchar{,}, but it can also be + written with @|unquote-elem|.} + + + @deftogether[( + @defform/none[(unsyntax @elem{@racketvalfont[",@"]@racket[expression]})] + @defform[#:id [unquote-splicing unquote-splicing-id] + (unquote-splicing expression)] + )]{ + + Under a single quasiquote, @racketfont[",@"]@racket[expression] + escapes from the quote to include an evaluated expression whose + result is a list to splice into the abbreviated list. + + Under multiple quasiquotes, a splicing unquote is like an unquote; + that is, it decrements the quasiquote count by one. + + Normally, a splicing unquote is written with @litchar{,}, but it + can also be written with @|unquote-splicing-elem|.} + + )) + + (define-syntax-rule (intermediate-forms lambda - quote - quasiquote - unquote - unquote-splicing local letrec let* let - time) + time + define + define-struct) (gen-intermediate-forms #'lambda @racket[lambda] - #'quote @racket[quote] - #'quasiquote @racket[quasiquote] - #'unquote @racket[unquote] - #'unquote-splicing @racket[unquote-splicing] #'local @racket[local] #'letrec @racket[letrec] #'let* @racket[let*] #'let @racket[let] - #'time @racket[time])) + #'time @racket[time] + @racket[define] + @racket[define-struct])) (define (gen-intermediate-forms lambda-id lambda-elem - quote-id quote-elem - quasiquote-id quasiquote-elem - unquote-id unquote-elem - unquote-splicing-id unquote-splicing-elem local-id local-elem letrec-id letrec-elem let*-id let*-elem let-id let-elem - time-id time-elem) + time-id time-elem + define-elem + define-struct-elem + ) (list - @deftogether[( - @defform/none[(unsyntax @elem{@racketvalfont{'}@racket[name]})] - @defform/none[(unsyntax @elem{@racketvalfont{'}@racket[part]})] - @defform[#:id [quote quote-id] (quote name)] - @defform/none[(#,quote-elem part)] - )]{ - - A quoted name is a symbol. A quote part is an abbreviation for a nested lists. - - Normally, this quotation is written with a @litchar{'}, like - @racket['(apple banana)], but it can also be written with - @quote-elem, like @racket[(@#,quote-elem (apple banana))].} - - - @deftogether[( - @defform/none[(unsyntax @elem{@racketvalfont{`}@racket[name]})] - @defform/none[(unsyntax @elem{@racketvalfont{`}@racket[part]})] - @defform[#:id [quasiquote quasiquote-id] - (quasiquote name)] - @defform/none[(#,quasiquote-elem part)] - )]{ - - Like @quote-elem, but also allows escaping to expression - ``unquotes.'' - - Normally, quasi-quotations are written with a backquote, - @litchar{`}, like @racket[`(apple ,(+ 1 2))], but they can also be - written with @quasiquote-elem, like - @racket[(@quasiquote-elem (apple ,(+ 1 2)))].} - - - @deftogether[( - @defform/none[(unsyntax @elem{@racketvalfont{,}@racket[expression]})] - @defform[#:id [unquote unquote-id] - (unquote expression)] - )]{ - - Under a single quasiquote, @racketfont{,}@racket[expression] - escapes from the quote to include an evaluated expression whose - result is inserted into the abbreviated list. - - Under multiple quasiquotes, @racketfont{,}@racket[expression] is - really the literal @racketfont{,}@racket[expression], decrementing - the quasiquote count by one for @racket[expression]. - - Normally, an unquote is written with @litchar{,}, but it can also be - written with @|unquote-elem|.} - - - @deftogether[( - @defform/none[(unsyntax @elem{@racketvalfont[",@"]@racket[expression]})] - @defform[#:id [unquote-splicing unquote-splicing-id] - (unquote-splicing expression)] - )]{ - - Under a single quasiquote, @racketfont[",@"]@racket[expression] - escapes from the quote to include an evaluated expression whose - result is a list to splice into the abbreviated list. - - Under multiple quasiquotes, a splicing unquote is like an unquote; - that is, it decrements the quasiquote count by one. - - Normally, a splicing unquote is written with @litchar{,}, but it - can also be written with @|unquote-splicing-elem|.} - @defform[#:id [local local-id] (local [definition ...] expression)]{ Groups related definitions for use in @racket[expression]. Each - @racket[definition] can be either a variable definition, a function - definition, or a structure definition, using the usual syntax. + @racket[definition] can be either a @define-elem or a + @|define-struct-elem|. When evaluating @local-elem, each @racket[definition] is evaluated in order, and finally the body @racket[expression] is @@ -585,6 +602,14 @@ defined with " (racket define) " or " (racket define-struct) ", or any one of:") (namespace-syntax-introduce (datum->syntax #f (car func)))))) not-in-ns)) (let ([desc-strs (cddr func)]) + (printf "prim-ops:605 ~v~n" (list id (cadr func) + (typeset-type + (cadr + func)) + (to-paragraph + (typeset-type + (cadr + func))))) (defthing/proc id (to-paragraph (typeset-type (cadr func))) From 020469a7169bf890f6ce1c07ad98e6fbafe368f7 Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Sat, 9 Jul 2011 01:37:32 -0400 Subject: [PATCH 217/746] Remove spurious printf left in 9053f8f9 (cherry picked from commit 3815862a818f35832ff979a04731037050037fc1) --- collects/scribblings/htdp-langs/prim-ops.rkt | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/collects/scribblings/htdp-langs/prim-ops.rkt b/collects/scribblings/htdp-langs/prim-ops.rkt index 1c7b46d5ea..3d78579f8c 100644 --- a/collects/scribblings/htdp-langs/prim-ops.rkt +++ b/collects/scribblings/htdp-langs/prim-ops.rkt @@ -602,15 +602,7 @@ defined with " (racket define) " or " (racket define-struct) ", or any one of:") (namespace-syntax-introduce (datum->syntax #f (car func)))))) not-in-ns)) (let ([desc-strs (cddr func)]) - (printf "prim-ops:605 ~v~n" (list id (cadr func) - (typeset-type - (cadr - func)) - (to-paragraph - (typeset-type - (cadr - func))))) - (defthing/proc +3 (defthing/proc id (to-paragraph (typeset-type (cadr func))) desc-strs))))) From 2b05b96b507eccabbc73c0fb5aab7137ff6605da Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 8 Jul 2011 20:00:02 -0600 Subject: [PATCH 218/746] fix dependency (cherry picked from commit 50bd06af9a13b51160389efe9a2674a820978a66) --- src/racket/src/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racket/src/Makefile.in b/src/racket/src/Makefile.in index be94275bd1..29d6bbf8a9 100644 --- a/src/racket/src/Makefile.in +++ b/src/racket/src/Makefile.in @@ -409,5 +409,5 @@ type.@LTO@: $(COMMON_HEADERS) \ $(srcdir)/../src/stypes.h $(srcdir)/mzmark_type.inc vector.@LTO@: $(COMMON_HEADERS) \ $(srcdir)/../src/stypes.h -vadliate.@LTO@: $(COMMON_HEADERS) \ +validate.@LTO@: $(COMMON_HEADERS) \ $(srcdir)/../src/stypes.h $(srcdir)/mzmark_validate.inc From 6bbfbad6a79e3306341e6ad52a8b537fc507b73a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 9 Jul 2011 08:47:21 -0600 Subject: [PATCH 219/746] export `step-count?' Merge to 5.1.2 (cherry picked from commit 8271f7b1820060783916ed62cac5d426af09b6ca) --- collects/2htdp/private/img-err.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/2htdp/private/img-err.rkt b/collects/2htdp/private/img-err.rkt index 06aa436046..62f13518dc 100644 --- a/collects/2htdp/private/img-err.rkt +++ b/collects/2htdp/private/img-err.rkt @@ -11,6 +11,7 @@ pen-cap? pen-join? real-valued-posn? + step-count? check-mode/color-combination) (require htdp/error From bc607e96e98941f3fcc78f8b05062124fe13e29b Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 11 Jul 2011 15:03:05 -0400 Subject: [PATCH 220/746] New Racket version 5.1.1.900. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index acfda735ec..f385cd85e2 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index b9c87bf2b2..fefc4dffc3 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,9 - PRODUCTVERSION 5,1,1,9 + FILEVERSION 5,1,1,900 + PRODUCTVERSION 5,1,1,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 1, 1, 9\0" + VALUE "FileVersion", "5, 1, 1, 900\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 1, 9\0" + VALUE "ProductVersion", "5, 1, 1, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 8d7e6e5d3b..a4d5c58f1d 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,9 - PRODUCTVERSION 5,1,1,9 + FILEVERSION 5,1,1,900 + PRODUCTVERSION 5,1,1,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 1, 1, 9" + VALUE "FileVersion", "5, 1, 1, 900" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 1, 1, 9" + VALUE "ProductVersion", "5, 1, 1, 900" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index 64c2f981fe..57221f610c 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.1.1.9 = s 'MzObj Class' + MzCOM.MzObj.5.1.1.900 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.1.1.9' + CurVer = s 'MzCOM.MzObj.5.1.1.900' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.1.1.9' + ProgID = s 'MzCOM.MzObj.5.1.1.900' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index db7b8f46cf..38a36b1736 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 4ef0a91c8a..d70780fd27 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,9 - PRODUCTVERSION 5,1,1,9 + FILEVERSION 5,1,1,900 + PRODUCTVERSION 5,1,1,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 1, 1, 9\0" + VALUE "FileVersion", "5, 1, 1, 900\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 1, 9\0" + VALUE "ProductVersion", "5, 1, 1, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 6c204f4713..8fa54b7f8e 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,9 - PRODUCTVERSION 5,1,1,9 + FILEVERSION 5,1,1,900 + PRODUCTVERSION 5,1,1,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 1, 1, 9\0" + VALUE "FileVersion", "5, 1, 1, 900\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 1, 9\0" + VALUE "ProductVersion", "5, 1, 1, 900\0" END END BLOCK "VarFileInfo" From 09113654030aea4772fd86f1ecc7fa225a086110 Mon Sep 17 00:00:00 2001 From: Carl Eastlund Date: Sat, 9 Jul 2011 14:46:58 -0400 Subject: [PATCH 221/746] Corrected documentation of quote-module-name to indicate that it does not produce collection and planet-relative paths on its own. Deprecated quote-module-path, and replaced existing uses of it with quote-module-name. (cherry picked from commit 2e6a608539f5ef39a9ff821d95163ea4660da952) --- collects/mzlib/unit.rkt | 2 +- collects/racket/contract/private/arr-i.rkt | 2 +- collects/racket/contract/private/base.rkt | 2 +- collects/racket/contract/private/provide.rkt | 4 +- .../syntax/parse/experimental/provide.rkt | 2 +- collects/syntax/scribblings/srcloc.scrbl | 57 +++++++++++++------ .../typed-scheme/typecheck/tc-toplevel.rkt | 2 +- collects/unstable/wrapc.rkt | 4 +- 8 files changed, 48 insertions(+), 27 deletions(-) diff --git a/collects/mzlib/unit.rkt b/collects/mzlib/unit.rkt index cd342989c5..8f18c8fa1c 100644 --- a/collects/mzlib/unit.rkt +++ b/collects/mzlib/unit.rkt @@ -1684,7 +1684,7 @@ (((wrap-code ...) ...) (map (λ (os ov tbs) (define rename-bindings - (get-member-bindings def-table os #'(quote-module-path))) + (get-member-bindings def-table os #'(quote-module-name))) (map (λ (tb i v c) (if c (with-syntax ([ctc-stx diff --git a/collects/racket/contract/private/arr-i.rkt b/collects/racket/contract/private/arr-i.rkt index 7e40dda29b..32c0b546b4 100644 --- a/collects/racket/contract/private/arr-i.rkt +++ b/collects/racket/contract/private/arr-i.rkt @@ -786,7 +786,7 @@ keywordlist #'(scname ...)))] [stxclass (in-list (attribute scname.value))] [rec (in-list (attribute c.rec))]) diff --git a/collects/syntax/scribblings/srcloc.scrbl b/collects/syntax/scribblings/srcloc.scrbl index 61e7bddb5d..803c0accf9 100644 --- a/collects/syntax/scribblings/srcloc.scrbl +++ b/collects/syntax/scribblings/srcloc.scrbl @@ -2,7 +2,8 @@ @(require scribble/eval (for-label racket/base syntax/srcloc - syntax/location)) + syntax/location + setup/path-to-relative)) @(define unsyntax #f) @@ -290,43 +291,63 @@ the whole macro application if no @racket[form] is given. } -@deftogether[( -@defform[(quote-module-name)] -@defform[(quote-module-path)] -)]{ +@defform[(quote-module-name)]{ -Quote the name of the module in which the form is compiled. The -@racket[quote-module-name] form produces a string or a symbol, while -@racket[quote-module-path] produces a @tech[#:doc reference-path]{module path}. - -These forms use relative names for modules found in the collections or PLaneT -cache; their results are suitable for printing, but not for accessing libraries -programmatically, such as via @racket[dynamic-require]. +Quotes the name of the module in which the form is compiled as a path or symbol, +or @racket['top-level] when used outside of a module. To produce a name +suitable for use in printed messages, apply +@racket[path->relative-string/library] when the result is a path. @defexamples[#:eval (new-evaluator) (module A racket (require syntax/location) (define-syntax-rule (name) (quote-module-name)) - (define-syntax-rule (path) (quote-module-path)) (define a-name (name)) - (define a-path (path)) (provide (all-defined-out))) (require 'A) a-name -a-path (module B racket (require syntax/location) (require 'A) (define b-name (name)) - (define b-path (path)) (provide (all-defined-out))) (require 'B) b-name -b-path (quote-module-name) -(quote-module-path) [current-namespace (module->namespace (quote 'A))] (quote-module-name) +] + +} + +@defform[(quote-module-path)]{ + +@emph{This form is deprecated, as it does not produce module paths that reliably +indicate collections or PLaneT packages. Please use @racket[quote-module-name] +and @racket[path->relative-string/library] to produce human-readable module +names in printed messages.} + +Quotes the name of the module in which the form is compiled as a +@tech[#:doc reference-path]{module path} using @racket[quote] or @racket[file], +or produces @racket['top-level] when used outside of a module. + +@defexamples[#:eval (new-evaluator) +(module A racket + (require syntax/location) + (define-syntax-rule (path) (quote-module-path)) + (define a-path (path)) + (provide (all-defined-out))) +(require 'A) +a-path +(module B racket + (require syntax/location) + (require 'A) + (define b-path (path)) + (provide (all-defined-out))) +(require 'B) +b-path +(quote-module-path) +[current-pathspace (module->pathspace (quote 'A))] (quote-module-path) ] diff --git a/collects/typed-scheme/typecheck/tc-toplevel.rkt b/collects/typed-scheme/typecheck/tc-toplevel.rkt index 5bbb4a6e0f..e143bcb9e6 100644 --- a/collects/typed-scheme/typecheck/tc-toplevel.rkt +++ b/collects/typed-scheme/typecheck/tc-toplevel.rkt @@ -310,7 +310,7 @@ #`(begin #,(if (null? (syntax-e #'(new-provs ...))) #'(begin) - #'(define the-variable-reference (quote-module-path))) + #'(define the-variable-reference (quote-module-name))) #,(env-init-code syntax-provide? provide-tbl def-tbl) #,(tname-env-init-code) #,(talias-env-init-code) diff --git a/collects/unstable/wrapc.rkt b/collects/unstable/wrapc.rkt index e80c88f235..4407da72f8 100644 --- a/collects/unstable/wrapc.rkt +++ b/collects/unstable/wrapc.rkt @@ -40,7 +40,7 @@ [_ #f])] [else #f])]) (base-wrap-expr/c expr ctc-expr - #:positive #'(quote-module-path) + #:positive #'(quote-module-name) #:negative neg-source-expr #:expr-name (cond [(and expr-name macro-name) (format "~a of ~a" expr-name macro-name)] @@ -64,7 +64,7 @@ (define (get-source-expr source ctx) (cond [(eq? source 'use-site) - #'(quote-module-path)] + #'(quote-module-name)] [(eq? source 'unknown) #'(quote "unknown")] [(eq? source 'from-macro) From 18e9e79aa038e6c2d733e710eb1339d6f185f27d Mon Sep 17 00:00:00 2001 From: Carl Eastlund Date: Fri, 8 Jul 2011 22:44:57 -0400 Subject: [PATCH 222/746] Changed default blame formatter to report blame parties relative to collection and planet directories where appropriate. Added a test for this behavior. (cherry picked from commit b3136095ea146c0aa831c2de7054da0cb896aaa0) --- collects/racket/contract/private/blame.rkt | 13 +++++++++---- collects/tests/racket/contract-test.rktl | 12 ++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/collects/racket/contract/private/blame.rkt b/collects/racket/contract/private/blame.rkt index cc45546817..d05f5e59eb 100644 --- a/collects/racket/contract/private/blame.rkt +++ b/collects/racket/contract/private/blame.rkt @@ -1,6 +1,6 @@ #lang racket/base -(require syntax/srcloc racket/pretty) +(require syntax/srcloc racket/pretty setup/path-to-relative) (provide blame? make-blame @@ -63,8 +63,8 @@ b))) (define (default-blame-format b x custom-message) - (let* ([source-message (regexp-replace #rx": *$" (source-location->prefix (blame-source b)) "")] - [positive-message (show/display (blame-positive b))] + (let* ([source-message (source-location->string (blame-source b))] + [positive-message (show/display (convert-blame-party (blame-positive b)))] [contract-message (format " contract: ~a" (show/write (blame-contract b)))] [contract-message+at (if (regexp-match #rx"\n$" contract-message) @@ -98,7 +98,7 @@ "\n")) contract-message+at)] [else - (define negative-message (show/display (blame-negative b))) + (define negative-message (show/display (convert-blame-party (blame-negative b)))) (define start-of-message (if (blame-value b) (format "~a: contract violation," (blame-value b)) @@ -141,6 +141,11 @@ (pretty-write v port) (get-output-string port))) +(define (convert-blame-party x) + (cond + [(path? x) (path->relative-string/library x)] + [else x])) + (define show/display (show pretty-format/display)) (define show/write (show pretty-format/write)) diff --git a/collects/tests/racket/contract-test.rktl b/collects/tests/racket/contract-test.rktl index 6a3689c306..cad3bd360f 100644 --- a/collects/tests/racket/contract-test.rktl +++ b/collects/tests/racket/contract-test.rktl @@ -2933,6 +2933,14 @@ (λ (x) (and (exn? x) (regexp-match (regexp-quote "|x y|: 123456789") (exn-message x))))) + + ;; test to make sure the collects directories are appropriately prefixed + (contract-error-test + #'(contract symbol? "not a symbol" 'pos 'neg 'not-a-symbol #'here) + (lambda (x) + (and (exn? x) + (regexp-match? #px"" + (exn-message x))))) (test/neg-blame '->i-protect-shared-state @@ -11447,7 +11455,7 @@ so that propagation occurs. (eval '(g 12))) (λ (x) (and (exn? x) - (regexp-match #rx"^g.*contract from 'pce9-bug" (exn-message x))))) + (regexp-match #rx"^g.*contract from pce9-bug" (exn-message x))))) (contract-error-test #'(begin @@ -11460,7 +11468,7 @@ so that propagation occurs. (eval '(g 'a))) (λ (x) (and (exn? x) - (regexp-match #rx"^g.*contract from 'pce10-bug" (exn-message x))))) + (regexp-match #rx"^g.*contract from pce10-bug" (exn-message x))))) (contract-eval `(,test From 6d79e54a4d5d93e7522e784ab8f03df7d108c644 Mon Sep 17 00:00:00 2001 From: Carl Eastlund Date: Fri, 8 Jul 2011 01:22:26 -0400 Subject: [PATCH 223/746] Changed source-location->string and ->prefix to use path->relative-string/library to produce collection and planet-relative source names. (cherry picked from commit 00a6442712759ebabe56fc57b58bcf3c93d1e914) --- collects/syntax/srcloc.rkt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/collects/syntax/srcloc.rkt b/collects/syntax/srcloc.rkt index c81c099b77..efd1da1ae1 100644 --- a/collects/syntax/srcloc.rkt +++ b/collects/syntax/srcloc.rkt @@ -37,6 +37,9 @@ ) +(require + setup/path-to-relative) + (define (source-location? x) (process-source-location x good? bad? 'source-location?)) @@ -163,7 +166,9 @@ (define ((good-string default) x src line col pos span) (format "~a~a" - (or src default) + (cond + [(path-string? src) (path->relative-string/library src)] + [else (or src default)]) (if line (if col (format ":~a.~a" line col) From d7fcd2f14951bf4ca78a238a4bb6bebbfb1fdd3c Mon Sep 17 00:00:00 2001 From: Carl Eastlund Date: Sat, 9 Jul 2011 17:28:04 -0400 Subject: [PATCH 224/746] Updated unit contract tests to not rely on a specific format for names of blamed modules in contract error messages. (cherry picked from commit d5b852c386ab05a829c07465710ca520c2dbefae) --- collects/tests/units/test-unit-contracts.rktl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/tests/units/test-unit-contracts.rktl b/collects/tests/units/test-unit-contracts.rktl index 3411f14978..6d89cc7f3f 100644 --- a/collects/tests/units/test-unit-contracts.rktl +++ b/collects/tests/units/test-unit-contracts.rktl @@ -626,8 +626,8 @@ (require (prefix-in m2: 'm2)) (m2:z) -(test-contract-error "'m2" "U@" "not a symbol" (m2:w)) -(test-contract-error "'m1" "U@" "not a string" (m2:v)) +(test-contract-error "m2" "U@" "not a symbol" (m2:w)) +(test-contract-error "m1" "U@" "not a string" (m2:v)) (test-syntax-error "no y in sig1" (unit/c (import (sig1 [y number?])) @@ -700,7 +700,7 @@ (require (prefix-in m4: 'm4)) -(test-contract-error "'m4" "f" "not an x" +(test-contract-error "m4" "f" "not an x" (m4:f 3)) (require (prefix-in m3: 'm3)) From 94770d3a085a74d873b7713b7c292050843db536 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 9 Jul 2011 20:09:41 -0600 Subject: [PATCH 225/746] fix `hash-ref' bugs on immutable `eq?'-based tables There were two: * new: after finding a hash code, the key wasn't always checked to be `eq?' to the desired key * old: the hash code wan't downshifted by 2, so changes in the low two bits (like when a pair is determined to start a list) could break lookup Merge to 5.1.2 (cherry picked from commit e765231dadb428688ce12e9ca66b48835dba07e4) --- collects/tests/racket/basic.rktl | 21 ++++++++++++++++++--- src/racket/src/hash.c | 4 +++- src/racket/src/thread.c | 8 +------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/collects/tests/racket/basic.rktl b/collects/tests/racket/basic.rktl index 4ad4079938..b9f75d6254 100644 --- a/collects/tests/racket/basic.rktl +++ b/collects/tests/racket/basic.rktl @@ -2388,9 +2388,11 @@ (check-all-bad hash-iterate-key) (check-all-bad hash-iterate-value)) -(test (list 1 2 3) hash-keys #hasheq((1 . a)(2 . b)(3 . c))) -(test (list 'a 'b 'c) hash-values #hasheq((1 . a)(2 . b)(3 . c))) -(test (list (cons 1 'a) (cons 2 'b) (cons 3 'c)) hash->list #hasheq((1 . a)(2 . b)(3 . c))) +(test (list 1 2 3) sort (hash-keys #hasheq((1 . a) (2 . b) (3 . c))) <) +(test (list 'a 'b 'c) + sort (hash-values #hasheq((1 . a) (2 . b) (3 . c))) stringstring) +(test (list (cons 1 'a) (cons 2 'b) (cons 3 'c)) + sort (hash->list #hasheq((1 . a) (2 . b) (3 . c))) < #:key car) (err/rt-test (hash-set*! im-t 1 2) exn:fail?) (err/rt-test (hash-set* (make-hasheq null) 1 2) exn:fail?) @@ -2495,6 +2497,19 @@ (test (equal-hash-code ht) values (equal-hash-code ht2)) (test (equal-secondary-hash-code ht) values (equal-secondary-hash-code ht2)))) +;; Check that immutable hash trees aren't confused by an +;; "is a list" bit set in a key: +(let () + (define p (list 1 2 3 4)) + (define ht (hasheq p 1 'a 7 'b 10 'c 13)) + (test 1 hash-ref ht p #f) + (list? p) + (list? p) + (list? (list* 1 2 p)) + (list? (list* 1 2 p)) + (list? (list* 1 2 p)) + (test 1 hash-ref ht p #f)) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Misc diff --git a/src/racket/src/hash.c b/src/racket/src/hash.c index b4d3174aec..cd2a8623bd 100644 --- a/src/racket/src/hash.c +++ b/src/racket/src/hash.c @@ -2276,6 +2276,7 @@ Scheme_Hash_Tree *scheme_hash_tree_set(Scheme_Hash_Tree *tree, Scheme_Object *ke } } else { h = PTR_TO_LONG((Scheme_Object *)key); + h = h >> 2; } if (!val) { @@ -2417,6 +2418,7 @@ Scheme_Object *scheme_eq_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *ke RBNode *rb; h = PTR_TO_LONG((Scheme_Object *)key); + h = h >> 2; rb = rb_find(h, tree->root); if (rb) { @@ -2429,7 +2431,7 @@ Scheme_Object *scheme_eq_hash_tree_get(Scheme_Hash_Tree *tree, Scheme_Object *ke return SCHEME_CDR(a); prs = SCHEME_CDR(prs); } - } else + } else if (SAME_OBJ(rb->key, key)) return rb->val; } diff --git a/src/racket/src/thread.c b/src/racket/src/thread.c index c198bc4b34..a8ee52fabe 100644 --- a/src/racket/src/thread.c +++ b/src/racket/src/thread.c @@ -258,12 +258,6 @@ typedef struct Thread_Cell { Scheme_Object so; char inherited, assigned; Scheme_Object *def_val; - /* A thread's thread_cell table maps cells to keys weakly. - This table maps keys to values weakly. The two weak - levels ensure that thread cells are properly GCed - when the value of a thread cell references the thread - cell. */ - Scheme_Bucket_Table *vals; } Thread_Cell; #ifdef MZ_PRECISE_GC @@ -6436,7 +6430,7 @@ static Scheme_Object *do_param(void *_data, int argc, Scheme_Object *argv[]) pos[0] = data->key; pos[1] = data->defcell; - + return scheme_param_config("parameter-procedure", (Scheme_Object *)(void *)pos, argc, argv2, From 64cac3e13cceddcfe1581e89ab5eb7bab6166344 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 9 Jul 2011 20:28:46 -0600 Subject: [PATCH 226/746] fix cross reference Merge to 5.1.2 (cherry picked from commit b5bb703b48c2b353659867d191fb434da96cf63a) --- collects/htdp/htdp.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/htdp/htdp.scrbl b/collects/htdp/htdp.scrbl index 3b74e16618..26f98f7cbb 100644 --- a/collects/htdp/htdp.scrbl +++ b/collects/htdp/htdp.scrbl @@ -20,7 +20,7 @@ file from the filesystem.} @racket[require] statement.}] Under the hood, HTdP Teachpacks and HTdP Libraries are implemented the same way, -using normal Racket @secref[#:doc '(lib "scribblings/guide/module.scrbl") "modules"]. +using normal Racket @secref[#:doc '(lib "scribblings/guide/guide.scrbl") "modules"]. When implementing an extension intended for students, pay a special attention to the error messages. The error messages of DrRacket's teaching languages go to From 177fff49e600494f927b2fa7c19f1662f6d0bf08 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sat, 9 Jul 2011 22:49:14 -0400 Subject: [PATCH 227/746] Fix capitalization of HtDP. Merge to 5.1.2. (cherry picked from commit 64d42fa0d3e9bf7bc2237b127edf71029181a7a5) --- collects/htdp/htdp.scrbl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/collects/htdp/htdp.scrbl b/collects/htdp/htdp.scrbl index 26f98f7cbb..fa1149e6a9 100644 --- a/collects/htdp/htdp.scrbl +++ b/collects/htdp/htdp.scrbl @@ -11,15 +11,15 @@ and functionality to students using the teaching languages. @itemize[ -@item{HTdP Teachpacks are added to a student's program by clicking on the +@item{HtDP Teachpacks are added to a student's program by clicking on the ``Language'' menu and selecting ``add Teachpack''. Students can then install a new Teachpack by clicking ``Add Teachpack to List'' and choosing the Teachpack file from the filesystem.} -@item{HTdP Libraries are brought into the student's program using a +@item{HtDP Libraries are brought into the student's program using a @racket[require] statement.}] -Under the hood, HTdP Teachpacks and HTdP Libraries are implemented the same way, +Under the hood, HtDP Teachpacks and HtDP Libraries are implemented the same way, using normal Racket @secref[#:doc '(lib "scribblings/guide/guide.scrbl") "modules"]. When implementing an extension intended for students, pay a special attention to @@ -29,8 +29,8 @@ uses vocabulary or phrases the students has not learned yet. The teaching langu also ensure that students cannot stumble by accident onto challenging or confusing features intended for professional or for higher-level students. -This manual describes library support for authors of HTdP Teachpacks, libraries, -and customized teaching languages. Use the HTdP +This manual describes library support for authors of HtDP Teachpacks, libraries, +and customized teaching languages. Use the HtDP @seclink["error-reporting"]{error reporting functions} to create error messages that integrate smoothly with those of the teaching languages. Before composing new error messages, we recommend you read the @seclink["error-guidelines"]{error From 2490b0711c27eecedc38105b5d60f8a59ad143f9 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 10 Jul 2011 06:51:57 -0400 Subject: [PATCH 228/746] Fix the path relative functions to return a string for a path input, clarify the documentation, add a few tests. Fixes pr 12032 Fixes pr 12034 (cherry picked from commit ebe9453e7371fba259146a5b6cc3b7a52eeb11ee) --- collects/scribblings/raco/setup.scrbl | 43 ++++++++++++++++++------- collects/setup/path-to-relative.rkt | 3 +- collects/tests/racket/scheme-tests.rktl | 1 + collects/tests/racket/setup.rktl | 24 ++++++++++++++ 4 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 collects/tests/racket/setup.rktl diff --git a/collects/scribblings/raco/setup.scrbl b/collects/scribblings/raco/setup.scrbl index 93675cdada..c91b9f53fd 100644 --- a/collects/scribblings/raco/setup.scrbl +++ b/collects/scribblings/raco/setup.scrbl @@ -1189,31 +1189,52 @@ than specified in the contract above, it is returned as-is.} @defmodule[setup/path-to-relative] -@defproc[(path->relative-string/library [path path-string?] - [default any/c (lambda (x) x)]) - any]{ +@defproc[(path->relative-string/library + [path path-string?] + [default (or/c (-> path-string? any/c) any/c) + (lambda (x) (if (path? x) (path->string x) x))]) + any/c]{ Produces a string suitable for display in error messages. If the path is an absolute one that is inside the @filepath{collects} tree, the result will be a string that begins with @racket["/"]. Similarly, a path in the user-specific collects results in a prefix of @racket["/"], and a @PLaneT path results in - @racket["/"]. If the path is not absolute, or if it is not in - any of these, the @racket[default] determines the result: if it is a - procedure, it is applied onto the path to get the result, otherwise it - is returned. + @racket["/"]. + + If the path is not absolute, or if it is not in any of these, it is + returned as-is (converted to a string if needed). If @racket[default] + is given, it specifies the return value instead: it can be a procedure + which is applied onto the path to get the result, or the result + itself. + + Note that this function can be a non-string only if @racket[default] + is given, and it does not return a string. } -@defproc[(path->relative-string/setup [path path-string?] - [default any/c (lambda (x) x)]) +@defproc[(path->relative-string/setup + [path path-string?] + [default (or/c (-> path-string? any/c) any/c) + (lambda (x) (if (path? x) (path->string x) x))]) any]{ Similar to @racket[path->relative-string/library], but more suited for output during compilation: @filepath{collects} paths are shown with no prefix, and in the user-specific collects with just a @racket[""] prefix. + + If the path is not absolute, or if it is not in any of these, it is + returned as-is (converted to a string if needed). If @racket[default] + is given, it specifies the return value instead: it can be a procedure + which is applied onto the path to get the result, or the result + itself. + + Note that this function can be a non-string only if @racket[default] + is given, and it does not return a string. } -@defproc[(make-path->relative-string [dirs (listof (cons (-> path?) string?))] - [default any/c (lambda (x) x)]) +@defproc[(make-path->relative-string + [dirs (listof (cons (-> path?) string?))] + [default (or/c (-> path-string? any/c) any/c) + (lambda (x) (if (path? x) (path->string x) x))]) (path-string? any/c . -> . any)]{ This function produces functions like @racket[path->relative-string/library] and diff --git a/collects/setup/path-to-relative.rkt b/collects/setup/path-to-relative.rkt index 44584ac550..bc97f87601 100644 --- a/collects/setup/path-to-relative.rkt +++ b/collects/setup/path-to-relative.rkt @@ -10,7 +10,8 @@ path->relative-string/setup path->relative-string/library) -(define (make-path->relative-string dirs [default (lambda (x) x)]) +(define (make-path->relative-string + dirs [default (lambda (x) (if (path? x) (path->string x) x))]) (unless (and (list? dirs) (andmap (lambda (x) (and (pair? x) diff --git a/collects/tests/racket/scheme-tests.rktl b/collects/tests/racket/scheme-tests.rktl index 8b7aef79de..a1d162f36d 100644 --- a/collects/tests/racket/scheme-tests.rktl +++ b/collects/tests/racket/scheme-tests.rktl @@ -1,6 +1,7 @@ (load-relative "loadtest.rktl") +(load-in-sandbox "setup.rktl") (load-in-sandbox "for.rktl") (load-in-sandbox "list.rktl") (load-in-sandbox "math.rktl") diff --git a/collects/tests/racket/setup.rktl b/collects/tests/racket/setup.rktl new file mode 100644 index 0000000000..6fbf83ba9c --- /dev/null +++ b/collects/tests/racket/setup.rktl @@ -0,0 +1,24 @@ +(load-relative "loadtest.rktl") + +(Section 'setup) + +(require setup/path-to-relative) + +(let ([missing "/some/inexistent/path"] + [collects (build-path (collection-path "racket") "foo.rkt")] + [relative "some/path"]) + (define (test-both path/str expected-str [lib-expected expected-str]) + (define str (if (string? path/str) path/str (path->string path/str))) + (define path (string->path str)) + (test expected-str path->relative-string/setup str) + (test expected-str path->relative-string/setup path) + (test lib-expected path->relative-string/library str) + (test lib-expected path->relative-string/library path)) + (test-both missing missing) + (test-both relative relative) + (test-both collects "racket/foo.rkt" "/racket/foo.rkt") + (err/rt-test (path->relative-string/setup #f)) + (err/rt-test (path->relative-string/setup #"bleh")) + (err/rt-test (path->relative-string/setup 'bleh))) + +(report-errs) From ede736ff84993c4508744306b9e825e999719e91 Mon Sep 17 00:00:00 2001 From: Stephen Bloch Date: Sun, 10 Jul 2011 08:42:49 -0400 Subject: [PATCH 229/746] Improved error messages to specify actual argument as well as expected type. Still produces one check-error failure because of bug in make-color. (cherry picked from commit d3df33b0234c953e8eb812a37efc3fe3cd849eed) --- .../picturing-programs/private/map-image.rkt | 49 +++++++++++++------ .../tests/map-image-bsl-tests.rkt | 27 +++++----- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/collects/picturing-programs/private/map-image.rkt b/collects/picturing-programs/private/map-image.rkt index 5136053ea3..1a420107c1 100644 --- a/collects/picturing-programs/private/map-image.rkt +++ b/collects/picturing-programs/private/map-image.rkt @@ -85,7 +85,8 @@ ; name->color : string-or-symbol -> maybe-color (define (name->color name) (unless (or (string? name) (symbol? name)) - (error 'name->color "argument must be a string or symbol")) + (error 'name->color + (format "expected a string or symbol, but found ~v" name))) (let [[result (send the-color-database find-color (if (string? name) name @@ -100,7 +101,7 @@ (cond [(color? thing) thing] [(eqv? thing #f) transparent] [(image-color? thing) (name->color thing)] - [else (error 'colorize (format "~v is not a color" thing))])) + [else (error 'colorize (format "expected a color, but found ~v" thing))])) ; colorize-func : (... -> broad-color) -> (... -> color) (define (colorize-func f) @@ -116,8 +117,12 @@ (define (color=? c1 c2) (let [[rc1 (colorize c1)] [rc2 (colorize c2)]] - (unless (and (color? rc1) (color? rc2)) - (error 'color=? "Expected two colors or color names as arguments")) + (unless (color? rc1) + (error 'color=? + (format "Expected a color or color name as first argument, but found ~v" c1))) + (unless (color? rc2) + (error 'color=? + (format "Expected a color or color name as second argument, but found ~v" c2))) (and (= (color-alpha rc1) (color-alpha rc2)) ; Both alphas MUST be equal. (or (= (color-alpha rc1) 0) ; If both are transparent, ignore rgb. (and (= (color-red rc1) (color-red rc2)) @@ -208,9 +213,11 @@ ; build-image : natural(width) natural(height) (nat nat -> broad-color) -> image (define (build-image w h f) (unless (natural? w) - (error 'build-image "Expected natural number as first argument")) + (error 'build-image + (format "Expected natural number as first argument, but found ~v" w))) (unless (natural? h) - (error 'build-image "Expected natural number as second argument")) + (error 'build-image + (format "Expected natural number as second argument, but found ~v" h))) (check-procedure-arity f 2 'build-image "Expected function with contract num(x) num(y) -> color as third argument") (build-image-internal w h (colorize-func f))) @@ -219,9 +226,11 @@ ; For students who don't yet know function closures. (define (build-image/extra w h f extra) (unless (natural? w) - (error 'build-image/extra "Expected natural number as first argument")) + (error 'build-image/extra + (format "Expected natural number as first argument, but found ~v" w))) (unless (natural? h) - (error 'build-image/extra "Expected natural number as second argument")) + (error 'build-image/extra + (format "Expected natural number as second argument, but found ~v" h))) (check-procedure-arity f 3 'build-image/extra "Expected function with contract num(x) num(y) any -> color as third argument") (build-image-internal w h (colorize-func (lambda (x y) (f x y extra))))) @@ -230,9 +239,11 @@ ; where each of rfunc, gfunc, bfunc is (nat(x) nat(y) -> nat) (define (build3-image w h rfunc gfunc bfunc) (unless (natural? w) - (error 'build3-image "Expected natural number as first argument")) + (error 'build3-image + (format "Expected natural number as first argument, but found ~v" w))) (unless (natural? h) - (error 'build3-image "Expected natural number as second argument")) + (error 'build3-image + (format "Expected natural number as second argument, but found ~v" h))) (check-procedure-arity rfunc 2 'build3-image "Expected function with contract num(x) num(y) -> color as third argument") (check-procedure-arity gfunc 2 'build3-image "Expected function with contract num(x) num(y) -> color as fourth argument") (check-procedure-arity bfunc 2 'build3-image "Expected function with contract num(x) num(y) -> color as fifth argument") @@ -244,9 +255,11 @@ ; where each of rfunc, gfunc, bfunc, afunc is (nat(x) nat(y) -> nat) (define (build4-image w h rfunc gfunc bfunc afunc) (unless (natural? w) - (error 'build-image "Expected natural number as first argument")) + (error 'build-image + (format "Expected natural number as first argument, but found ~v" w))) (unless (natural? h) - (error 'build-image "Expected natural number as second argument")) + (error 'build-image + (format "Expected natural number as second argument, but found ~v" h))) (check-procedure-arity rfunc 2 'build-image "Expected function with contract num(x) num(y) -> color as third argument") (check-procedure-arity gfunc 2 'build-image "Expected function with contract num(x) num(y) -> color as fourth argument") (check-procedure-arity bfunc 2 'build-image "Expected function with contract num(x) num(y) -> color as fifth argument") @@ -277,7 +290,8 @@ (define (map-image f img) (check-procedure-arity f 3 'map-image "Expected function with contract num(x) num(y) color -> color as first argument") (unless (image? img) - (error 'map-image "Expected image as second argument")) + (error 'map-image + (format "Expected image as second argument, but found ~v" img))) (map-image-internal (colorize-func f) img)) ; map-image/extra : (nat nat color X -> broad-color) image X -> image @@ -286,7 +300,8 @@ (define (map-image/extra f img extra) (check-procedure-arity f 4 'map-image/extra "Expected function with contract num(x) num(y) color other -> color as first argument") (unless (image? img) - (error 'map-image/extra "Expected image as second argument")) + (error 'map-image/extra + (format "Expected image as second argument, but found ~v" img))) (map-image-internal (colorize-func (lambda (x y c) (f x y c extra))) img)) @@ -304,7 +319,8 @@ (check-procedure-arity gfunc 5 'map3-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(g) as second argument") (check-procedure-arity bfunc 5 'map3-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") (unless (image? pic) - (error 'map3-image "Expected image as fourth argument")) + (error 'map3-image + (format "Expected image as fourth argument, but found ~v" pic))) (map-image-internal (lambda (x y c) (make-color (rfunc x y (color-red c) (color-green c) (color-blue c)) @@ -325,7 +341,8 @@ (check-procedure-arity bfunc 6 'map4-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(b) as third argument") (check-procedure-arity afunc 6 'map4-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(alpha) as fourth argument") (unless (image? pic) - (error 'map4-image "Expected image as fifth argument")) + (error 'map4-image + "Expected image as fifth argument, but found ~v" pic)) (map-image-internal (lambda (x y c) (make-color (rfunc x y (color-red c) (color-green c) (color-blue c) (color-alpha c)) diff --git a/collects/picturing-programs/tests/map-image-bsl-tests.rkt b/collects/picturing-programs/tests/map-image-bsl-tests.rkt index b031156fe3..07d3721c8c 100644 --- a/collects/picturing-programs/tests/map-image-bsl-tests.rkt +++ b/collects/picturing-programs/tests/map-image-bsl-tests.rkt @@ -1,6 +1,6 @@ ;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. -#reader(lib "htdp-beginner-reader.ss" "lang")((modname new.map-image-bsl-tests) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) +#reader(lib "htdp-beginner-reader.ss" "lang")((modname map-image-bsl-tests) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) (require picturing-programs) ; Test cases for primitives: @@ -24,7 +24,7 @@ (check-expect (name->color "black") (make-color 0 0 0)) (check-expect (name->color "blue") (make-color 0 0 255)) (check-expect (name->color "plaid") false) -(check-error (name->color 7) "name->color: argument must be a string or symbol") +(check-error (name->color 7) "name->color: expected a string or symbol, but found 7") (check-expect (color=? (make-color 5 10 15) (make-color 5 10 15)) true) (check-expect (color=? (make-color 5 10 15) (make-color 5 15 10)) false) @@ -36,8 +36,9 @@ (check-expect (color=? (make-color 5 10 15 255) (make-color 5 10 15)) true) (check-expect (color=? (make-color 5 10 15 0) false) true) (check-expect (color=? (make-color 5 10 15 20) false) false) -(check-error (color=? "white" 3) "colorize: 3 is not a color") -(check-error (color=? "white" "plaid") "color=?: Expected two colors or color names as arguments") +(check-error (color=? "white" 3) "colorize: expected a color, but found 3") +(check-error (color=? "plaid" "white") "color=?: Expected a color or color name as first argument, but found \"plaid\"") +(check-error (color=? "white" "plaid") "color=?: Expected a color or color name as second argument, but found \"plaid\"") ; Test cases for map3-image: ;(check-error (map3-image 5 + + pic:bloch) @@ -54,7 +55,7 @@ (check-error (map3-image + + sqrt pic:bloch) "map3-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") (check-error (map3-image + + + 5) - "map3-image: Expected image as fourth argument") + "map3-image: Expected image as fourth argument, but found 5") ; red-id : x y r g b -> num (define (red-id x y r g b) r) @@ -113,7 +114,7 @@ (check-error (map4-image + + + sqrt pic:bloch) "map4-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(alpha) as fourth argument") (check-error (map4-image + + + + 5) - "map4-image: Expected image as fifth argument") + "map4-image: Expected image as fifth argument, but found 5") ; red-id6 : x y r g b a -> num (define (red-id6 x y r g b a) r) ; green-id6 : x y r g b a -> num @@ -153,7 +154,7 @@ (check-error (map-image sqrt pic:bloch) "map-image: Expected function with contract num(x) num(y) color -> color as first argument") (check-error (map-image + 5) - "map-image: Expected image as second argument") + "map-image: Expected image as second argument, but found 5") ; color-id : x y color -> color (define (color-id x y c) @@ -186,7 +187,7 @@ (define ex6 (map-image kill-red bloch)) ex6 (define (return-5 x y c) 5) -(check-error (map-image return-5 bloch) "colorize: 5 is not a color") +(check-error (map-image return-5 bloch) "colorize: expected a color, but found 5") "Test cases for build3-image:" (define (x-gradient-2 x y) (min 255 (* 4 x))) @@ -195,9 +196,9 @@ "(build3-image 60 40 zero-2-args x-gradient-2 y-gradient-2) should be a 60x40 rectangle with no red, green increasing from left to right, and blue increasing from top to bottom:" (build3-image 60 40 zero-2-args x-gradient-2 y-gradient-2) (check-error (build3-image "hello" true sqrt sqrt sqrt) - "build3-image: Expected natural number as first argument") + "build3-image: Expected natural number as first argument, but found \"hello\"") (check-error (build3-image 17 true sqrt sqrt sqrt) - "build3-image: Expected natural number as second argument") + "build3-image: Expected natural number as second argument, but found true") (check-error (build3-image 17 24 sqrt sqrt sqrt) "build3-image: Expected function with contract num(x) num(y) -> color as third argument") (check-error (build3-image 17 24 x-gradient-2 sqrt sqrt) @@ -207,7 +208,7 @@ (define (return-minus-5 x y) -5) (check-error (build3-image 17 24 x-gradient-2 y-gradient-2 return-minus-5) - "make-color: expected as third argument, given: -5") + "make-color: expected an integer between 0 and 255 as third argument, given: -5") "Test cases for build4-image:" "(build4-image 50 50 x-gradient-2 x-gradient-2 zero-2-args y-gradient-2) should be a square, increasingly yellow from left to right and increasingly alpha from top to bottom. On a blue background." @@ -224,8 +225,8 @@ "(build-image 100 100 (lambda (x y) (make-color (* x 2.5) (* y 2.5) 0))):" (build-image 100 100 a-gradient) "should be a 100x100 square with a color gradient increasing in red from left to right, and in green from top to bottom" -(check-error (build-image 3.2 100 a-gradient) "build-image: Expected natural number as first argument") -(check-error (build-image 100 -2 a-gradient) "build-image: Expected natural number as second argument") +(check-error (build-image 3.2 100 a-gradient) "build-image: Expected natural number as first argument, but found 3.2") +(check-error (build-image 100 -2 a-gradient) "build-image: Expected natural number as second argument, but found -2") (check-error (build-image 100 100 sqrt) "build-image: Expected function with contract num(x) num(y) -> color as third argument") From 097df98b3dcafd225205e3c69e6dbb8545a1832b Mon Sep 17 00:00:00 2001 From: Stephen Bloch Date: Sun, 10 Jul 2011 08:56:43 -0400 Subject: [PATCH 230/746] Fixed some more error messages. (cherry picked from commit 904ef63ce20def1ed5ca140f5caad0a6ab453703) --- .../picturing-programs/private/map-image.rkt | 64 +++++++++---------- .../tests/map-image-bsl-tests.rkt | 62 +++++++++--------- 2 files changed, 63 insertions(+), 63 deletions(-) diff --git a/collects/picturing-programs/private/map-image.rkt b/collects/picturing-programs/private/map-image.rkt index 1a420107c1..c9dc2cae03 100644 --- a/collects/picturing-programs/private/map-image.rkt +++ b/collects/picturing-programs/private/map-image.rkt @@ -86,7 +86,7 @@ (define (name->color name) (unless (or (string? name) (symbol? name)) (error 'name->color - (format "expected a string or symbol, but found ~v" name))) + (format "Expected a string or symbol, but found ~v" name))) (let [[result (send the-color-database find-color (if (string? name) name @@ -101,7 +101,7 @@ (cond [(color? thing) thing] [(eqv? thing #f) transparent] [(image-color? thing) (name->color thing)] - [else (error 'colorize (format "expected a color, but found ~v" thing))])) + [else (error 'colorize (format "Expected a color, but found ~v" thing))])) ; colorize-func : (... -> broad-color) -> (... -> color) (define (colorize-func f) @@ -214,11 +214,11 @@ (define (build-image w h f) (unless (natural? w) (error 'build-image - (format "Expected natural number as first argument, but found ~v" w))) + (format "Expected a natural number as first argument, but found ~v" w))) (unless (natural? h) (error 'build-image - (format "Expected natural number as second argument, but found ~v" h))) - (check-procedure-arity f 2 'build-image "Expected function with contract num(x) num(y) -> color as third argument") + (format "Expected a natural number as second argument, but found ~v" h))) + (check-procedure-arity f 2 'build-image "Expected a function with contract num(x) num(y) -> color as third argument") (build-image-internal w h (colorize-func f))) ; build-image/extra : natural(width) natural(height) (nat nat any -> broad-color) any -> image @@ -227,11 +227,11 @@ (define (build-image/extra w h f extra) (unless (natural? w) (error 'build-image/extra - (format "Expected natural number as first argument, but found ~v" w))) + (format "Expected a natural number as first argument, but found ~v" w))) (unless (natural? h) (error 'build-image/extra - (format "Expected natural number as second argument, but found ~v" h))) - (check-procedure-arity f 3 'build-image/extra "Expected function with contract num(x) num(y) any -> color as third argument") + (format "Expected a natural number as second argument, but found ~v" h))) + (check-procedure-arity f 3 'build-image/extra "Expected a function with contract num(x) num(y) any -> color as third argument") (build-image-internal w h (colorize-func (lambda (x y) (f x y extra))))) @@ -240,13 +240,13 @@ (define (build3-image w h rfunc gfunc bfunc) (unless (natural? w) (error 'build3-image - (format "Expected natural number as first argument, but found ~v" w))) + (format "Expected a natural number as first argument, but found ~v" w))) (unless (natural? h) (error 'build3-image - (format "Expected natural number as second argument, but found ~v" h))) - (check-procedure-arity rfunc 2 'build3-image "Expected function with contract num(x) num(y) -> color as third argument") - (check-procedure-arity gfunc 2 'build3-image "Expected function with contract num(x) num(y) -> color as fourth argument") - (check-procedure-arity bfunc 2 'build3-image "Expected function with contract num(x) num(y) -> color as fifth argument") + (format "Expected a natural number as second argument, but found ~v" h))) + (check-procedure-arity rfunc 2 'build3-image "Expected a function with contract num(x) num(y) -> color as third argument") + (check-procedure-arity gfunc 2 'build3-image "Expected a function with contract num(x) num(y) -> color as fourth argument") + (check-procedure-arity bfunc 2 'build3-image "Expected a function with contract num(x) num(y) -> color as fifth argument") (build-image-internal w h (lambda (x y) (make-color (rfunc x y) (gfunc x y) (bfunc x y))))) @@ -256,14 +256,14 @@ (define (build4-image w h rfunc gfunc bfunc afunc) (unless (natural? w) (error 'build-image - (format "Expected natural number as first argument, but found ~v" w))) + (format "Expected a natural number as first argument, but found ~v" w))) (unless (natural? h) (error 'build-image - (format "Expected natural number as second argument, but found ~v" h))) - (check-procedure-arity rfunc 2 'build-image "Expected function with contract num(x) num(y) -> color as third argument") - (check-procedure-arity gfunc 2 'build-image "Expected function with contract num(x) num(y) -> color as fourth argument") - (check-procedure-arity bfunc 2 'build-image "Expected function with contract num(x) num(y) -> color as fifth argument") - (check-procedure-arity afunc 2 'build-image "Expected function with contract num(x) num(y) -> color as sixth argument") + (format "Expected a natural number as second argument, but found ~v" h))) + (check-procedure-arity rfunc 2 'build-image "Expected a function with contract num(x) num(y) -> color as third argument") + (check-procedure-arity gfunc 2 'build-image "Expected a function with contract num(x) num(y) -> color as fourth argument") + (check-procedure-arity bfunc 2 'build-image "Expected a function with contract num(x) num(y) -> color as fifth argument") + (check-procedure-arity afunc 2 'build-image "Expected a function with contract num(x) num(y) -> color as sixth argument") (build-image-internal w h (lambda (x y) (make-color (rfunc x y) (gfunc x y) (bfunc x y) (afunc x y))))) @@ -288,20 +288,20 @@ ; map-image : (int int color -> broad-color) image -> image (define (map-image f img) - (check-procedure-arity f 3 'map-image "Expected function with contract num(x) num(y) color -> color as first argument") + (check-procedure-arity f 3 'map-image "Expected a function with contract num(x) num(y) color -> color as first argument") (unless (image? img) (error 'map-image - (format "Expected image as second argument, but found ~v" img))) + (format "Expected an image as second argument, but found ~v" img))) (map-image-internal (colorize-func f) img)) ; map-image/extra : (nat nat color X -> broad-color) image X -> image ; Like map-image, but passes a fixed extra argument to every call of the function. ; For students who don't yet know function closures. (define (map-image/extra f img extra) - (check-procedure-arity f 4 'map-image/extra "Expected function with contract num(x) num(y) color other -> color as first argument") + (check-procedure-arity f 4 'map-image/extra "Expected a function with contract num(x) num(y) color other -> color as first argument") (unless (image? img) (error 'map-image/extra - (format "Expected image as second argument, but found ~v" img))) + (format "Expected an image as second argument, but found ~v" img))) (map-image-internal (colorize-func (lambda (x y c) (f x y c extra))) img)) @@ -315,12 +315,12 @@ ; image -> image ; Note: by default, preserves alpha values from old image. (define (map3-image rfunc gfunc bfunc pic) - (check-procedure-arity rfunc 5 'map3-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(r) as first argument") - (check-procedure-arity gfunc 5 'map3-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(g) as second argument") - (check-procedure-arity bfunc 5 'map3-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") + (check-procedure-arity rfunc 5 'map3-image "Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(r) as first argument") + (check-procedure-arity gfunc 5 'map3-image "Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(g) as second argument") + (check-procedure-arity bfunc 5 'map3-image "Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") (unless (image? pic) (error 'map3-image - (format "Expected image as fourth argument, but found ~v" pic))) + (format "Expected an image as fourth argument, but found ~v" pic))) (map-image-internal (lambda (x y c) (make-color (rfunc x y (color-red c) (color-green c) (color-blue c)) @@ -336,13 +336,13 @@ ; (int(x) int(y) int(r) int(g) int(b) int(a) -> int(a)) ; image -> image (define (map4-image rfunc gfunc bfunc afunc pic) - (check-procedure-arity rfunc 6 'map4-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(r) as first argument") - (check-procedure-arity gfunc 6 'map4-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(g) as second argument") - (check-procedure-arity bfunc 6 'map4-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(b) as third argument") - (check-procedure-arity afunc 6 'map4-image "Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(alpha) as fourth argument") + (check-procedure-arity rfunc 6 'map4-image "Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(r) as first argument") + (check-procedure-arity gfunc 6 'map4-image "Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(g) as second argument") + (check-procedure-arity bfunc 6 'map4-image "Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(b) as third argument") + (check-procedure-arity afunc 6 'map4-image "Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(alpha) as fourth argument") (unless (image? pic) (error 'map4-image - "Expected image as fifth argument, but found ~v" pic)) + "Expected an image as fifth argument, but found ~v" pic)) (map-image-internal (lambda (x y c) (make-color (rfunc x y (color-red c) (color-green c) (color-blue c) (color-alpha c)) diff --git a/collects/picturing-programs/tests/map-image-bsl-tests.rkt b/collects/picturing-programs/tests/map-image-bsl-tests.rkt index 07d3721c8c..ec270cf90c 100644 --- a/collects/picturing-programs/tests/map-image-bsl-tests.rkt +++ b/collects/picturing-programs/tests/map-image-bsl-tests.rkt @@ -24,7 +24,7 @@ (check-expect (name->color "black") (make-color 0 0 0)) (check-expect (name->color "blue") (make-color 0 0 255)) (check-expect (name->color "plaid") false) -(check-error (name->color 7) "name->color: expected a string or symbol, but found 7") +(check-error (name->color 7) "name->color: Expected a string or symbol, but found 7") (check-expect (color=? (make-color 5 10 15) (make-color 5 10 15)) true) (check-expect (color=? (make-color 5 10 15) (make-color 5 15 10)) false) @@ -36,26 +36,26 @@ (check-expect (color=? (make-color 5 10 15 255) (make-color 5 10 15)) true) (check-expect (color=? (make-color 5 10 15 0) false) true) (check-expect (color=? (make-color 5 10 15 20) false) false) -(check-error (color=? "white" 3) "colorize: expected a color, but found 3") +(check-error (color=? "white" 3) "colorize: Expected a color, but found 3") (check-error (color=? "plaid" "white") "color=?: Expected a color or color name as first argument, but found \"plaid\"") (check-error (color=? "white" "plaid") "color=?: Expected a color or color name as second argument, but found \"plaid\"") ; Test cases for map3-image: ;(check-error (map3-image 5 + + pic:bloch) -; "map3-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(r) as first argument") +; "map3-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(r) as first argument") ; Actually, the above is caught by Check Syntax, before map3-image has a chance to check anything. (check-error (map3-image sqrt + + pic:bloch) - "map3-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(r) as first argument") + "map3-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(r) as first argument") ;(check-error (map3-image + 5 + pic:bloch) -; "map3-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(g) as second argument") +; "map3-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(g) as second argument") (check-error (map3-image + sqrt + pic:bloch) - "map3-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(g) as second argument") + "map3-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(g) as second argument") ;(check-error (map3-image + + 5 pic:bloch) -; "map3-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") +; "map3-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") (check-error (map3-image + + sqrt pic:bloch) - "map3-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") + "map3-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") (check-error (map3-image + + + 5) - "map3-image: Expected image as fourth argument, but found 5") + "map3-image: Expected an image as fourth argument, but found 5") ; red-id : x y r g b -> num (define (red-id x y r g b) r) @@ -98,23 +98,23 @@ "Test cases for map4-image:" ;(check-error (map4-image 5 + + + pic:bloch) -; "map4-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) -> num(r) as first argument") +; "map4-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(r) as first argument") (check-error (map4-image sqrt + + + pic:bloch) - "map4-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(r) as first argument") + "map4-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(r) as first argument") ;(check-error (map4-image + 5 + + pic:bloch) -; "map4-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(g) as second argument") +; "map4-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(g) as second argument") (check-error (map4-image + sqrt + + pic:bloch) - "map4-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(g) as second argument") + "map4-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(g) as second argument") ;(check-error (map4-image + + 5 + pic:bloch) -; "map4-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(b) as third argument") +; "map4-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(b) as third argument") (check-error (map4-image + + sqrt + pic:bloch) - "map4-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(b) as third argument") + "map4-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(b) as third argument") ;(check-error (map4-image + + + 5 pic:bloch) -; "map4-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(a) as fourth argument") +; "map4-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(a) as fourth argument") (check-error (map4-image + + + sqrt pic:bloch) - "map4-image: Expected function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(alpha) as fourth argument") + "map4-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(alpha) as fourth argument") (check-error (map4-image + + + + 5) - "map4-image: Expected image as fifth argument, but found 5") + "map4-image: Expected an image as fifth argument, but found 5") ; red-id6 : x y r g b a -> num (define (red-id6 x y r g b a) r) ; green-id6 : x y r g b a -> num @@ -150,11 +150,11 @@ ; Test cases for map-image: ;(check-error (map-image 5 pic:bloch) -; "map-image: Expected function with contract num(x) num(y) color -> color as first argument") +; "map-image: Expected a function with contract num(x) num(y) color -> color as first argument") (check-error (map-image sqrt pic:bloch) - "map-image: Expected function with contract num(x) num(y) color -> color as first argument") + "map-image: Expected a function with contract num(x) num(y) color -> color as first argument") (check-error (map-image + 5) - "map-image: Expected image as second argument, but found 5") + "map-image: Expected an image as second argument, but found 5") ; color-id : x y color -> color (define (color-id x y c) @@ -187,7 +187,7 @@ (define ex6 (map-image kill-red bloch)) ex6 (define (return-5 x y c) 5) -(check-error (map-image return-5 bloch) "colorize: expected a color, but found 5") +(check-error (map-image return-5 bloch) "colorize: Expected a color, but found 5") "Test cases for build3-image:" (define (x-gradient-2 x y) (min 255 (* 4 x))) @@ -196,19 +196,19 @@ "(build3-image 60 40 zero-2-args x-gradient-2 y-gradient-2) should be a 60x40 rectangle with no red, green increasing from left to right, and blue increasing from top to bottom:" (build3-image 60 40 zero-2-args x-gradient-2 y-gradient-2) (check-error (build3-image "hello" true sqrt sqrt sqrt) - "build3-image: Expected natural number as first argument, but found \"hello\"") + "build3-image: Expected a natural number as first argument, but found \"hello\"") (check-error (build3-image 17 true sqrt sqrt sqrt) - "build3-image: Expected natural number as second argument, but found true") + "build3-image: Expected a natural number as second argument, but found true") (check-error (build3-image 17 24 sqrt sqrt sqrt) - "build3-image: Expected function with contract num(x) num(y) -> color as third argument") + "build3-image: Expected a function with contract num(x) num(y) -> color as third argument") (check-error (build3-image 17 24 x-gradient-2 sqrt sqrt) - "build3-image: Expected function with contract num(x) num(y) -> color as fourth argument") + "build3-image: Expected a function with contract num(x) num(y) -> color as fourth argument") (check-error (build3-image 17 24 x-gradient-2 y-gradient-2 sqrt) - "build3-image: Expected function with contract num(x) num(y) -> color as fifth argument") + "build3-image: Expected a function with contract num(x) num(y) -> color as fifth argument") (define (return-minus-5 x y) -5) (check-error (build3-image 17 24 x-gradient-2 y-gradient-2 return-minus-5) - "make-color: expected an integer between 0 and 255 as third argument, given: -5") + "make-color: Expected an integer between 0 and 255 as third argument, given: -5") "Test cases for build4-image:" "(build4-image 50 50 x-gradient-2 x-gradient-2 zero-2-args y-gradient-2) should be a square, increasingly yellow from left to right and increasingly alpha from top to bottom. On a blue background." @@ -225,9 +225,9 @@ "(build-image 100 100 (lambda (x y) (make-color (* x 2.5) (* y 2.5) 0))):" (build-image 100 100 a-gradient) "should be a 100x100 square with a color gradient increasing in red from left to right, and in green from top to bottom" -(check-error (build-image 3.2 100 a-gradient) "build-image: Expected natural number as first argument, but found 3.2") -(check-error (build-image 100 -2 a-gradient) "build-image: Expected natural number as second argument, but found -2") -(check-error (build-image 100 100 sqrt) "build-image: Expected function with contract num(x) num(y) -> color as third argument") +(check-error (build-image 3.2 100 a-gradient) "build-image: Expected a natural number as first argument, but found 3.2") +(check-error (build-image 100 -2 a-gradient) "build-image: Expected a natural number as second argument, but found -2") +(check-error (build-image 100 100 sqrt) "build-image: Expected a function with contract num(x) num(y) -> color as third argument") From 036f7bec064b585154714621e71a27a25c06fdfa Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 11 Jul 2011 06:37:57 -0600 Subject: [PATCH 231/746] fix JIT problem that can break futures A recent (weeks-old) JIT change set one of a function's code pointers to NULL to indicate that JIT-compilation of the function is in progress, but that breaks futures. Set the code pointer to a different not-yet-ready function, instead. Merge to 5.1.2 Closes PR 12037 (cherry picked from commit 09eab9c3ebdb88dc4f8a39a38b6b49fc74be35e2) --- src/racket/src/jit.c | 2 +- src/racket/src/jit.h | 2 +- src/racket/src/jitcall.c | 2 +- src/racket/src/jitcommon.c | 6 ++++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index 05a3fa89e3..e3ffa81ca7 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -3312,7 +3312,7 @@ static void on_demand_generate_lambda(Scheme_Native_Closure *nc, int argc, Schem if (ndata->code != scheme_on_demand_jit_code) return; - ndata->arity_code = NULL; /* => in progress */ + ndata->arity_code = sjc.in_progress_on_demand_jit_arity_code; /* => in progress */ scheme_generate_one(NULL, do_generate_closure, &gdata, 1, data->name, ndata); diff --git a/src/racket/src/jit.h b/src/racket/src/jit.h index 5d0ae881f9..27753a79d2 100644 --- a/src/racket/src/jit.h +++ b/src/racket/src/jit.h @@ -227,7 +227,7 @@ struct scheme_jit_common_record { void *fxvector_ref_code, *fxvector_ref_check_index_code, *fxvector_set_code, *fxvector_set_check_index_code; void *struct_raw_ref_code, *struct_raw_set_code; void *syntax_e_code; - void *on_demand_jit_arity_code; + void *on_demand_jit_arity_code, *in_progress_on_demand_jit_arity_code; void *get_stack_pointer_code; void *stack_cache_pop_code; void *struct_pred_code, *struct_pred_multi_code; diff --git a/src/racket/src/jitcall.c b/src/racket/src/jitcall.c index 23762634c9..9fee1ee2d9 100644 --- a/src/racket/src/jitcall.c +++ b/src/racket/src/jitcall.c @@ -1454,7 +1454,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ Scheme_Native_Closure *nc; nc = (Scheme_Native_Closure *)scheme_jit_closure((Scheme_Object *)data, NULL); if (nc->code->code == scheme_on_demand_jit_code) { - if (nc->code->arity_code) { /* i.e., not in progress */ + if (nc->code->arity_code != sjc.in_progress_on_demand_jit_arity_code) { scheme_on_demand_generate_lambda(nc, 0, NULL); } } diff --git a/src/racket/src/jitcommon.c b/src/racket/src/jitcommon.c index bcd89ad733..72987b7522 100644 --- a/src/racket/src/jitcommon.c +++ b/src/racket/src/jitcommon.c @@ -729,6 +729,12 @@ static int common2(mz_jit_state *jitter, void *_data) CHECK_LIMIT(); scheme_jit_register_helper_func(jitter, scheme_on_demand_jit_code); + /* Used for the state of a function that is being JITted + (for a kind of cycle detection) without breaking concurrent + future threads that might try to call the function. */ + sjc.in_progress_on_demand_jit_arity_code = jit_get_ip().ptr; + (void)jit_jmpi(sjc.on_demand_jit_arity_code); + /* *** app_values_tail_slow_code *** */ /* RELIES ON jit_prolog(NATIVE_ARG_COUNT) FROM ABOVE */ /* Rator in V1, arguments are in thread's multiple-values cells. */ From cef91e1527c4ab37756149b54822258878c20eec Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 11 Jul 2011 13:54:06 -0400 Subject: [PATCH 232/746] Revert "Add real->double-flonum to the JIT." This reverts commit 2afff3d2102761815872f67d11dec0688effca48. This commit caused real->double-flonum to have a different behavior when jitted as opposed to interpreted, and caused real->single-flonum to break in some cases. Merge to 5.1.2. (cherry picked from commit 7dfe1f636f94b0eff4bab90db9d9d13d620bae43) --- src/racket/src/jitinline.c | 3 +-- src/racket/src/number.c | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/racket/src/jitinline.c b/src/racket/src/jitinline.c index 58ef3ac8a5..06e7d32dcd 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -1108,8 +1108,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in || IS_NAMED_PRIM(rator, "fllog")) { scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_FLUNOP, 0, 0, NULL, 1, 0, -1, NULL); return 1; - } else if (IS_NAMED_PRIM(rator, "exact->inexact") - || IS_NAMED_PRIM(rator, "real->double-flonum")) { + } else if (IS_NAMED_PRIM(rator, "exact->inexact")) { scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_EX_INEX, 0, 0, NULL, 1, 0, 0, NULL); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx->fl")) { diff --git a/src/racket/src/number.c b/src/racket/src/number.c index cd0081bda5..02b9751214 100644 --- a/src/racket/src/number.c +++ b/src/racket/src/number.c @@ -374,10 +374,6 @@ scheme_init_number (Scheme_Env *env) scheme_add_global_constant("single-flonum?", p, env); p = scheme_make_folding_prim(real_to_single_flonum, "real->single-flonum", 1, 1, 1); - if (scheme_can_inline_fp_op()) - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; - else - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_SOMETIMES_INLINED; scheme_add_global_constant("real->single-flonum", p, env); p = scheme_make_folding_prim(real_to_double_flonum, "real->double-flonum", 1, 1, 1); From 73fb46b42bba866c99aa69c06f1b006cb1f6c283 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 11 Jul 2011 12:24:36 -0400 Subject: [PATCH 233/746] Add tests for jitted real->*-flonum. (cherry picked from commit 427eaca513b06ce24ab527acc7ac783b0b2dc4d3) --- collects/tests/racket/number.rktl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/collects/tests/racket/number.rktl b/collects/tests/racket/number.rktl index 7c55c1ec93..15a9c0991f 100644 --- a/collects/tests/racket/number.rktl +++ b/collects/tests/racket/number.rktl @@ -686,6 +686,16 @@ (test 2.25 real->double-flonum 2.25) (test 2.25 real->double-flonum 2.25f0) +;; to make sure they work when jitted +(define (r->s-f x) (real->single-flonum x)) +(define (r->d-f x) (real->double-flonum x)) +(test 2.0f0 r->s-f 2) +(test 2.25f0 r->s-f 2.25) +(test 2.25f0 r->s-f 2.25f0) +(test 2.0 r->d-f 2) +(test 2.25 r->d-f 2.25) +(test 2.25 r->d-f 2.25f0) + (err/rt-test (* 'a 0)) (err/rt-test (+ 'a 0)) (err/rt-test (/ 'a 0)) From 07511110119190bf46e5ed46980a334a67a681ac Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 11 Jul 2011 12:32:23 -0400 Subject: [PATCH 234/746] Fix jitting of real->double-flonum. Merge to 5.1.2. (cherry picked from commit 09b6616bfa0f7a56e9ea362df6e8517cd76272ae) --- src/racket/src/jitinline.c | 3 ++- src/racket/src/number.c | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/racket/src/jitinline.c b/src/racket/src/jitinline.c index 06e7d32dcd..58ef3ac8a5 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -1108,7 +1108,8 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in || IS_NAMED_PRIM(rator, "fllog")) { scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_FLUNOP, 0, 0, NULL, 1, 0, -1, NULL); return 1; - } else if (IS_NAMED_PRIM(rator, "exact->inexact")) { + } else if (IS_NAMED_PRIM(rator, "exact->inexact") + || IS_NAMED_PRIM(rator, "real->double-flonum")) { scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_EX_INEX, 0, 0, NULL, 1, 0, 0, NULL); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx->fl")) { diff --git a/src/racket/src/number.c b/src/racket/src/number.c index 02b9751214..d478e78350 100644 --- a/src/racket/src/number.c +++ b/src/racket/src/number.c @@ -377,6 +377,10 @@ scheme_init_number (Scheme_Env *env) scheme_add_global_constant("real->single-flonum", p, env); p = scheme_make_folding_prim(real_to_double_flonum, "real->double-flonum", 1, 1, 1); + if (scheme_can_inline_fp_op()) + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + else + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_SOMETIMES_INLINED; scheme_add_global_constant("real->double-flonum", p, env); scheme_add_global_constant("exact?", From 6ca28bc60cbcf2bc3637113bb4c0b98a77ed93cb Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 11 Jul 2011 15:35:49 -0400 Subject: [PATCH 235/746] Fix test for new contract error message format. (cherry picked from commit 79ef8e889e327cd50df683ff9594b83f5a50cc64) --- collects/tests/typed-scheme/fail/pr10594.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/tests/typed-scheme/fail/pr10594.rkt b/collects/tests/typed-scheme/fail/pr10594.rkt index 7d524f3f26..89f6eb5a6f 100644 --- a/collects/tests/typed-scheme/fail/pr10594.rkt +++ b/collects/tests/typed-scheme/fail/pr10594.rkt @@ -1,5 +1,5 @@ #; -(exn-pred exn:fail:contract? #rx".*contract violation.*blaming 'U.*") +(exn-pred exn:fail:contract? #rx".*contract violation.*blaming U.*") #lang scheme/load (module T typed-scheme From 289e82b0b7ce1709bbd4443cee6e6e4f6ce72239 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 11 Jul 2011 15:35:04 -0600 Subject: [PATCH 236/746] updated docs for struct-type-contract/c (cherry picked from commit 5a10ef75505449b226816fd864fe29f7e8c156cc) --- .../unstable/scribblings/prop-contract.scrbl | 61 +++++++++++++------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/collects/unstable/scribblings/prop-contract.scrbl b/collects/unstable/scribblings/prop-contract.scrbl index a77f8ffcdf..ca74af499f 100644 --- a/collects/unstable/scribblings/prop-contract.scrbl +++ b/collects/unstable/scribblings/prop-contract.scrbl @@ -16,34 +16,57 @@ Produces a contract for struct type properties. When the contract is applied to a struct type property, it produces a wrapped struct type -property. When the wrapped struct type property is used to create a -new struct type (via @racket[struct], @racket[make-struct-type], etc), -it applies @racket[value-contract] to the value associated with the -property. +property that applies @racket[value-contract] to the value associated +with the property when used to create a new struct type (via +@racket[struct], @racket[make-struct-type], etc). -The contract has no effect on the struct type property accessor. +The struct type property's accessor function is not affected; it must +be protected separately. @examples[#:eval the-eval -(define-values (prop prop? prop-ref) - (make-struct-type-property 'prop)) +(module propmod racket + (require racket/contract + unstable/prop-contract) + (define-values (prop prop? prop-ref) + (make-struct-type-property 'prop)) + (define (prop-app x v) + (((prop-ref x) x) v)) + (provide/contract + [prop? (-> any/c boolean?)] + [prop (struct-type-property/c + (-> prop? (-> number? boolean?)))] + [prop-app (-> prop? number? boolean?)]) + (provide prop-ref)) -(define/contract wrapped - (struct-type-property/c (-> any/c (-> number? number?))) - prop) +(module structmod racket + (require 'propmod) + (struct s (f) #:property prop (lambda (s) (s-f s))) + (provide (struct-out s))) -(struct s (f) - #:property wrapped (lambda (s) (s-f s))) +(require 'propmod 'structmod) +(define s1 (s even?)) +(prop-app s1 5) +(prop-app s1 'apple) -(define (get-f s) ((prop-ref s) s)) +(define s2 (s "not a fun")) +(prop-app s2 5) -(define s1 (s add1)) -((get-f s1) 5) -((get-f s1) 'apple) +(define s3 (s list)) +(prop-app s3 5) -(define s2 (s (lambda (n) (if (zero? n) 'zero 'nonzero)))) -((get-f s2) 5) -((get-f s2) 'apple) +((prop-ref s3) 'apple) ] +The first contract error above is a simple function contract violation +on @racket[prop-app]. The second and third contract errors above blame +the @racketidfont{structmod} module, because it accepted the struct type +property contract. To avoid blame, @racketidfont{structmod} +should have placed a contract on @racket[s]. The final contract error, +involving @racket[s3], blames @racketidfont{propmod} because the struct +type property contract obliges @racketidfont{propmod} to make sure the +property's value is not misused, but @racketidfont{propmod} allows +direct access to the property value via @racket[prop-ref]. To +avoid blame, @racketidfont{propmod} should remove the export of +@racket[prop-ref] or protect it with a contract. } @close-eval[the-eval] From 4f794fe496339e94872f5075c564053ca6c37f09 Mon Sep 17 00:00:00 2001 From: Stephen Bloch Date: Tue, 12 Jul 2011 07:08:47 -0400 Subject: [PATCH 237/746] Fixed some more error messages. (cherry picked from commit 52527d8a95d3415b0f1808a5903aa00ed69f8a93) --- .../picturing-programs/private/map-image.rkt | 32 +++++++++---------- .../tests/map-image-bsl-tests.rkt | 24 +++++++------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/collects/picturing-programs/private/map-image.rkt b/collects/picturing-programs/private/map-image.rkt index c9dc2cae03..10865a4ea1 100644 --- a/collects/picturing-programs/private/map-image.rkt +++ b/collects/picturing-programs/private/map-image.rkt @@ -86,7 +86,7 @@ (define (name->color name) (unless (or (string? name) (symbol? name)) (error 'name->color - (format "Expected a string or symbol, but found ~v" name))) + (format "Expected a string or symbol, but received ~v" name))) (let [[result (send the-color-database find-color (if (string? name) name @@ -101,7 +101,7 @@ (cond [(color? thing) thing] [(eqv? thing #f) transparent] [(image-color? thing) (name->color thing)] - [else (error 'colorize (format "Expected a color, but found ~v" thing))])) + [else (error 'colorize (format "Expected a color, but received ~v" thing))])) ; colorize-func : (... -> broad-color) -> (... -> color) (define (colorize-func f) @@ -119,10 +119,10 @@ [rc2 (colorize c2)]] (unless (color? rc1) (error 'color=? - (format "Expected a color or color name as first argument, but found ~v" c1))) + (format "Expected a color or color name as first argument, but received ~v" c1))) (unless (color? rc2) (error 'color=? - (format "Expected a color or color name as second argument, but found ~v" c2))) + (format "Expected a color or color name as second argument, but received ~v" c2))) (and (= (color-alpha rc1) (color-alpha rc2)) ; Both alphas MUST be equal. (or (= (color-alpha rc1) 0) ; If both are transparent, ignore rgb. (and (= (color-red rc1) (color-red rc2)) @@ -214,10 +214,10 @@ (define (build-image w h f) (unless (natural? w) (error 'build-image - (format "Expected a natural number as first argument, but found ~v" w))) + (format "Expected a natural number as first argument, but received ~v" w))) (unless (natural? h) (error 'build-image - (format "Expected a natural number as second argument, but found ~v" h))) + (format "Expected a natural number as second argument, but received ~v" h))) (check-procedure-arity f 2 'build-image "Expected a function with contract num(x) num(y) -> color as third argument") (build-image-internal w h (colorize-func f))) @@ -227,10 +227,10 @@ (define (build-image/extra w h f extra) (unless (natural? w) (error 'build-image/extra - (format "Expected a natural number as first argument, but found ~v" w))) + (format "Expected a natural number as first argument, but received ~v" w))) (unless (natural? h) (error 'build-image/extra - (format "Expected a natural number as second argument, but found ~v" h))) + (format "Expected a natural number as second argument, but received ~v" h))) (check-procedure-arity f 3 'build-image/extra "Expected a function with contract num(x) num(y) any -> color as third argument") (build-image-internal w h (colorize-func (lambda (x y) (f x y extra))))) @@ -240,10 +240,10 @@ (define (build3-image w h rfunc gfunc bfunc) (unless (natural? w) (error 'build3-image - (format "Expected a natural number as first argument, but found ~v" w))) + (format "Expected a natural number as first argument, but received ~v" w))) (unless (natural? h) (error 'build3-image - (format "Expected a natural number as second argument, but found ~v" h))) + (format "Expected a natural number as second argument, but received ~v" h))) (check-procedure-arity rfunc 2 'build3-image "Expected a function with contract num(x) num(y) -> color as third argument") (check-procedure-arity gfunc 2 'build3-image "Expected a function with contract num(x) num(y) -> color as fourth argument") (check-procedure-arity bfunc 2 'build3-image "Expected a function with contract num(x) num(y) -> color as fifth argument") @@ -256,10 +256,10 @@ (define (build4-image w h rfunc gfunc bfunc afunc) (unless (natural? w) (error 'build-image - (format "Expected a natural number as first argument, but found ~v" w))) + (format "Expected a natural number as first argument, but received ~v" w))) (unless (natural? h) (error 'build-image - (format "Expected a natural number as second argument, but found ~v" h))) + (format "Expected a natural number as second argument, but received ~v" h))) (check-procedure-arity rfunc 2 'build-image "Expected a function with contract num(x) num(y) -> color as third argument") (check-procedure-arity gfunc 2 'build-image "Expected a function with contract num(x) num(y) -> color as fourth argument") (check-procedure-arity bfunc 2 'build-image "Expected a function with contract num(x) num(y) -> color as fifth argument") @@ -291,7 +291,7 @@ (check-procedure-arity f 3 'map-image "Expected a function with contract num(x) num(y) color -> color as first argument") (unless (image? img) (error 'map-image - (format "Expected an image as second argument, but found ~v" img))) + (format "Expected an image as second argument, but received ~v" img))) (map-image-internal (colorize-func f) img)) ; map-image/extra : (nat nat color X -> broad-color) image X -> image @@ -301,7 +301,7 @@ (check-procedure-arity f 4 'map-image/extra "Expected a function with contract num(x) num(y) color other -> color as first argument") (unless (image? img) (error 'map-image/extra - (format "Expected an image as second argument, but found ~v" img))) + (format "Expected an image as second argument, but received ~v" img))) (map-image-internal (colorize-func (lambda (x y c) (f x y c extra))) img)) @@ -320,7 +320,7 @@ (check-procedure-arity bfunc 5 'map3-image "Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") (unless (image? pic) (error 'map3-image - (format "Expected an image as fourth argument, but found ~v" pic))) + (format "Expected an image as fourth argument, but received ~v" pic))) (map-image-internal (lambda (x y c) (make-color (rfunc x y (color-red c) (color-green c) (color-blue c)) @@ -342,7 +342,7 @@ (check-procedure-arity afunc 6 'map4-image "Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(alpha) as fourth argument") (unless (image? pic) (error 'map4-image - "Expected an image as fifth argument, but found ~v" pic)) + "Expected an image as fifth argument, but received ~v" pic)) (map-image-internal (lambda (x y c) (make-color (rfunc x y (color-red c) (color-green c) (color-blue c) (color-alpha c)) diff --git a/collects/picturing-programs/tests/map-image-bsl-tests.rkt b/collects/picturing-programs/tests/map-image-bsl-tests.rkt index ec270cf90c..673a3615fb 100644 --- a/collects/picturing-programs/tests/map-image-bsl-tests.rkt +++ b/collects/picturing-programs/tests/map-image-bsl-tests.rkt @@ -24,7 +24,7 @@ (check-expect (name->color "black") (make-color 0 0 0)) (check-expect (name->color "blue") (make-color 0 0 255)) (check-expect (name->color "plaid") false) -(check-error (name->color 7) "name->color: Expected a string or symbol, but found 7") +(check-error (name->color 7) "name->color: Expected a string or symbol, but received 7") (check-expect (color=? (make-color 5 10 15) (make-color 5 10 15)) true) (check-expect (color=? (make-color 5 10 15) (make-color 5 15 10)) false) @@ -36,9 +36,9 @@ (check-expect (color=? (make-color 5 10 15 255) (make-color 5 10 15)) true) (check-expect (color=? (make-color 5 10 15 0) false) true) (check-expect (color=? (make-color 5 10 15 20) false) false) -(check-error (color=? "white" 3) "colorize: Expected a color, but found 3") -(check-error (color=? "plaid" "white") "color=?: Expected a color or color name as first argument, but found \"plaid\"") -(check-error (color=? "white" "plaid") "color=?: Expected a color or color name as second argument, but found \"plaid\"") +(check-error (color=? "white" 3) "colorize: Expected a color, but received 3") +(check-error (color=? "plaid" "white") "color=?: Expected a color or color name as first argument, but received \"plaid\"") +(check-error (color=? "white" "plaid") "color=?: Expected a color or color name as second argument, but received \"plaid\"") ; Test cases for map3-image: ;(check-error (map3-image 5 + + pic:bloch) @@ -55,7 +55,7 @@ (check-error (map3-image + + sqrt pic:bloch) "map3-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) -> num(b) as third argument") (check-error (map3-image + + + 5) - "map3-image: Expected an image as fourth argument, but found 5") + "map3-image: Expected an image as fourth argument, but received 5") ; red-id : x y r g b -> num (define (red-id x y r g b) r) @@ -114,7 +114,7 @@ (check-error (map4-image + + + sqrt pic:bloch) "map4-image: Expected a function with contract num(x) num(y) num(r) num(g) num(b) num(alpha) -> num(alpha) as fourth argument") (check-error (map4-image + + + + 5) - "map4-image: Expected an image as fifth argument, but found 5") + "map4-image: Expected an image as fifth argument, but received 5") ; red-id6 : x y r g b a -> num (define (red-id6 x y r g b a) r) ; green-id6 : x y r g b a -> num @@ -154,7 +154,7 @@ (check-error (map-image sqrt pic:bloch) "map-image: Expected a function with contract num(x) num(y) color -> color as first argument") (check-error (map-image + 5) - "map-image: Expected an image as second argument, but found 5") + "map-image: Expected an image as second argument, but received 5") ; color-id : x y color -> color (define (color-id x y c) @@ -187,7 +187,7 @@ (define ex6 (map-image kill-red bloch)) ex6 (define (return-5 x y c) 5) -(check-error (map-image return-5 bloch) "colorize: Expected a color, but found 5") +(check-error (map-image return-5 bloch) "colorize: Expected a color, but received 5") "Test cases for build3-image:" (define (x-gradient-2 x y) (min 255 (* 4 x))) @@ -196,9 +196,9 @@ "(build3-image 60 40 zero-2-args x-gradient-2 y-gradient-2) should be a 60x40 rectangle with no red, green increasing from left to right, and blue increasing from top to bottom:" (build3-image 60 40 zero-2-args x-gradient-2 y-gradient-2) (check-error (build3-image "hello" true sqrt sqrt sqrt) - "build3-image: Expected a natural number as first argument, but found \"hello\"") + "build3-image: Expected a natural number as first argument, but received \"hello\"") (check-error (build3-image 17 true sqrt sqrt sqrt) - "build3-image: Expected a natural number as second argument, but found true") + "build3-image: Expected a natural number as second argument, but received true") (check-error (build3-image 17 24 sqrt sqrt sqrt) "build3-image: Expected a function with contract num(x) num(y) -> color as third argument") (check-error (build3-image 17 24 x-gradient-2 sqrt sqrt) @@ -225,8 +225,8 @@ "(build-image 100 100 (lambda (x y) (make-color (* x 2.5) (* y 2.5) 0))):" (build-image 100 100 a-gradient) "should be a 100x100 square with a color gradient increasing in red from left to right, and in green from top to bottom" -(check-error (build-image 3.2 100 a-gradient) "build-image: Expected a natural number as first argument, but found 3.2") -(check-error (build-image 100 -2 a-gradient) "build-image: Expected a natural number as second argument, but found -2") +(check-error (build-image 3.2 100 a-gradient) "build-image: Expected a natural number as first argument, but received 3.2") +(check-error (build-image 100 -2 a-gradient) "build-image: Expected a natural number as second argument, but received -2") (check-error (build-image 100 100 sqrt) "build-image: Expected a function with contract num(x) num(y) -> color as third argument") From 95ed19b91ffbf61217b7026bf450e1d3924e8e6e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 13 Jul 2011 06:46:44 -0600 Subject: [PATCH 238/746] fix bad contract (cherry picked from commit 2fb03852b34e326a870f6647ac4b39829e31f53f) --- collects/scribblings/framework/group.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/framework/group.scrbl b/collects/scribblings/framework/group.scrbl index f89e289ae1..84cd1d6547 100644 --- a/collects/scribblings/framework/group.scrbl +++ b/collects/scribblings/framework/group.scrbl @@ -85,7 +85,7 @@ each frame in the group. } - @defmethod*[(((can-close-all?) void?))]{ + @defmethod*[(((can-close-all?) boolean?))]{ Call this method to make sure that closing all of the frames in the frame groups is permitted by the user. The function @method[group:% on-close-all] is expected to be called just after this method is called. From 8d0d481d634c668be7b76a7ed930cd82d115c16b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 13 Jul 2011 10:44:30 -0600 Subject: [PATCH 239/746] rebuild Mac x86 libraries to work with 10.4 Merge to 5.1.2 (cherry picked from commit 0860e62bfaa30b229c9bb8a31485fb37109f08da) --- src/get-libs.rkt | 24 ++++++++++++------------ src/mac/README.txt | 10 +++++++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/get-libs.rkt b/src/get-libs.rkt index 31c61f99a8..aaf4993596 100644 --- a/src/get-libs.rkt +++ b/src/get-libs.rkt @@ -6,7 +6,7 @@ ;; without using bytecode. (define url-host "download.racket-lang.org") -(define url-path "/libs/2/") +(define url-path "/libs/3/") (define url-base (string-append "http://" url-host url-path)) (provide all-files+sizes) @@ -28,18 +28,18 @@ ;; GUI Libraries [gui [i386-macosx - ["libcairo.2.dylib" 832656] - ["libintl.8.dylib" 57536] - ["libgio-2.0.0.dylib" 748360] + ["libcairo.2.dylib" 805952] + ["libintl.8.dylib" 57604] + ["libgio-2.0.0.dylib" 747088] ["libjpeg.62.dylib" 412024] - ["libglib-2.0.0.dylib" 1015008] - ["libpango-1.0.0.dylib" 347180] - ["libgmodule-2.0.0.dylib" 19016] - ["libpangocairo-1.0.0.dylib" 84340] - ["libgobject-2.0.0.dylib" 288252] - ["libpixman-1.0.dylib" 526824] - ["libgthread-2.0.0.dylib" 24592] - ["libpng14.14.dylib" 182992] + ["libglib-2.0.0.dylib" 1014032] + ["libpango-1.0.0.dylib" 347300] + ["libgmodule-2.0.0.dylib" 18996] + ["libpangocairo-1.0.0.dylib" 84364] + ["libgobject-2.0.0.dylib" 288244] + ["libpixman-1.0.dylib" 527016] + ["libgthread-2.0.0.dylib" 24556] + ["libpng14.14.dylib" 183016] ["PSMTabBarControl.tgz" 91302 "PSMTabBarControl.framework" 247768]] [x86_64-macosx ["libcairo.2.dylib" 919840] diff --git a/src/mac/README.txt b/src/mac/README.txt index 085dbca57d..ea83654819 100644 --- a/src/mac/README.txt +++ b/src/mac/README.txt @@ -43,10 +43,14 @@ Configures (where is some temporary area): pkg-config: --prefix= libpng: --prefix= pixman: --prefix= - Cairo: PATH=/bin --disable-xlib --disable-ft --disable-fc --prefix= + Cairo: PATH=/bin:... --disable-xlib --disable-ft --disable-fc --prefix= gettext: --prefix= - glib: PATH=/bin CFLAGS=-I/include LDFLAGS=-L/lib --prefix= - Pango: PATH=/bin --without-x --with-included-modules=yes --with-dynamic-modules=no + glib: PATH=/bin:... CFLAGS=-I/include LDFLAGS=-L/lib --prefix= + Pango: PATH=/bin:... --without-x --with-included-modules=yes --with-dynamic-modules=no + + To support 10.4, add + CC=gcc-4.0 CPPFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" + for all packages. Note: PATH above ensures that pkg-config binaries are used to find things in rather than some other area, such as /opt/local. From 60f3e79bb802f958213f916c0961a7ac9bd4326a Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 13 Jul 2011 15:34:55 -0400 Subject: [PATCH 240/746] Use real contract in bitmap% docs (cherry picked from commit 2fdc56db3af0ed2065d29639b60584fd97580651) --- collects/scribblings/draw/bitmap-class.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/draw/bitmap-class.scrbl b/collects/scribblings/draw/bitmap-class.scrbl index a987475ec5..171fab7f78 100644 --- a/collects/scribblings/draw/bitmap-class.scrbl +++ b/collects/scribblings/draw/bitmap-class.scrbl @@ -62,7 +62,7 @@ When a @racket[bits] byte string is provided: Creates a monochrome [y real?] [width exact-nonnegative-integer?] [height exact-nonnegative-integer?] - [pixels (and/c bytes? mutable?)] + [pixels (and/c bytes? (not/c immutable?))] [just-alpha? any/c #f] [pre-multiplied? any/c #f]) void?]{ From 7f7618dd0735f9bc8ab276a6994da812e8c733a6 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Wed, 13 Jul 2011 18:00:35 -0400 Subject: [PATCH 241/746] small edit to doc of atan; Closes PR 12039 (cherry picked from commit 03dc212d61babec305209832dd4c9a5c1afd9271) --- collects/lang/private/beginner-funs.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/lang/private/beginner-funs.rkt b/collects/lang/private/beginner-funs.rkt index a7973a1cb4..27dc2860df 100644 --- a/collects/lang/private/beginner-funs.rkt +++ b/collects/lang/private/beginner-funs.rkt @@ -73,8 +73,8 @@ "Evaluates the arcsine (inverse of sin) of a number.") (acos (number -> number) "Evaluates the arccosine (inverse of cos) of a number.") - (atan (number -> number) - "Evaluates the arctan (inverse of tan) of a number.") + (atan (number [number] -> number) + "Evaluates the arctan of the given number or the ratio of the two given numbers.") (sinh (number -> number) "Evaluates the hyperbolic sine of a number.") From 72a81a7c124670514b5c06dfdba372c61fd48724 Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Wed, 13 Jul 2011 23:51:06 -0400 Subject: [PATCH 242/746] Fixed that 'all contracts for primitives print as lists' bug in scribblings/htdp-langs. (cherry picked from commit 452f3a14fb7b25e6c54d08abdb8770fb20e68752) --- collects/scribblings/htdp-langs/prim-ops.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/htdp-langs/prim-ops.rkt b/collects/scribblings/htdp-langs/prim-ops.rkt index 3d78579f8c..6fdd02885c 100644 --- a/collects/scribblings/htdp-langs/prim-ops.rkt +++ b/collects/scribblings/htdp-langs/prim-ops.rkt @@ -5,7 +5,7 @@ scribble/struct scribble/racket racket/list - racket/pretty + scheme/pretty syntax/docprovide (for-syntax racket/base) ) From fd6d7de5066190e11e41ceb3f8f1428af1ba68f4 Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Thu, 14 Jul 2011 00:12:47 -0400 Subject: [PATCH 243/746] Better fix for the previous bug. (cherry picked from commit 793d7894f1e63f6b183c3e717f9d522133b39afb) --- collects/scribblings/htdp-langs/prim-ops.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/scribblings/htdp-langs/prim-ops.rkt b/collects/scribblings/htdp-langs/prim-ops.rkt index 6fdd02885c..473e39851b 100644 --- a/collects/scribblings/htdp-langs/prim-ops.rkt +++ b/collects/scribblings/htdp-langs/prim-ops.rkt @@ -5,7 +5,7 @@ scribble/struct scribble/racket racket/list - scheme/pretty + racket/pretty syntax/docprovide (for-syntax racket/base) ) @@ -33,7 +33,7 @@ (define (typeset-type type) (let-values ([(in out) (make-pipe)]) (parameterize ([pretty-print-columns 50]) - (pretty-print type out)) + (pretty-write type out)) (port-count-lines! in) (read-syntax #f in))) From ef167bb249d1e7b7a79c743534bce6e745c353ba Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Thu, 14 Jul 2011 01:45:51 -0400 Subject: [PATCH 244/746] Fixed some missing links in the documentation. (cherry picked from commit da6e819b6f40ee246f6e6534d411250d70b68782) --- collects/htdp/error-reporting.scrbl | 4 +++- collects/htdp/error.rkt | 2 +- collects/htdp/htdp-lib.scrbl | 5 +++-- collects/htdp/testing.rkt | 4 ++-- collects/htdp/testing.scrbl | 29 +++++++++++++++-------------- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/collects/htdp/error-reporting.scrbl b/collects/htdp/error-reporting.scrbl index 4d46e46f47..452e82cbf5 100755 --- a/collects/htdp/error-reporting.scrbl +++ b/collects/htdp/error-reporting.scrbl @@ -1,6 +1,8 @@ #lang scribble/doc -@(require scribble/manual) +@(require scribble/manual + (for-label htdp/error) + ) @title[#:tag "error-reporting"]{Error Reporting Functions} diff --git a/collects/htdp/error.rkt b/collects/htdp/error.rkt index 9708d75dc4..21883517a1 100644 --- a/collects/htdp/error.rkt +++ b/collects/htdp/error.rkt @@ -114,7 +114,7 @@ ;; check-arg : sym bool str (or/c str non-negative-integer) TST -> void (define (check-arg pname condition expected arg-posn given) (unless condition - (tp-error pname "expects a ~a as ~a argument, given: ~e" + (tp-error pname "expects a ~a as ~a argument, given ~e" expected (spell-out arg-posn) given))) diff --git a/collects/htdp/htdp-lib.scrbl b/collects/htdp/htdp-lib.scrbl index 7d84f4abf4..154150320a 100755 --- a/collects/htdp/htdp-lib.scrbl +++ b/collects/htdp/htdp-lib.scrbl @@ -1,6 +1,7 @@ #lang scribble/doc -@(require scribble/manual scribble/eval) +@(require scribble/manual scribble/eval + (for-label lang/prim lang/imageeq lang/posn racket/gui/base)) @(define (htdp-ref s) @secref[#:doc '(lib "scribblings/htdp-langs/htdp-langs.scrbl") s]) @title{HtDP Languages as Libraries} @@ -72,7 +73,7 @@ libraries in legacy form. It provides the bindings of @defmodule[lang/plt-pretty-big] The @racketmodname[lang/plt-pretty-big] module extends -@racket[lang/plt-pretty-big-text] with @racketmodname[scheme/gui/base] +@racket[lang/plt-pretty-big-text] with @racketmodname[racket/gui/base] and @racketmodname[lang/imageeq]. This language corresponds to the @onscreen{Pretty Big} legacy language in DrRacket. diff --git a/collects/htdp/testing.rkt b/collects/htdp/testing.rkt index 0be8f0e45d..614ef15449 100644 --- a/collects/htdp/testing.rkt +++ b/collects/htdp/testing.rkt @@ -1,8 +1,8 @@ #lang scheme/base -(require test-engine/scheme-tests) +(require test-engine/racket-tests) (define (generate-report) (test)#;(void)) -(provide (all-from-out test-engine/scheme-tests) +(provide (all-from-out test-engine/racket-tests) generate-report) diff --git a/collects/htdp/testing.scrbl b/collects/htdp/testing.scrbl index 43caa5f74d..dbae46f672 100755 --- a/collects/htdp/testing.scrbl +++ b/collects/htdp/testing.scrbl @@ -1,25 +1,26 @@ #lang scribble/doc -@(require scribble/manual) +@(require scribble/manual + (for-label test-engine/racket-tests)) @title{Testing} @; ----------------------------------------------------------------------------- -@defmodule[htdp/testing #:use-sources (test-engine/scheme-tests)] +@defmodule[htdp/testing #:use-sources (test-engine/racket-tests)] -The library re-exports the following identifiers from test-engine/scheme-tests: +The library re-exports the following identifiers from test-engine/racket-tests: - @racket[build-test-engine] - @racket[builder] - @racket[display-results] - @racket[error-handler] - @racket[exn:fail:wish] - @racket[generate-report] - @racket[get-test-engine] - @racket[reset-tests] - @racket[run-tests] - @racket[scheme-test-data] - @racket[signature-test-info%] +@defproc[(build-test-engine) void?] +@defproc[(builder) void?] +@defproc[(display-results) void?] +@defproc[(error-handler) void?] +@defproc[(exn:fail:wish) void?] +@defproc[(generate-report) void?] +@defproc[(get-test-engine) void?] +@defproc[(reset-tests) void?] +@defproc[(run-tests) void?] +@defproc[(scheme-test-data) void?] +@defproc[(signature-test-info%) void?] @(require scribble/eval From f5923dd7488b113a3efe6c73f6991188ad7dbb25 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Thu, 14 Jul 2011 12:02:40 -0400 Subject: [PATCH 245/746] sk requested empty scenes with optional background color (cherry picked from commit 40948ee653f99201dbd85b5633d1fbe0b09cc9b0) --- collects/2htdp/private/image-more.rkt | 4 ++-- collects/teachpack/2htdp/scribblings/image.scrbl | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/collects/2htdp/private/image-more.rkt b/collects/2htdp/private/image-more.rkt index 4e7fb86648..78bc2de002 100644 --- a/collects/2htdp/private/image-more.rkt +++ b/collects/2htdp/private/image-more.rkt @@ -882,10 +882,10 @@ (check-mode/color-combination 'square 3 mode color) (make-a-polygon (rectangle-points side-length side-length) mode color)) -(define/chk (empty-scene width height) +(define/chk (empty-scene width height [color 'white]) (crop 0 0 width height (overlay (rectangle width height 'outline (pen "black" 2 'solid 'round 'round)) - (rectangle width height 'solid 'white)))) + (rectangle width height 'solid color)))) (define/chk (rhombus side-length angle mode color) (check-mode/color-combination 'rhombus 3 mode color) diff --git a/collects/teachpack/2htdp/scribblings/image.scrbl b/collects/teachpack/2htdp/scribblings/image.scrbl index c3b5eaec3e..eb525bd515 100644 --- a/collects/teachpack/2htdp/scribblings/image.scrbl +++ b/collects/teachpack/2htdp/scribblings/image.scrbl @@ -936,14 +936,20 @@ the @racket[point-count] argument determines how many points the star has. Placing images into scenes is particularly useful when building worlds and universes using @racket[2htdp/universe]. -@defproc[(empty-scene [width (and/c real? (not/c negative?))] - [height (and/c real? (not/c negative?))]) - image?]{ +@defproc*[([(empty-scene [width (and/c real? (not/c negative?))] + [height (and/c real? (not/c negative?))]) + image?] + [(empty-scene [width (and/c real? (not/c negative?))] + [height (and/c real? (not/c negative?))] + [color image-color?]) + image?])]{ -Creates an empty scene, i.e., a rectangle with a black outline. +Creates an empty scene, i.e., a white rectangle with a black outline. @image-examples[(empty-scene 160 90)] - + +The three-argument version creates a rectangle of the specified color with +a black outline. } @defproc[(place-image [image image?] [x real?] [y real?] [scene image?]) image?]{ From 4b3c7d0aece38e0984661ca37fb9f5baeaf29e5b Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 14 Jul 2011 12:04:38 -0400 Subject: [PATCH 246/746] Switch tcsh(!) and bash scripts to use /bin/sh. (Satisfy some 3rd-party packaging linters.) (cherry picked from commit 69464bba9194fb38418d59f5f918b961c8c18cdd) --- collects/2htdp/tests/xtest | 69 +++++++++++++-------------------- collects/2htdp/uchat/xrun | 6 +-- collects/meta/drdr/copy.sh | 3 +- collects/meta/drdr/good-init.sh | 7 ++-- 4 files changed, 37 insertions(+), 48 deletions(-) diff --git a/collects/2htdp/tests/xtest b/collects/2htdp/tests/xtest index 1427362f9c..d2561c46db 100755 --- a/collects/2htdp/tests/xtest +++ b/collects/2htdp/tests/xtest @@ -1,43 +1,30 @@ -#!/bin/tcsh +#!/bin/sh -gracket bad-draw.rkt -echo "done:--- bad-draw.rkt ---" echo "" -racket batch-io.rkt -echo "done:--- batch-io.rkt ---" echo "" -gracket clause-once.rkt -echo "done:--- clause-once.rkt ---" echo "" -gracket full-scene-visible.rkt -echo "done:--- full-scene-visible.rkt ---" echo "" -gracket image-too-large.rkt -echo "done:--- image-too-large.rkt ---" echo "" -gracket image-equality-performance-htdp.rkt -echo "done:--- image-equality-performance-htdp.rkt ---" echo "" -gracket image-equality-performance.rkt -echo "done:--- image-equality-performance.rkt ---" echo "" -gracket mouse-evt.rkt -echo "done:--- mouse-evt.rkt ---" echo "" -gracket on-tick-defined.rkt -echo "done:--- on-tick-defined.rkt ---" echo "" -gracket perform-robby.rkt -echo "done:--- perform-robby.rkt ---" echo "" -gracket profile-robby.rkt -echo "done:--- profile-robby.rkt ---" echo "" -gracket release.rkt -echo "done:--- release.rkt ---" echo "" -gracket stop.rkt -echo "done:--- stop.rkt ---" echo "" -gracket test-image.rkt -echo "done:--- test-image.rkt ---" echo "" -gracket ufo-rename.rkt -echo "done:--- ufo-rename.rkt ---" echo "" -gracket server-rename.rkt -echo "done:--- server-rename.rkt ---" echo "" -gracket world0-stops.rkt -echo "done:--- world0-stops.rkt ---" echo "" -gracket record.rkt -echo "done:--- record.rkt ---" echo "" -gracket record-stop-when.rkt -echo "done:--- record-stop-when.rkt ---" echo "" +run() { + exe="gracket" + if [ "x$1" = "x-t" ]; then exe="racket"; fi + "$exe" "$1" + echo "done:--- $1 ---" + echo "" +} -gracket stop-when-crash.rkt -echo "done:--- stop-when-crash.rkt ---" echo "" +run bad-draw.rkt +run -t batch-io.rkt +run clause-once.rkt +run full-scene-visible.rkt +run image-too-large.rkt +run image-equality-performance-htdp.rkt +run image-equality-performance.rkt +run mouse-evt.rkt +run on-tick-defined.rkt +run perform-robby.rkt +run profile-robby.rkt +run release.rkt +run stop.rkt +run test-image.rkt +run ufo-rename.rkt +run server-rename.rkt +run world0-stops.rkt +run record.rkt +run record-stop-when.rkt +run stop-when-crash.rkt diff --git a/collects/2htdp/uchat/xrun b/collects/2htdp/uchat/xrun index 27361d78a4..833373fb5e 100755 --- a/collects/2htdp/uchat/xrun +++ b/collects/2htdp/uchat/xrun @@ -1,4 +1,4 @@ -#!/bin/tcsh +#!/bin/sh -mred server.ss & -mred chatter.ss -e"(run* 'go)" & +gracket server.rkt & +gracket chatter.rkt -e"(run* 'go)" & diff --git a/collects/meta/drdr/copy.sh b/collects/meta/drdr/copy.sh index 71ba9b1858..c529dc4e92 100755 --- a/collects/meta/drdr/copy.sh +++ b/collects/meta/drdr/copy.sh @@ -1,2 +1,3 @@ -#!/bin/bash +#!/bin/sh + rsync -avz . drdr:/opt/svn/drdr/ --exclude=compiled --delete --exclude=data diff --git a/collects/meta/drdr/good-init.sh b/collects/meta/drdr/good-init.sh index 2cbc5c170c..547ee019fd 100755 --- a/collects/meta/drdr/good-init.sh +++ b/collects/meta/drdr/good-init.sh @@ -1,4 +1,5 @@ -#!/bin/bash +#!/bin/sh + export PLTSTDERR="info" PLTROOT="/opt/plt/plt" LOGS="/opt/plt/logs" @@ -19,7 +20,7 @@ kill_all() { run_loop () { # while true; do - if [[ "x$2" = "xyes" ]]; then + if [ "x$2" = "xyes" ]; then echo "clearing unattached shm regions" ipcs -ma | awk '0 == $6 {print $2}' | xargs -n 1 ipcrm -m fi @@ -31,7 +32,7 @@ run_loop () { # wait "$!" echo "$1: died" rm "$LOGS/$1.pid" - if [[ "x$2" = "xyes" ]]; then + if [ "x$2" = "xyes" ]; then echo "killing processes" kill_all fi From 533293c666e5be969afa5a4bb06bda1de7534331 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 14 Jul 2011 12:05:45 -0400 Subject: [PATCH 247/746] Added Guillaume's gmail address to mailmap (cherry picked from commit 6e72bf2dad8a15751dc1c296806fda29e3595a6a) --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 0ff7365061..324d04bec8 100644 --- a/.mailmap +++ b/.mailmap @@ -16,3 +16,4 @@ Robby Findler Jon Rafkind Stephen Chang Asumu Takikawa +Guillaume Marceau From a606c3a988c1840a90b102feec8524d9e8b46d07 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 14 Jul 2011 12:13:37 -0400 Subject: [PATCH 248/746] Shift typo. (cherry picked from commit 318c4fedfc6a654c37fad4e762c471d5f297cfc2) --- collects/2htdp/tests/xtest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/2htdp/tests/xtest b/collects/2htdp/tests/xtest index d2561c46db..25463109d2 100755 --- a/collects/2htdp/tests/xtest +++ b/collects/2htdp/tests/xtest @@ -2,7 +2,7 @@ run() { exe="gracket" - if [ "x$1" = "x-t" ]; then exe="racket"; fi + if [ "x$1" = "x-t" ]; then exe="racket"; shift; fi "$exe" "$1" echo "done:--- $1 ---" echo "" From 3a2e4969e994f6085d94456e9700bf841f9eeae1 Mon Sep 17 00:00:00 2001 From: Stephen Bloch Date: Thu, 14 Jul 2011 12:08:36 -0400 Subject: [PATCH 249/746] Corrected an error message that said it wanted a real, but actually expected an integer. (cherry picked from commit 83fd1e968d03a3483d0f6698bd387ff7d7d4a8a4) --- collects/2htdp/private/image-more.rkt | 8 ++++---- collects/2htdp/private/img-err.rkt | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/collects/2htdp/private/image-more.rkt b/collects/2htdp/private/image-more.rkt index 78bc2de002..a63a62928a 100644 --- a/collects/2htdp/private/image-more.rkt +++ b/collects/2htdp/private/image-more.rkt @@ -1372,14 +1372,14 @@ (define build-pen/make-pen (let ([orig-make-pen make-pen]) - (define/chk (make-pen color real-0-255 pen-style pen-cap pen-join) - (orig-make-pen color real-0-255 pen-style pen-cap pen-join)) + (define/chk (make-pen color int-0-255 pen-style pen-cap pen-join) + (orig-make-pen color int-0-255 pen-style pen-cap pen-join)) make-pen)) (define build-pen/pen (let ([orig-make-pen make-pen]) - (define/chk (pen color real-0-255 pen-style pen-cap pen-join) - (orig-make-pen color real-0-255 pen-style pen-cap pen-join)) + (define/chk (pen color int-0-255 pen-style pen-cap pen-join) + (orig-make-pen color int-0-255 pen-style pen-cap pen-join)) pen)) (define/chk freeze diff --git a/collects/2htdp/private/img-err.rkt b/collects/2htdp/private/img-err.rkt index 62f13518dc..e68488f185 100644 --- a/collects/2htdp/private/img-err.rkt +++ b/collects/2htdp/private/img-err.rkt @@ -253,9 +253,9 @@ (check-arg fn-name (and (integer? arg) (<= 0 arg 255)) 'integer\ between\ 0\ and\ 255 i arg) arg] - [(real-0-255) + [(int-0-255) (check-arg fn-name (and (integer? arg) (<= 0 arg 255)) - 'real\ number\ between\ 0\ and\ 255 i arg) + 'integer\ between\ 0\ and\ 255 i arg) arg] [(pen-style) From 14ed19da09193bb534baff6fa22d35ab7438d5b0 Mon Sep 17 00:00:00 2001 From: Stephen Bloch Date: Thu, 14 Jul 2011 16:39:25 -0400 Subject: [PATCH 250/746] Corrected signature of scene+line to match examples and actual behavior (sixth argument can be a pen or color, not just a color). (cherry picked from commit d510f6aecc9331a1700079703679ec6080e6727d) --- collects/teachpack/2htdp/scribblings/image.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/teachpack/2htdp/scribblings/image.scrbl b/collects/teachpack/2htdp/scribblings/image.scrbl index eb525bd515..a0372f14db 100644 --- a/collects/teachpack/2htdp/scribblings/image.scrbl +++ b/collects/teachpack/2htdp/scribblings/image.scrbl @@ -1016,7 +1016,7 @@ a black outline. @defproc[(scene+line [image image?] [x1 real?] [y1 real?] [x2 real?] [y2 real?] - [color image-color?]) + [pen-or-color (or/c pen? image-color?)]) image?]{ Adds a line to the image @racket[scene], starting from the point (@racket[x1],@racket[y1]) From 0b0de351fd5818839506336b5ccf5aaf59db17b9 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 14 Jul 2011 16:42:04 -0400 Subject: [PATCH 251/746] New `xrepl' collection. (cherry picked from commit c544ebfe6c9d0864047ad712ac6c3c97e023588f) --- collects/meta/dist-specs.rkt | 3 + collects/meta/props | 1 + collects/unstable/time.rkt | 49 ++ collects/xrepl/info.rkt | 3 + collects/xrepl/main.rkt | 13 + collects/xrepl/xrepl.rkt | 1245 ++++++++++++++++++++++++++++++++++ 6 files changed, 1314 insertions(+) create mode 100644 collects/unstable/time.rkt create mode 100644 collects/xrepl/info.rkt create mode 100644 collects/xrepl/main.rkt create mode 100644 collects/xrepl/xrepl.rkt diff --git a/collects/meta/dist-specs.rkt b/collects/meta/dist-specs.rkt index 13fa0f72f9..99187995f3 100644 --- a/collects/meta/dist-specs.rkt +++ b/collects/meta/dist-specs.rkt @@ -511,6 +511,9 @@ mz-extras :+= (collects: "rnrs/") ;; -------------------- readline mz-extras :+= (package: "readline/") +;; -------------------- readline +mz-extras :+= (package: "xrepl/") + ;; -------------------- wxme mz-extras :+= (collects: "wxme/") diff --git a/collects/meta/props b/collects/meta/props index e428687d58..914c0e3d85 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -2069,6 +2069,7 @@ path/s is either such a string or a list of them. "collects/xml/text-box-tool.rkt" drdr:command-line (gracket-text "-t" *) "collects/xml/text-snipclass.rkt" drdr:command-line (gracket-text "-t" *) "collects/xml/xml-snipclass.rkt" drdr:command-line (gracket-text "-t" *) +"collects/xrepl" responsible (eli) "doc/release-notes/COPYING-libscheme.txt" responsible (mflatt) "doc/release-notes/COPYING.txt" responsible (mflatt) "doc/release-notes/drracket" responsible (robby) diff --git a/collects/unstable/time.rkt b/collects/unstable/time.rkt new file mode 100644 index 0000000000..5350346c6f --- /dev/null +++ b/collects/unstable/time.rkt @@ -0,0 +1,49 @@ +#lang racket/base + +;; An improved `time' variant: better output, and repetitions with averages +(provide time) + +(require racket/list) + +(define (time* thunk times) + (define throw + (if (<= times 0) + (error 'time "bad count: ~e" times) + (floor (* times 2/7)))) + (define results #f) + (define timings '()) + (define (run n) + (when (<= n times) + (when (> times 1) (printf "; run #~a..." n) (flush-output)) + (let ([r (call-with-values (lambda () (time-apply thunk '())) list)]) + (set! results (car r)) + (set! timings (cons (cdr r) timings)) + (when (> times 1) + (printf " ->") + (if (null? results) + (printf " (0 values returned)") + (begin (printf " ~.s" (car results)) + (for ([r (in-list (cdr results))]) (printf ", ~s" r)) + (newline)))) + (run (add1 n))))) + (collect-garbage) + (collect-garbage) + (collect-garbage) + (run 1) + (set! timings (sort timings < #:key car)) ; sort by cpu-time + (set! timings (drop timings throw)) ; throw extreme bests + (set! timings (take timings (- (length timings) throw))) ; and worsts + (set! timings (let ([n (length timings)]) ; average + (map (lambda (x) (round (/ x n))) (apply map + timings)))) + (let-values ([(cpu real gc) (apply values timings)]) + (when (> times 1) + (printf "; ~a runs, ~a best/worst removed, ~a left for average:\n" + times throw (- times throw throw))) + (printf "; cpu time: ~sms = ~sms + ~sms gc; real time: ~sms\n" + cpu (- cpu gc) gc real)) + (apply values results)) + +(define-syntax time + (syntax-rules () + [(_ n expr0 expr ...) (time* (lambda () expr0 expr ...) n)] + [(_ expr0 expr ...) (time* (lambda () expr0 expr ...) 1)])) diff --git a/collects/xrepl/info.rkt b/collects/xrepl/info.rkt new file mode 100644 index 0000000000..dd70b324f1 --- /dev/null +++ b/collects/xrepl/info.rkt @@ -0,0 +1,3 @@ +#lang setup/infotab + +(define name "eXtended REPL") diff --git a/collects/xrepl/main.rkt b/collects/xrepl/main.rkt new file mode 100644 index 0000000000..d4a285c32b --- /dev/null +++ b/collects/xrepl/main.rkt @@ -0,0 +1,13 @@ +#lang racket/base + +;; This file is intended to be loaded from your init file (evaluatue +;; (find-system-path 'init-file) to see where that is on your OS.) + +(require "xrepl.rkt") + +;; may want to disable inlining to allow redefinitions +;; (compile-enforce-module-constants #f) + +;; create the command repl reader, and value-saving evaluator +(current-prompt-read (make-command-reader)) +(current-eval (make-command-evaluator (current-eval))) diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt new file mode 100644 index 0000000000..a53c13899b --- /dev/null +++ b/collects/xrepl/xrepl.rkt @@ -0,0 +1,1245 @@ +#lang racket/base + +;; ---------------------------------------------------------------------------- +;; customization + +(define toplevel-prefix (make-parameter "-")) ; when not in a module +(define saved-values-number (make-parameter 5)) +(define saved-values-char (make-parameter #\^)) +(define wrap-column (make-parameter 79)) +;; TODO: when there's a few more of these, make them come from the prefs + +;; ---------------------------------------------------------------------------- + +(require racket/list racket/match) + +;; ---------------------------------------------------------------------------- +;; utilities + +;; autoloads: avoid loading a ton of stuff to minimize startup penalty +(define autoloaded-specs (make-hasheq)) +(define (autoloaded? sym) (hash-ref autoloaded-specs sym #f)) +(define-syntax-rule (defautoload libspec id ...) + (begin (define (id . args) + (set! id (dynamic-require 'libspec 'id)) + (hash-set! autoloaded-specs 'libspec #t) + (hash-set! autoloaded-specs 'id #t) + (apply id args)) + ...)) + +(defautoload racket/system system system*) +(defautoload racket/file file->string) +(defautoload setup/path-to-relative path->relative-string/setup) +(defautoload syntax/modcode get-module-code) +(defautoload racket/path find-relative-path) + +;; similar, but just for identifiers +(define-namespace-anchor anchor) +(define (here-namespace) (namespace-anchor->namespace anchor)) +(define (make-lazy-identifier sym from) + (define id #f) + (λ () (or id (parameterize ([current-namespace (here-namespace)]) + (eval (namespace-syntax-introduce + (datum->syntax #f #`(require #,from)))) + (set! id (namespace-symbol->identifier sym)) + id)))) + +;; makes it easy to use meta-tools without user-namespace contamination +(define (eval-sexpr-for-user form) + (eval (namespace-syntax-introduce (datum->syntax #f form)))) + +(define (modspec->path modspec) ; returns a symbol for 'foo specs + (resolved-module-path-name ((current-module-name-resolver) modspec #f #f))) +(define (mpi->name mpi) + (resolved-module-path-name (module-path-index-resolve mpi))) +(define (->relname x) + (if (path-string? x) (path->relative-string/setup x) x)) + +(define (here-source) ; returns a path, a symbol, or #f (= not in a module) + (let* ([x (datum->syntax #'here '(#%variable-reference))] + [x (eval (namespace-syntax-introduce x))] + [x (variable-reference->module-source x)]) + x)) + +(define (phase->name phase [fmt #f]) + (define s + (case phase + [(0) #f] [(#f) "for-label"] [(1) "for-syntax"] [(-1) "for-template"] + [else (format "for-meta:~a" phase)])) + (cond [(not fmt) s] [s (format fmt s)] [else ""])) + +;; true if (quote sym) is a known module name +(define (module-name? sym) + (and (symbol? sym) + (with-handlers ([exn? (λ (_) #f)]) (module->imports `',sym) #t))) + +;; support visual column-aware output +;; right after an input expression is entered the terminal won't show the +;; newline, so as far as column counting goes it's still after the prompt which +;; leads to bad output in practice. (at least in the common case where IO +;; share the same terminal.) This will be redundant with the already-added +;; `port-set-next-location!'. +(define last-output-port #f) +(define last-output-line #f) +(define last-output-visual-col #f) +(define (maybe-new-output-port) + (unless (eq? last-output-port (current-output-port)) + (set! last-output-port (current-output-port)) + (flush-output last-output-port) + (port-count-lines! last-output-port) + (let-values ([(line col pos) (port-next-location last-output-port)]) + (set! last-output-line line) + (set! last-output-visual-col col)))) +(define (fresh-line) + (maybe-new-output-port) + (flush-output last-output-port) + (let-values ([(line col pos) (port-next-location last-output-port)]) + (unless (eq? col (if (eq? line last-output-line) last-output-visual-col 0)) + (newline)))) +(define (prompt-shown) + (maybe-new-output-port) + ;; if there was a way to change the location of stdout we'd set the column to + ;; 0 here... + (let-values ([(line col pos) (port-next-location last-output-port)]) + (set! last-output-line line) + (set! last-output-visual-col col))) + +;; wrapped `printf' (cheap but effective), aware of the visual col +(define wrap-prefix (make-parameter "")) +(define (wprintf fmt . args) + (let ([o (current-output-port)] + [wcol (wrap-column)] + [pfx (wrap-prefix)] + [strs (regexp-split #rx" +" (apply format fmt args))]) + (write-string (car strs) o) + (for ([str (in-list (cdr strs))]) + (define-values [line col pos] (port-next-location o)) + (define vcol + (if (eq? line last-output-line) (- col last-output-visual-col) col)) + (if ((+ vcol (string-length str)) . >= . wcol) + (begin (newline o) (write-string pfx o)) + (write-string " " o)) + (write-string str o)))) + +;; ---------------------------------------------------------------------------- +;; toplevel "," commands management + +(struct command (names argline blurb desc handler)) +(define commands (make-hasheq)) +(define commands-list '()) ; for help displays, in definition order +(define current-command (make-parameter #f)) +(define (register-command! names blurb argline desc handler) + (let* ([names (if (list? names) names (list names))] + [cmd (command names blurb argline desc handler)]) + (for ([n (in-list names)]) + (if (hash-ref commands n #f) + (error 'defcommand "duplicate command name: ~s" n) + (hash-set! commands n cmd))) + (set! commands-list (cons cmd commands-list)))) +(define-syntax-rule (defcommand cmd+aliases argline blurb [desc ...] + body0 body ...) + (register-command! `cmd+aliases `argline `blurb `(desc ...) + (λ () body0 body ...))) + +(define (cmderror fmt #:default-who [dwho #f] . args) + (let ([cmd (current-command)]) + (raise-user-error (or (and cmd (string->symbol (format ",~a" cmd))) + dwho '???) + (apply format fmt args)))) + +;; returns first peeked non-space/tab char (#\return is considered space too) +(define string->list* + (let ([t (make-weak-hasheq)]) ; good for string literals + (λ (s) (hash-ref! t s (λ () (string->list s)))))) +(define (skip-spaces/peek [skip " \t\r"]) + (let ([skip (string->list* skip)]) + (let loop () + (let ([ch (peek-char)]) + (if (memq ch skip) (begin (read-char) (loop)) ch))))) + +(define (getarg kind [flag 'req]) + (define (argerror fmt . args) + (apply cmderror #:default-who 'getarg fmt args)) + (define (missing) (argerror "missing ~a argument" kind)) + (define (get read) + (let loop ([flag flag]) + (case flag + [(req) (let ([x (if (eq? #\newline (skip-spaces/peek)) eof (read))]) + (if (eof-object? x) (missing) x))] + [(opt) (and (not (eq? #\newline (skip-spaces/peek))) (loop 'req))] + [(list) (let ([x (loop 'opt)]) + (if x (cons x (loop 'list)) '()))] + [(list+) (cons (loop 'req) (loop 'list))] + [else (error 'getarg "unknown flag: ~e" flag)]))) + (define (read-string-arg) + (define ch (skip-spaces/peek " \t\r\n")) + (let* ([i (current-input-port)] + [m (if (eq? ch #\") + (let ([m (regexp-match #px#"((?:\\\\.|[^\"\\\\]+)+)\"" i)]) + (and m (regexp-replace* #rx#"\\\\(.)" (cadr m) #"\\1"))) + (cond [(regexp-match #px#"\\S+" i) => car] [else #f]))]) + (if m (bytes->string/locale m) eof))) + (define (read-line-arg) + (regexp-replace* #px"^\\s+|\\s+$" (read-line) "")) + (define (process-modspec spec) + ;; convenience: symbolic modspecs that name a file turn to a `file' spec, + ;; and those that name a known module turn to a (quote sym) spec + (define dtm (if (syntax? spec) (syntax->datum spec) spec)) + (if (not (symbol? dtm)) + spec + (let* (;; try a file + [f (expand-user-path (symbol->string dtm))] + [f (and (file-exists? f) (path->string f))] + [f (and f (if (absolute-path? f) `(file ,f) f))] + ;; try a quoted one if the above failed + [m (or f (and (module-name? dtm) `',dtm))] + [m (and m (if (syntax? spec) (datum->syntax spec m spec) m))]) + (or m spec)))) + (define (translate arg convert) + (and arg (if (memq flag '(list list+)) (map convert arg) (convert arg)))) + (let loop ([kind kind]) + (case kind + [(line) (get read-line-arg)] + [(string) (get read-string-arg)] + [(path) (translate (loop 'string) expand-user-path)] + [(path*) (if (eq? flag 'list) + (let ([args (getarg 'path 'list)]) + (if (pair? args) + args + (let ([x (here-source)]) (if (path? x) (list x) '())))) + (error 'getarg "'path* must always be used with 'list"))] + [(sexpr) (get read)] + [(syntax) (translate (get read-syntax) namespace-syntax-introduce)] + [(modspec) (translate (loop 'syntax) process-modspec)] + [else (error 'getarg "unknown arg kind: ~e" kind)]))) + +(define (run-command cmd) + (parameterize ([current-command cmd]) + (with-handlers ([void (λ (e) + (if (exn? e) + (eprintf "~a\n" (exn-message e)) + (eprintf "~s\n" e)))]) + ((command-handler (or (hash-ref commands cmd #f) + (error "Unknown command:" cmd))))))) + +(defcommand (help h ?) "[]" + "display available commands" + ["Lists known commands and their help; use with a command name to get" + "additional information for that command."] + (define arg (match (getarg 'sexpr 'opt) [(list 'unquote x) x] [x x])) + (define cmd + (and arg (hash-ref commands arg + (λ () (printf "*** Unknown command: `~s'\n" arg) #f)))) + (define (show-cmd cmd indent) + (define names (command-names cmd)) + (printf "~a~s" indent (car names)) + (when (pair? (cdr names)) (printf " ~s" (cdr names))) + (printf ": ~a\n" (command-blurb cmd))) + (if cmd + (begin (show-cmd cmd "; ") + (printf "; usage: ,~a" arg) + (let ([a (command-argline cmd)]) (when a (printf " ~a" a))) + (printf "\n") + (for ([d (in-list (command-desc cmd))]) + (printf "; ~a\n" d))) + (begin (printf "; Available commands:\n") + (for-each (λ (c) (show-cmd c "; ")) (reverse commands-list))))) + +;; ---------------------------------------------------------------------------- +;; generic commands + +(defcommand (exit quit ex) "[]" + "exit racket" + ["Optional argument specifies exit code."] + (cond [(getarg 'sexpr 'opt) => exit] [else (exit)])) + +(define last-2dirs + (make-parameter (let ([d (current-directory)]) (cons d d)))) +(define (report-directory-change [mode #f]) + (define curdir (current-directory)) + (define (report) ; remove last "/" and say where we are + (define-values [base name dir?] (split-path curdir)) + (printf "; now in ~a\n" (if base (build-path base name) curdir))) + (cond [(not (equal? (car (last-2dirs)) curdir)) + (last-2dirs (cons curdir (car (last-2dirs)))) + (report)] + [else (case mode + [(pwd) (report)] + [(cd) (printf "; still in the same directory\n")])])) + +(defcommand cd "[]" + "change the current directory" + ["Sets `current-directory'; expands user paths. With no arguments, goes" + "to your home directory. An argument of `-' indicates the previous" + "directory."] + (let* ([arg (or (getarg 'path 'opt) (find-system-path 'home-dir))] + [arg (if (equal? arg (string->path "-")) (cdr (last-2dirs)) arg)]) + (if (directory-exists? arg) + (begin (current-directory arg) (report-directory-change 'cd)) + (eprintf "cd: no such directory: ~a\n" arg)))) + +(defcommand pwd #f + "read the current directory" + ["Displays the value of `current-directory'."] + (report-directory-change 'pwd)) + +(defcommand (shell sh ls cp mv rm md rd git svn) "" + "run a shell command" + ["`sh' runs a shell command (via `system'), the aliases run a few useful" + "unix commands. (Note: `ls' has some default arguments set.)"] + (let* ([arg (getarg 'line)] + [arg (if (equal? "" arg) #f arg)] + [cmd (current-command)]) + (case cmd + [(ls) (set! cmd "ls -F")] + [(shell) (set! cmd 'sh)]) + (let ([cmd (cond [(eq? 'sh cmd) #f] + [(symbol? cmd) (symbol->string cmd)] + [else cmd])]) + (unless (system (cond [(and (not cmd) (not arg)) (getenv "SHELL")] + [(not cmd) arg] + [(not arg) cmd] + [else (string-append cmd " " arg)])) + (eprintf "(exit with an error status)\n"))))) + +(defcommand (edit e) " ..." + "edit files in your $EDITOR" + ["Runs your $EDITOR with the specified file/s. If no files are given, and" + "the REPL is currently inside a module, the file for that module is used." + "If $EDITOR is not set, the ,drracket will be used instead."] + (define env (let ([e (getenv "EDITOR")]) (and (not (equal? "" e)) e))) + (define exe (and env (find-executable-path env))) + (cond [(not env) + (printf "~a, using the ,drracket command.\n" + (if env + (string-append "$EDITOR ("env") not found in your path") + "no $EDITOR variable")) + (run-command 'drracket)] + [(not (apply system* exe (getarg 'path* 'list))) + (eprintf "(exit with an error status)\n")] + [else (void)])) + +(define ->running-dr #f) +(define (->dr . xs) (unless ->running-dr (start-dr)) (->running-dr xs)) +(define (start-dr) + (define c (make-custodian)) + (define ns ((dynamic-require 'racket/gui 'make-gui-namespace))) + (parameterize ([current-custodian c] + [current-namespace ns] + [exit-handler (λ (x) + (eprintf "DrRacket shutdown.\n") + (set! ->running-dr #f) + (custodian-shutdown-all c))]) + ;; construct a kind of a fake sandbox to run drracket in + (define es + (eval '(begin (require racket/class racket/gui framework racket/file) + (define es (make-eventspace)) + es))) + (define (E expr) + (parameterize ([current-custodian c] + [current-namespace ns] + [(eval 'current-eventspace ns) es]) + (eval expr ns))) + (E '(begin + (define c (current-custodian)) + (define-syntax-rule (Q expr ...) + (parameterize ([current-eventspace es]) + (queue-callback + (λ () (parameterize ([current-custodian c]) expr ...))))) + ;; problem: right after we read commands, readline will save a new + ;; history in the prefs file which frequently collides with drr; so + ;; make it use a writeback thing, with silent failures. (actually, + ;; this is more likely a result of previously starting drr wrongly, + ;; but keep this anyway.) + (let ([t (make-hasheq)] [dirty '()]) + (preferences:low-level-get-preference + (λ (sym [dflt (λ () #f)]) + (hash-ref t sym + (λ () (let ([r (get-preference sym dflt)]) + (hash-set! t sym r) + r))))) + (preferences:low-level-put-preferences + (λ (prefs vals) + (Q (set! dirty (append prefs dirty)) + (for ([pref (in-list prefs)] [val (in-list vals)]) + (hash-set! t pref val))))) + (define (flush-prefs) + (set! dirty (remove-duplicates dirty)) + (with-handlers ([void void]) + (put-preferences dirty (map (λ (p) (hash-ref t p)) dirty)) + (set! dirty '()))) + (exit:insert-on-callback flush-prefs) + (define (write-loop) + (sleep (random 4)) + (when (pair? dirty) (Q (flush-prefs))) + (write-loop)) + (define th (thread write-loop)) + (exit:insert-on-callback (λ () (Q (kill-thread th))))) + ;; start it + (Q (dynamic-require 'drracket #f)) + ;; hide the first untitled window, so drr runs in "server mode" + (Q (dynamic-require 'drracket/tool-lib #f)) + (define top-window + (let ([ch (make-channel)]) + (Q (let ([r (get-top-level-windows)]) + (channel-put ch (and (pair? r) (car r))))) + (channel-get ch))) + (Q (when top-window (send top-window show #f)) + ;; and avoid trying to open new windows in there + (send (group:get-the-frame-group) clear)) + ;; avoid being able to quit so the server stays running, + ;; also hack: divert quitting into closing all group frames + (define should-exit? #f) + (exit:insert-can?-callback + (λ () (or should-exit? + (let ([g (group:get-the-frame-group)]) + (when (send g can-close-all?) (send g on-close-all)) + #f)))) + (require drracket/tool-lib))) ; used as usual below + (define (new) + (E '(Q (drracket:unit:open-drscheme-window #f)))) + (define open + (case-lambda + [() (E '(Q (handler:open-file)))] + [paths + (let ([paths (map path->string paths)]) + (E `(Q (let ([f (drracket:unit:open-drscheme-window ,(car paths))]) + (send f show #t) + ,@(for/list ([p (in-list (cdr paths))]) + `(begin (send f open-in-new-tab ,p) + (send f show #t)))))))])) + (define (quit) + (E `(Q (set! should-exit? #t) (exit:exit)))) + (define (loop) + (define m (thread-receive)) + (if (pair? m) + (let ([proc (case (car m) [(new) new] [(open) open] [(quit) quit] + [else (cmderror "unknown flag: -~a" (car m))])]) + (if (procedure-arity-includes? proc (length (cdr m))) + (apply proc (cdr m)) + (cmderror "bad number of arguments for the -~a flag" (car m)))) + (error '->dr "internal error")) + (loop)) + (define th (thread loop)) + (set! ->running-dr (λ (xs) (thread-send th xs))))) +(defcommand (drracket dr drr) "[-flag] ..." + "edit files in DrRacket" + ["Runs DrRacket with the specified file/s. If no files are given, and" + "the REPL is currently inside a module, the file for that module is used." + "DrRacket is launched directly, without starting a new subprocess, and it" + "is kept running in a hidden window so further invocations are immediate." + "In addition to file arguments, the arguments can have a flag that" + "specifies one of a few operations for the running DrRacket:" + "* -new: opens a new editing window. This is the default when no files are" + " given and the REPL is not inside a module," + "* -open: opens the specified file/s (or the current module's file). This" + " is the default when files are given or when inside a module." + "* -quit: exits the running instance. Quitting the application as usual" + " will only close the visible window, but it will still run in a hidden" + " window. This command should not be needed under normal circumstances."] + (let ([args (getarg 'path* 'list)]) + (if (null? args) + (->dr 'new) + (let* ([cmd (let ([s (path->string (car args))]) + (and (regexp-match? #rx"^-" s) + (string->symbol (substring s 1))))] + [args (if cmd (cdr args) args)]) + (apply ->dr (or cmd 'open) args))))) + +;; ---------------------------------------------------------------------------- +;; binding related commands + +(defcommand (apropos ap) " ..." + "look for a binding" + ["Additional string arguments restrict matches shown. The search specs can" + "have symbols (which specify what to look for in bound names), and regexps" + "(for more complicated matches)."] + (let* ([look (map (λ (s) (cond [(symbol? s) + (regexp (regexp-quote (symbol->string s)))] + [(regexp? s) s] + [else (cmderror "bad search spec: ~e" s)])) + (getarg 'sexpr 'list))] + [look (and (pair? look) + (λ (str) (andmap (λ (rx) (regexp-match? rx str)) look)))] + [syms (map (λ (sym) (cons sym (symbol->string sym))) + (namespace-mapped-symbols))] + [syms (if look (filter (λ (s) (look (cdr s))) syms) syms)] + [syms (sort syms string] ..." + "describe a (bound) identifier" + ["For a bound identifier, describe where is it coming from; for a known" + "module, describe its imports and exports. You can use this command with" + "several identifiers. An optional numeric argument specifies phase for" + "identifier lookup."] + (define-values [try-mods? level ids/mods] + (let ([xs (getarg 'syntax 'list)]) + (if (and (pair? xs) (number? (syntax-e (car xs)))) + (values #f (syntax-e (car xs)) (cdr xs)) + (values #t 0 xs)))) + (for ([id/mod (in-list ids/mods)]) + (define dtm (syntax->datum id/mod)) + (define mod + (and try-mods? + (match dtm + [(list 'quote (and sym (? module-name?))) sym] + [(? module-name?) dtm] + [_ (let ([x (with-handlers ([exn:fail? (λ (_) #f)]) + (modspec->path dtm))]) + (cond [(or (not x) (path? x)) x] + [(symbol? x) (and (module-name? x) `',x)] + [else (error 'describe "internal error: ~s" x)]))]))) + (define bind + (cond [(identifier? id/mod) (identifier-binding id/mod level)] + [mod #f] + [else (cmderror "not an identifier or a known module: ~s" dtm)])) + (define bind? (or bind (not mod))) + (when bind? (describe-binding dtm bind level)) + (when mod (describe-module dtm mod bind?)))) +(define (describe-binding sym b level) + (define at-phase (phase->name level " (~a)")) + (cond + [(not b) + (printf "; `~s' is a toplevel (or unbound) identifier~a\n" sym at-phase)] + [(eq? b 'lexical) + (printf "; `~s' is a lexical identifier~a\n" sym at-phase)] + [(or (not (list? b)) (not (= 7 (length b)))) + (cmderror "*** internal error, racket changed ***")] + [else + (define-values [src-mod src-id nominal-src-mod nominal-src-id + src-phase import-phase nominal-export-phase] + (apply values b)) + (set! src-mod (->relname (mpi->name src-mod))) + (set! nominal-src-mod (->relname (mpi->name nominal-src-mod))) + (printf "; `~s' is a bound identifier~a,\n" sym at-phase) + (printf "; defined~a in ~a~a\n" (phase->name src-phase "-~a") src-mod + (if (not (eq? sym src-id)) (format " as `~s'" src-id) "")) + (printf "; required~a ~a\n" (phase->name import-phase "-~a") + (if (equal? src-mod nominal-src-mod) + "directly" + (format "through \"~a\"~a" + nominal-src-mod + (if (not (eq? sym nominal-src-id)) + (format " where it is defined as `~s'" nominal-src-id) + "")))) + (printf "~a" (phase->name nominal-export-phase "; (exported-~a)\n"))])) +(define (describe-module sexpr mod-path/sym also?) + (define get + (if (symbol? mod-path/sym) + (let ([spec `',mod-path/sym]) + (λ (imp?) ((if imp? module->imports module->exports) spec))) + (let ([code (get-module-code mod-path/sym)]) + (λ (imp?) + ((if imp? module-compiled-imports module-compiled-exports) code))))) + (define (phase p1 0) (> p2 0)) (< p1 p2)] + [(and (< p1 0) (< p2 0)) (> p1 p2)] + [else (> p1 0)])) + (define (modnamestring x) (symbol->string y))] + [(and (symbol? x) (string? y)) #t] + [(and (string? x) (symbol? y)) #f] + [else (error 'describe-module "internal error: ~s, ~s" x y)])) + (define imports + (filter-map + (λ (x) + (and (pair? (cdr x)) + (cons (car x) (sort (map (λ (m) (->relname (mpi->name m))) (cdr x)) + modnamerelname mod-path/sym)]) + (printf "; ~a~a\n" + (if (symbol? relname) "defined directly as '" "located at ") + relname)) + (if (null? imports) + (printf "; no imports.\n") + (parameterize ([wrap-prefix "; "]) + (for ([imps (in-list imports)]) + (let ([phase (car imps)] [imps (cdr imps)]) + (wprintf "; imports~a: ~a" (phase->name phase "-~a") (car imps)) + (for ([imp (in-list (cdr imps))]) (wprintf ", ~a" imp)) + (wprintf ".\n"))))) + (define (show-exports exports kind) + (parameterize ([wrap-prefix "; "]) + (for ([exps (in-list exports)]) + (let ([phase (car exps)] [exps (cdr exps)]) + (wprintf "; direct ~a exports~a: ~a" + kind (phase->name phase "-~a") (car exps)) + (for ([exp (in-list (cdr exps))]) (wprintf ", ~a" exp)) + (wprintf ".\n"))))) + (if (and (null? val-exports) (null? stx-exports)) + (printf "; no direct exports.\n") + (begin (show-exports val-exports "value") + (show-exports stx-exports "syntax")))) + +(define help-id (make-lazy-identifier 'help 'racket/help)) +(defcommand doc " ..." + "browse the racket documentation" + ["Uses Racket's `help' to browse the documentation. (Note that this can be" + "used even in languages that don't have the `help' binding.)"] + (eval-sexpr-for-user `(,(help-id) ,@(getarg 'syntax 'list)))) + +;; ---------------------------------------------------------------------------- +;; require/load commands + +(defcommand (require req r) " ...+" + "require a module" + ["The arguments are usually passed to `require', unless an argument" + "specifies an existing filename -- in that case, it's like using a" + "\"string\" or a (file \"...\") in `require'. (Note: this does not" + "work in subforms.)"] + (more-inputs #`(require #,@(getarg 'modspec 'list+)))) ; use *our* `require' + +(define rr-modules (make-hash)) ; hash to remember reloadable modules + +(defcommand (require-reloadable reqr rr) " ...+" + "require a module, make it reloadable" + ["Same as ,require but the module is required in a way that makes it" + "possible to reload later. If it was already loaded then it is reloaded." + "Note that this is done by setting `compile-enforce-module-constants' to" + "#f, which prohibits some optimizations."] + (parameterize ([compile-enforce-module-constants + (compile-enforce-module-constants)]) + (compile-enforce-module-constants #f) + (for ([spec (in-list (getarg 'modspec 'list+))]) + (define datum (syntax->datum spec)) + (define resolved ((current-module-name-resolver) datum #f #f #f)) + (define path (resolved-module-path-name resolved)) + (if (hash-ref rr-modules resolved #f) + ;; reload + (begin (printf "; reloading ~a\n" path) + (parameterize ([current-module-declare-name resolved]) + (load/use-compiled path))) + ;; require + (begin (hash-set! rr-modules resolved #t) + (printf "; requiring ~a\n" path) + ;; (namespace-require spec) + (eval #`(require #,spec))))))) + +(define enter!-id (make-lazy-identifier 'enter! 'racket/enter)) + +(defcommand (enter en) "[] [noisy?]" + "require a module and go into its namespace" + ["Uses `enter!' to go into the module's namespace; the module name is" + "optional, without it you go back to the toplevel. A module name can" + "specify an existing file as with the ,require command. (Note that this" + "can be used even in languages that don't have the `enter!' binding.)"] + (eval-sexpr-for-user `(,(enter!-id) ,(getarg 'modspec)))) + +(defcommand (toplevel top) #f + "go back to the toplevel" + ["Go back to the toplevel, same as ,enter with no arguments."] + (eval-sexpr-for-user `(,(enter!-id) #f))) + +(defcommand (load ld) " ..." + "load a file" + ["Uses `load' to load the specified file(s)"] + (more-inputs* (map (λ (name) #`(load #,name)) (getarg 'path 'list)))) + +;; ---------------------------------------------------------------------------- +;; debugging commands + +;; not useful: catches only escape continuations +;; (define last-break-exn (make-parameter #f)) +;; (defcommand (continue cont) #f +;; "continue from a break" +;; ["Continue running from the last break."] +;; (if (last-break-exn) +;; ((exn:break-continuation (last-break-exn))) +;; (cmderror 'continue "no break exception to continue from"))) + +(define time-id + (make-lazy-identifier 'time* '(only-in unstable/time [time time*]))) +(defcommand time "[] ..." + "time an expression" + ["Times execution of an expression, similar to `time' but prints a" + "little easier to read information. You can provide an initial number" + "that specifies how many times to run the expression -- in this case," + "the expression will be executed that many times, extreme results are" + "be removed (top and bottom 2/7ths), and the remaining results will" + "be averaged. Two garbage collections are triggered before each run;" + "the resulting value(s) are from the last run."] + (more-inputs #`(#,(time-id) #,@(getarg 'syntax 'list)))) + +(define trace-id (make-lazy-identifier 'trace 'racket/trace)) +(defcommand (trace tr) " ..." + "trace a function" + ["Traces a function (or functions), using the `racket/trace' library."] + (eval-sexpr-for-user `(,(trace-id) ,@(getarg 'syntax 'list)))) + +(define untrace-id (make-lazy-identifier 'untrace 'racket/trace)) +(defcommand (untrace untr) " ..." + "untrace a function" + ["Untraces functions that were traced with ,trace."] + (eval-sexpr-for-user `(,(untrace-id) ,@(getarg 'syntax 'list)))) + +(defautoload errortrace + profiling-enabled instrumenting-enabled clear-profile-results + output-profile-results execute-counts-enabled annotate-executed-file) + +(defcommand (errortrace errt inst) "[]" + "errortrace instrumentation control" + ["An argument is used to perform a specific operation:" + " + : turn errortrace instrumentation on (effective only for code that is" + " evaluated from now on)" + " - : turn it off (also only for future evaluations)" + " ? : show status without changing it" + "With no arguments, toggles instrumentation."] + (case (getarg 'sexpr 'opt) + [(#f) (if (autoloaded? 'errortrace) + (instrumenting-enabled (not (instrumenting-enabled))) + (instrumenting-enabled #t))] + [(-) (when (autoloaded? 'errortrace) (instrumenting-enabled #f))] + [(+) (instrumenting-enabled #t)] + [(?) (void)] + [else (cmderror "unknown subcommand")]) + (if (autoloaded? 'errortrace) + (printf "; errortrace instrumentation is ~a\n" + (if (instrumenting-enabled) "on" "off")) + (printf "; errortrace not loaded\n"))) + +(define profile-id + (make-lazy-identifier 'profile 'profile)) +(define (statistical-profiler) + (more-inputs #`(#,(profile-id) #,(getarg 'syntax)))) +(define (errortrace-profiler) + (instrumenting-enabled #t) + (define flags (regexp-replace* #rx"[ \t]+" (getarg 'line) "")) + (for ([cmd (in-string (if (equal? "" flags) + (if (profiling-enabled) "*!" "+") + flags))]) + (case cmd + [(#\+) (profiling-enabled #t) (printf "; profiling is on\n")] + [(#\-) (profiling-enabled #f) (printf "; profiling is off\n")] + [(#\*) (output-profile-results #f #t)] + [(#\#) (output-profile-results #f #f)] + [(#\!) (clear-profile-results) (printf "; profiling data cleared\n")] + [else (cmderror "unknown subcommand")]))) +(defcommand (profile prof) "[ | ...]" + "profiler control" + ["Runs either the exact errortrace-based profiler, or the statistical one." + "* If a parenthesized expression is given, run the statistical profiler" + " while running it. This profiler requires no special setup and adds" + " almost no overhead, it samples stack traces as execution goes on." + "* Otherwise the errortrace profiler is used. This profiler produces" + " precise results, but like other errortrace uses, it must be enabled" + " before loading the code and it adds noticeable overhead. In this case," + " an argument is used to determine a specific operation:" + " + : turn the profiler on (effective only for code that is evaluated" + " from now on)" + " - : turn the profiler off (also only for future evaluations)" + " * : show profiling results by time" + " # : show profiling results by counts" + " ! : clear profiling results" + " Multiple commands can be combined, for example \",prof *!-\" will show" + " profiler results, clear them, and turn it off." + "* With no arguments, turns the errortrace profiler on if it's off, and if" + " it's on it shows the collected results and clears them." + "Note: using no arguments or *any* of the flags turns errortrace" + " instrumentation on, even a \",prof -\". Use the ,errortrace command if" + " you want to turn instrumentation off."] + (if (memq (skip-spaces/peek) '(#\( #\[ #\{)) + (statistical-profiler) + (errortrace-profiler))) + +(defcommand execution-counts " ..." + "execution counts" + ["Enable errortrace instrumentation for coverage, require the file(s)," + "display the results, disables coverage, and disables instrumentation if" + "it wasn't previously turned on."] + (let ([files (getarg 'path 'list)] + [inst? (and (autoloaded? 'errortrace) (instrumenting-enabled))]) + (more-inputs + (λ () + (instrumenting-enabled #t) + (execute-counts-enabled #t)) + #`(require #,@(map (λ (file) `(file ,(path->string file))) files)) + (λ () + (for ([file (in-list files)]) + (annotate-executed-file file " 123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) + (λ () + (execute-counts-enabled #f) + (unless inst? (instrumenting-enabled #f)))))) + +(defautoload racket/sandbox + make-module-evaluator kill-evaluator call-with-trusted-sandbox-configuration + sandbox-coverage-enabled get-uncovered-expressions) + +(defcommand (coverage cover) "" + "coverage information via a sandbox" + ["Runs the given file in a (trusted) sandbox, and annotates it with" + "uncovered expression information."] + (let ([file (getarg 'path)]) + (sandbox-coverage-enabled) ; autoload it + (parameterize ([sandbox-coverage-enabled #t]) + (define e + (call-with-trusted-sandbox-configuration + (λ () (make-module-evaluator file)))) + (define uncovered + (map (λ (x) (let ([p (sub1 (syntax-position x))]) + (cons p (+ p (syntax-span x))))) + (get-uncovered-expressions e #t))) + (kill-evaluator e) + (call-with-input-file file + (λ (inp) + ;; this is a naive and inefficient solution, could be made efficient + ;; using `mzlib/integer-set' + (let loop () + (let* ([start (file-position inp)] + [line (read-line inp)] + [len (and (string? line) (string-length line))] + [end (and len (+ len start))] + [indent (and len (regexp-match-positions #px"\\S" line))] + [indent (and indent (caar indent))]) + (when len + (displayln line) + (when indent + (string-fill! line #\space) + (for ([u (in-list uncovered)]) + (when (and ((car u) . < . end) + ((cdr u) . > . indent)) + (for ([i (in-range (max (- (car u) start) indent) + (min (- (cdr u) start) len))]) + (string-set! line i #\^)))) + (displayln (regexp-replace #rx" +$" line ""))) + (loop))))))))) + +;; ---------------------------------------------------------------------------- +;; namespace switching + +(define default-namespace-name '*) +(define current-namespace-name (make-parameter default-namespace-name)) +(define namespaces + (let* ([r (namespace-symbol->identifier '#%top-interaction)] + [r (identifier-binding r)] + [r (and r (mpi->name (caddr r)))] + [t (make-hasheq)]) + (hash-set! t (current-namespace-name) (cons (current-namespace) r)) + t)) +(defcommand (switch-namespace switch) "[] [! []]" + "switch to a different repl namespace" + ["Switch to the namespace, creating it if needed. The of a" + "namespace is a symbol or an integer where a `*' indicates the initial one;" + "it is only used to identify namespaces for this command (so don't confuse" + "it with racket bindings). A new namespace is initialized using the name" + "of the namespace (if it's require-able), or using the same initial module" + "that was used for the current namespace. If `! ' is used, it" + "indicates that a new namespace will be created even if it exists, using" + "`' as the initial module, and if just `!' is used, then this happens" + "with the existing namespace's init or with the current one's." + "A few examples:" + " ,switch ! reset the current namespace" + " ,switch ! racket reset it using the `racket' language" + " ,switch r5rs switch to a new `r5rs' namespace" + " ,switch foo switch to `foo', creating it if it doesn't exist" + " ,switch foo ! racket switch to newly made `foo', even if it exists" + " ,switch foo ! same, but using the same as it was created" + " with, or same as the current if it's new" + "(Note that you can use `^' etc to communicate values between namespaces.)"] + (define-values (name force-reset? init) + (match (getarg 'sexpr 'list) + [(list '!) (values #f #t #f )] + [(list '! init) (values #f #t init)] + [(list name) (values name #f #f )] + [(list name '!) (values name #t #f )] + [(list name '! init) (values name #t init)] + [(list) (cmderror "what do you want to do?")] + [_ (cmderror "syntax error, see ,help switch-namespace")])) + (unless (or (not name) (symbol? name) (fixnum? name)) + (cmderror "bad namespace name, must be symbol or fixnum")) + (define old-namespace (current-namespace)) + (define (is-require-able? name) + (with-handlers ([void (λ (_) #f)]) + ;; name is not a string => no need to set the current directory + (file-exists? (modspec->path name)))) + ;; if there's an , then it must be forced + (let* ([name (or name (current-namespace-name))] + [init + (cond [init] + [(or force-reset? (not (hash-ref namespaces name #f))) + (cdr (or (hash-ref namespaces name #f) + (and (is-require-able? name) (cons #f name)) + (hash-ref namespaces (current-namespace-name) #f) + ;; just in case + (hash-ref namespaces default-namespace-name #f)))] + [else #f])]) + (when init + (printf "*** ~a `~s' namespace with ~s ***\n" + (if (hash-ref namespaces name #f) + "Resetting the" "Initializing a new") + name + (->relname init)) + (current-namespace (make-base-empty-namespace)) + (namespace-require init) + (hash-set! namespaces name (cons (current-namespace) init)))) + (when (and name (not (eq? name (current-namespace-name)))) + (printf "*** switching to the `~s' namespace ***\n" name) + (let ([x (hash-ref namespaces (current-namespace-name))]) + (unless (eq? (car x) old-namespace) + (printf "*** (note: saving current namespace for `~s')\n" + (current-namespace-name)) + (hash-set! namespaces (current-namespace-name) + (cons old-namespace (cdr x))))) + (current-namespace-name name) + (current-namespace (car (hash-ref namespaces name))))) + +;; ---------------------------------------------------------------------------- +;; syntax commands + +(define current-syntax (make-parameter #f)) +(defautoload racket/pretty pretty-write) +(defautoload macro-debugger/stepper-text expand/step-text) +(define not-in-base + (λ () (let ([base-stxs #f]) + (unless base-stxs + (set! base-stxs ; all ids that are bound to a syntax in racket/base + (parameterize ([current-namespace (here-namespace)]) + (let-values ([(vals stxs) (module->exports 'racket/base)]) + (map (λ (s) (namespace-symbol->identifier (car s))) + (cdr (assq 0 stxs))))))) + (λ (id) (not (ormap (λ (s) (free-identifier=? id s)) base-stxs)))))) +(defcommand (syntax stx st) "[] [ ...]" + "set syntax object to inspect, and control it" + ["With no arguments, will show the previously set (or expanded) syntax" + "additional arguments serve as an operation to perform:" + "- `^' sets the syntax from the last entered expression" + "- `+' will `expand-once' the syntax and show the result (can be used again" + " for additional `expand-once' steps)" + "- `!' will `expand' the syntax and show the result" + "- `*' will use the syntax stepper to show expansion steps, leaving macros" + " from racket/base intact (does not change the currently set syntax)" + "- `**' similar to `*', but expanding everything"] + (for ([stx (in-list (getarg 'syntax 'list))]) + (define (show/set label stx) + (printf "~a\n" label) + (current-syntax stx) + (pretty-write (syntax->datum stx))) + (define (cur) (or (current-syntax) (cmderror "no syntax set yet"))) + (case (and stx (if (identifier? stx) (syntax-e stx) '--none--)) + [(#f) (show/set "current syntax:" (cur))] + [(^) (if (last-input-syntax) + (show/set "using last expression:" (last-input-syntax)) + (cmderror "no expression entered yet"))] + [(+) (show/set "expand-once ->" (expand-once (cur)))] + [(!) (show/set "expand ->" (expand (cur)))] + [(*) (printf "stepper:\n") (expand/step-text (cur) (not-in-base))] + [(**) (printf "stepper:\n") (expand/step-text (cur))] + [else + (if (syntax? stx) + (begin (printf "syntax set\n") (current-syntax stx)) + (cmderror "internal error: ~s ~s" stx (syntax? stx)))]))) + +;; ---------------------------------------------------------------------------- +;; meta evaluation hook + +;; questionable value, (and need to display the resulting values etc) +#; +(defcommand meta "" + "meta evaluation" + ["Evaluate the given expression where bindings are taken from the xrepl" + "module. This is convenient when you're in a namespace that does not have" + "a specific binding -- for example, you might be using a language that" + "doesn't have `current-namespace', so to get it, you can use" + "`,eval (current-namespace)'. The evaluation happens in the repl namespace" + "as usual, only the bindings are taken from the xrepl module -- so you can" + "use `^' to refer to the result of such an evaluation."] + (eval (datum->syntax #'here `(#%top-interaction . ,(getarg 'sexpr)))) + (void)) + +;; ---------------------------------------------------------------------------- +;; dynamic log output control + +(define current-log-receiver-thread (make-parameter #f)) +(define global-logger (current-logger)) + +(defcommand log "" + "control log output" + ["Starts (or stops) logging events at the given level. The level should be" + "one of the valid racket logging levels, or #f for no logging. For" + "convenience, the level can also be #t (maximum logging) or an integer" + "(with 0 for no logging, and larger numbers for more logging output)."] + (define levels '(#f fatal error warning info debug)) + (define level + (let ([l (getarg 'sexpr)]) + (cond [(memq l levels) l] + [(memq l '(#f none -)) #f] + [(memq l '(#t all +)) (last levels)] + [(not (integer? l)) + (cmderror "bad level, expecting one of: ~s" levels)] + [(<= l 0) #f] + [(< l (length levels)) (list-ref levels l)] + [else (last levels)]))) + (cond [(current-log-receiver-thread) => kill-thread]) + (when level + (let ([r (make-log-receiver global-logger level)]) + (current-log-receiver-thread + (thread + (λ () + (let loop () + (match (sync r) + [(vector l m v) + (display (format "; [~a] ~a~a\n" + l m (if v (format " ~.s" v) ""))) + (flush-output)]) + (loop)))))))) + +;; ---------------------------------------------------------------------------- +;; setup xrepl in the user's racketrc file + +(define init-file (find-system-path 'init-file)) +(defcommand install! #f + "install xrepl in your Racket init file" + ["Installs xrepl in your Racket REPL initialization file. This is done" + "carefully: I will tell you about the change, and ask for permission." + "You can then edit the file if you want to; in your system, you can find it" + ,(format "at \"~a\"." init-file)] + (define comment "The following line loads `xrepl' support") + (define expr "(require xrepl)") + (define dexpr "(dynamic-require 'xrepl #f)") + (define contents (file->string init-file)) + (define (look-for comment-rx expr) + (let ([m (regexp-match-positions + (format "(?<=\r?\n|^) *;+ *~a *\r?\n *~a *(?=\r?\n|$)" + comment-rx (regexp-quote expr)) + contents)]) + (and m (car m)))) + (define existing? (look-for (regexp-quote comment) expr)) + (define existing-readline? + (look-for "load readline support[^\r\n]*" "(require readline/rep)")) + (define (yes?) + (flush-output) + (begin0 (regexp-match? #rx"^[yY]" (getarg 'string)) (prompt-shown))) + (cond + [existing? + (printf "; already installed, nothing to do\n") + (when existing-readline? + (printf "; (better to remove the readline loading, xrepl does that)"))] + [(let ([m (regexp-match + (string-append (regexp-quote expr) "|" (regexp-quote dexpr)) + contents)]) + (and m (begin (printf "; found \"~a\", ~a\n" + (car m) "looks like xrepl is already installed") + (printf "; should I continue anyway? ") + (not (yes?)))))] + [else + (when existing-readline? + (printf "; found a `readline' loading line\n") + (printf "; xrepl will already do that, ok to remove? ") + (if (yes?) + (set! contents (string-append + (substring contents 0 (car existing-readline?)) + (substring contents (cdr existing-readline?)))) + (printf "; it will be kept ~a\n" + "(you can edit the file and removing it later)"))) + (printf "; writing new contents, with an added \"~a\"\n" expr) + (printf "; (if you want to load it conditionally, edit the file and\n") + (printf "; use \"~a\" instead, which is a plain expression)\n" dexpr) + (printf "; OK to continue? ") + (if (yes?) + (begin + (call-with-output-file* init-file #:exists 'truncate + (λ (o) (write-string + (string-append (regexp-replace #rx"(?:\r?\n)+$" contents "") + (format "\n\n;; ~a\n~a\n" comment expr)) + o))) + (printf "; new contents written to ~a\n" init-file)) + (printf "; ~a was not updated\n" init-file))]) + (void)) + +;; ---------------------------------------------------------------------------- +;; eval hook that keep track of recent evaluation results + +;; saved interaction values +(define saved-values (make-parameter '())) +(define (save-values! xs) + (let ([xs (filter (λ (x) (not (void? x))) xs)]) ; don't save void values + (unless (null? xs) + ;; the order is last, 2nd-to-last, ..., same from prev interactions + ;; the idea is that `^', `^^', etc refer to the values as displayed + (saved-values (append (reverse xs) (saved-values))) + (let ([n (saved-values-number)] [l (saved-values)]) + (when (< n (length l)) (saved-values (take l n))))))) + +(define last-saved-names+state (make-parameter '(#f #f #f))) +(define (get-saved-names) + (define last (last-saved-names+state)) + (define last-num (cadr last)) + (define last-char (caddr last)) + (define cur-num (saved-values-number)) + (define cur-char (saved-values-char)) + (if (and (equal? last-num cur-num) (equal? last-char cur-char)) + (car last) + (let ([new (for/list ([i (in-range (saved-values-number))]) + (string->symbol (make-string (add1 i) (saved-values-char))))]) + (last-saved-names+state (list new cur-num cur-char)) + new))) + +;; make saved values available through bindings, but do this in a way that +;; doesn't interfere with users using these binders in some way -- set only ids +;; that were void, and restore them to void afterwards +(define (with-saved-values thunk) + (define saved-names (get-saved-names)) + (define vals (for/list ([id (in-list saved-names)]) + (box (namespace-variable-value id #f void)))) + (define res #f) + (dynamic-wind + (λ () + (for ([id (in-list saved-names)] + [saved (in-list (saved-values))] + [v (in-list vals)]) + ;; set only ids that are void, and remember these values + (if (void? (unbox v)) + (begin (namespace-set-variable-value! id saved) + (set-box! v saved)) + (set-box! v (void))))) + (λ () (call-with-values thunk (λ vs (set! res vs) (apply values vs)))) + (λ () + (for ([id (in-list saved-names)] [v (in-list vals)]) + ;; restore the names to void so we can set them next time + (when (and (not (void? (unbox v))) ; restore if we set this id above + (eq? (unbox v) ; and if it didn't change + (namespace-variable-value id #f void))) + (namespace-set-variable-value! id (void)))) + (when res (save-values! res))))) + +(provide make-command-evaluator) +(define (make-command-evaluator builtin-evaluator) + (λ (expr) + ;; not useful: catches only escape continuations + ;; (with-handlers ([exn:break? (λ (e) (last-break-exn e) (raise e))]) ...) + (if (saved-values) + (with-saved-values (λ () (builtin-evaluator expr))) + (builtin-evaluator expr)))) + +;; ---------------------------------------------------------------------------- +;; capture ",..." and run the commands, use readline/rep when possible + +(define home-dir (expand-user-path "~")) +(define get-prefix ; to show before the "> " prompt + (let () + (define (choose-path x) + ;; choose the shortest from an absolute path, a relative path, and a + ;; "~/..." path. + (if (not (complete-path? x)) ; shouldn't happen + x + (let* ([r (path->string (find-relative-path (current-directory) x))] + [h (path->string (build-path (string->path-element "~") + (find-relative-path home-dir x)))] + [best (if (< (string-length r) (string-length h)) r h)] + [best (if (< (string-length best) (string-length x)) best x)]) + best))) + (define (get-prefix* path) + (define x (path->string path)) + (define y (->relname path)) + (if (equal? x y) + (format "~s" (choose-path x)) + (regexp-replace #rx"[.]rkt$" y ""))) + (define (get-prefix) + (let* ([x (here-source)] + [x (and x (if (symbol? x) (format "'~s" x) (get-prefix* x)))] + [x (or x (toplevel-prefix))]) + (if (eq? (current-namespace-name) default-namespace-name) + x (format "~a::~a" (current-namespace-name) x)))) + (define last-directory #f) + (define last-namespace #f) + (define prefix #f) + (λ () + (define curdir (current-directory)) + (unless (and (equal? (current-namespace) last-namespace) + (equal? curdir last-directory)) + (report-directory-change) + (set! prefix (get-prefix)) + (set! last-namespace (current-namespace)) + (set! last-directory curdir)) + prefix))) + +;; the last non-command expression read +(define last-input-syntax (make-parameter #f)) + +(struct more-inputs (list) + #:constructor-name more-inputs* #:omit-define-syntaxes) +(define (more-inputs . inputs) (more-inputs* inputs)) + +(provide make-command-reader) +(define (make-command-reader) + (define (plain-reader prefix) ; a plain reader, without readline + (display prefix) (display "> ") (flush-output) + (let ([in ((current-get-interaction-input-port))]) + ((current-read-interaction) (object-name in) in))) + (define RL ; no direct dependency on readline + (with-handlers ([exn? (λ (_) #f)]) + (collection-file-path "pread.rkt" "readline"))) + (define (make-readline-reader) + (let ([p (dynamic-require RL 'current-prompt)] + [r (dynamic-require RL 'read-cmdline-syntax)]) + (λ (prefix) ; uses the readline prompt + (parameterize ([p (bytes-append (string->bytes/locale prefix) (p))]) + (r))))) + (define reader + (case (object-name (current-input-port)) + [(stdin) + (if (or (not (terminal-port? (current-input-port))) + (regexp-match? #rx"^dumb" (or (getenv "TERM") "")) + (not RL)) + plain-reader + (with-handlers ([exn? + (λ (e) + (eprintf "Warning: no readline support (~a)\n" + (exn-message e)) + plain-reader)]) + (dynamic-require 'readline/rep-start #f) + ;; requiring readline should have changed the reader + (if (eq? (current-prompt-read) + (dynamic-require RL 'read-cmdline-syntax)) + (make-readline-reader) + (begin (eprintf "Warning: could not initialize readline\n") + plain-reader))))] + [(readline-input) + (eprintf "Note: readline already loaded\n~a\n" + " (better to let xrepl load it for you)") + (make-readline-reader)] + [else plain-reader])) + ;; IO management + (port-count-lines! (current-input-port)) + ;; wrap the reader to get the command functionality + (define more-inputs '()) + (define (reader-loop) + (parameterize ([saved-values #f]) + (define from-queue? (pair? more-inputs)) + (define input + (if from-queue? + (begin0 (car more-inputs) (set! more-inputs (cdr more-inputs))) + (begin (fresh-line) (begin0 (reader (get-prefix)) (prompt-shown))))) + (syntax-case input () + [(uq cmd) (eq? 'unquote (syntax-e #'uq)) + (let ([r (run-command (syntax->datum #'cmd))]) + (cond [(void? r) (reader-loop)] + [(more-inputs? r) + (set! more-inputs (append (more-inputs-list r) more-inputs)) + (reader-loop)] + [else (eprintf "Warning: internal weirdness: ~s\n" r) r]))] + [_ (begin (unless from-queue? (last-input-syntax input)) input)]))) + reader-loop) From 225f563bdaafb4de606d88ca0968fb69583cd586 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 14 Jul 2011 16:57:45 -0400 Subject: [PATCH 252/746] Add a new `#:dont-re-require-enter' flag for `enter!', to avoid requiring itself into the entered namespace. This makes it useful in some cases where this require leads to a dependency cycle, eg (enter! racket/list). It's obviously not useful for use as-is, since you will not have a bound `enter!' to get out of the namespace (and possibly no `require' to get it) -- but it is useful for meta-tools like xrepl. This is why the flag is verbose. `xrepl' now uses this flag. Also, the check for valid keywords for the form is now done at runtime rather than in the macro. This doesn't matter in this case, since the form is intended for interactive use anyway. Also, separate the two parts of `enter-load/use-compiled' (it was defined curried, but didn't use it). (cherry picked from commit db7f2b4542606037a72f7d86298aa05e5a8f5da8) --- collects/racket/enter.rkt | 106 ++++++++++++--------- collects/scribblings/reference/enter.scrbl | 26 ++--- collects/xrepl/xrepl.rkt | 3 +- 3 files changed, 76 insertions(+), 59 deletions(-) diff --git a/collects/racket/enter.rkt b/collects/racket/enter.rkt index f81b98a214..79169a5ba0 100644 --- a/collects/racket/enter.rkt +++ b/collects/racket/enter.rkt @@ -5,73 +5,85 @@ (provide enter!) (define-syntax (enter! stx) - (define (do-enter mod noise) - (unless (or (not (syntax-e mod)) (module-path? (syntax->datum mod))) - (raise-syntax-error #f "not a valid module path, and not #f" stx mod)) - (unless (memq (syntax-e noise) '(#:verbose #:quiet #:verbose-reload)) - (raise-syntax-error #f "not a valid verbosity keyword" stx noise)) - #`(do-enter! '#,mod '#,noise)) (syntax-protect (syntax-case stx () - [(enter! mod) (do-enter #'mod #'#:verbose-reload)] - [(enter! mod noise) (do-enter #'mod #'noise)] + [(enter! mod flag ...) (andmap keyword? (syntax->datum #'(flag ...))) + #'(do-enter! 'mod '(flag ...))] [_ (raise-syntax-error - #f "bad syntax; should be `(enter! [noise-flag])'" + #f "bad syntax; should be `(enter! [flag...])'" stx)]))) (define orig-namespace (current-namespace)) -(define (do-enter! mod noise) - (if mod - (begin (enter-require mod noise) - (let ([ns (module->namespace mod)]) - (current-namespace ns) - (namespace-require 'racket/enter))) - (current-namespace orig-namespace))) +(define (check-flags flags) + ;; check that all flags are known, that at most one of the noise flags is + ;; present, and add #:verbose-reload if none are (could be done at the macro + ;; level, but this is intended for interactive use anyway) + (let loop ([flags (remove-duplicates flags eq?)] [noise #f]) + (cond [(null? flags) + (if noise '() '(#:verbose-reload))] + [(eq? (car flags) '#:dont-re-require-enter) + (cons (car flags) (loop (cdr flags) noise))] + [(not (memq (car flags) '(#:verbose #:quiet #:verbose-reload))) + (error 'enter! "unknown flag: ~e" (car flags))] + [noise (error 'enter! "contradicting noise flags: ~e and ~e" + noise (car flags))] + [else (cons (car flags) (loop (cdr flags) (car flags)))]))) + +(define (do-enter! mod flags) + (let ([flags (check-flags flags)]) + (if mod + (begin (enter-require mod flags) + (let ([ns (module->namespace mod)]) + (current-namespace ns) + (unless (memq '#:dont-re-require-enter flags) + (namespace-require 'racket/enter)))) + (current-namespace orig-namespace)))) (struct mod (name timestamp depends)) (define loaded (make-hash)) -(define (enter-require mod noise) +(define (enter-require mod flags) ;; Collect dependencies while loading: (parameterize ([current-load/use-compiled (enter-load/use-compiled (current-load/use-compiled) - #f noise)]) + #f flags)]) (dynamic-require mod #f)) ;; Reload anything that's not up to date: - (check-latest mod noise)) + (check-latest mod flags)) -(define ((enter-load/use-compiled orig re? noise) path name) +(define (enter-load/use-compiled orig re? flags) (define notify - (if (case noise [(#:verbose-reload) re?] [(#:verbose) #t] [(#:quiet) #f]) + (if (or (memq '#:verbose flags) (and re? (memq '#:verbose-reload flags))) (lambda (path) (fprintf (current-error-port) " [~aloading ~a]\n" (if re? "re-" "") path)) void)) - (if name - ;; Module load: - (let* ([code (get-module-code - path "compiled" - (lambda (e) - (parameterize ([compile-enforce-module-constants #f]) - (compile e))) - (lambda (ext loader?) (load-extension ext) #f) - #:notify notify)] - [dir (or (current-load-relative-directory) (current-directory))] - [path (path->complete-path path dir)] - [path (normal-case-path (simplify-path path))]) - ;; Record module timestamp and dependencies: - (let ([a-mod (mod name - (get-timestamp path) - (if code - (append-map cdr (module-compiled-imports code)) - null))]) - (hash-set! loaded path a-mod)) - ;; Evaluate the module: - (eval code)) - ;; Not a module: - (begin (notify path) (orig path name)))) + (lambda (path name) + (if name + ;; Module load: + (let* ([code (get-module-code + path "compiled" + (lambda (e) + (parameterize ([compile-enforce-module-constants #f]) + (compile e))) + (lambda (ext loader?) (load-extension ext) #f) + #:notify notify)] + [dir (or (current-load-relative-directory) (current-directory))] + [path (path->complete-path path dir)] + [path (normal-case-path (simplify-path path))]) + ;; Record module timestamp and dependencies: + (let ([a-mod (mod name + (get-timestamp path) + (if code + (append-map cdr (module-compiled-imports code)) + null))]) + (hash-set! loaded path a-mod)) + ;; Evaluate the module: + (eval code)) + ;; Not a module: + (begin (notify path) (orig path name))))) (define (get-timestamp path) (file-or-directory-modify-seconds path #f @@ -81,7 +93,7 @@ (path-replace-suffix path #".ss") #f (lambda () -inf.0)) -inf.0)))) -(define (check-latest mod noise) +(define (check-latest mod flags) (define mpi (module-path-index-join mod #f)) (define done (make-hash)) (let loop ([mpi mpi]) @@ -98,7 +110,7 @@ (when (ts . > . (mod-timestamp mod)) (define orig (current-load/use-compiled)) (parameterize ([current-load/use-compiled - (enter-load/use-compiled orig #f noise)] + (enter-load/use-compiled orig #f flags)] [current-module-declare-name rpath]) - ((enter-load/use-compiled orig #t noise) + ((enter-load/use-compiled orig #t flags) npath (mod-name mod))))))))) diff --git a/collects/scribblings/reference/enter.scrbl b/collects/scribblings/reference/enter.scrbl index 3e5f327e71..8a5d915f26 100644 --- a/collects/scribblings/reference/enter.scrbl +++ b/collects/scribblings/reference/enter.scrbl @@ -7,7 +7,7 @@ @defform*[[(enter! module-path) (enter! #f) - (enter! module-path noise-flag)]]{ + (enter! module-path flag ...+)]]{ Intended for use in a @tech{REPL}, such as when @exec{racket} is started in interactive mode. When a @racket[module-path] is provided @@ -26,13 +26,17 @@ module is re-loaded. Re-loading support works only for modules that are first loaded (either directly or indirectly through transitive @racket[require]s) via @racket[enter!]. -After switching namespaces to the designated module, @racket[enter!] -automatically requires @racket[racket/enter] into the namespace, so -that @racket[enter!] can be used to switch namespaces again. - -When @racket[enter!] loads or re-loads a module from a file, it can -print a message to @racket[(current-error-port)], as determined by the -optional @racket[noise-flag]. It can be @racket[#:verbose] to print a -message about such loads and re-loads, @racket[#:verbose-reload] to -print a message only for re-loaded modules, and it can be -@racket[#:quiet] for no printouts.} +Additional @racket[flag]s can customize aspects of @racket[enter!]: +@itemize[ +@item{When @racket[enter!] loads or re-loads a module from a file, it + can print a message to @racket[(current-error-port)]. Use a + @racket[#:verbose] flag to print a message about such loads and + re-loads, @racket[#:verbose-reload] to print a message only for + re-loaded modules, and @racket[#:quiet] for no printouts. The default + reporting corresponds to @racket[#:verbose-reload].} +@item{After switching namespaces to the designated module, + @racket[enter!] automatically requires @racket[racket/enter] into the + namespace, so that @racket[enter!] can be used to switch namespaces + again. In some cases this might not be desirable (e.g., in a tool + that uses @racket[racket/enter])---use a + @racket[#:dont-re-require-enter] to diable this.}] diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index a53c13899b..33f631b622 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -647,7 +647,8 @@ "optional, without it you go back to the toplevel. A module name can" "specify an existing file as with the ,require command. (Note that this" "can be used even in languages that don't have the `enter!' binding.)"] - (eval-sexpr-for-user `(,(enter!-id) ,(getarg 'modspec)))) + (eval-sexpr-for-user `(,(enter!-id) ,(getarg 'modspec) + #:dont-re-require-enter))) (defcommand (toplevel top) #f "go back to the toplevel" From 2c70c982286e7b33d6de426d08b7c74a958da80c Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 14 Jul 2011 17:39:07 -0400 Subject: [PATCH 253/746] Fix a few framework contracts to match code (cherry picked from commit 6c3284a828f58475a9a8cd6cda6665864b156d3b) --- collects/scribblings/framework/color.scrbl | 2 +- collects/scribblings/framework/scheme.scrbl | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/collects/scribblings/framework/color.scrbl b/collects/scribblings/framework/color.scrbl index 067c6bb05b..cfc1ef6e50 100644 --- a/collects/scribblings/framework/color.scrbl +++ b/collects/scribblings/framework/color.scrbl @@ -207,7 +207,7 @@ be inserted, even if it is not the right kind. If @racket[flash?] is true, the matching open parenthesis will be flashed. } - @defmethod*[(((classify-position (position exact-nonnegative-integer?)) symbol?))]{ + @defmethod*[(((classify-position (position exact-nonnegative-integer?)) (or/c symbol? #f)))]{ Return a symbol for the lexer-determined token type for the token that contains the item after @racket[position]. diff --git a/collects/scribblings/framework/scheme.scrbl b/collects/scribblings/framework/scheme.scrbl index 4a822f9009..da1b48cdd8 100644 --- a/collects/scribblings/framework/scheme.scrbl +++ b/collects/scribblings/framework/scheme.scrbl @@ -67,12 +67,13 @@ } @defmethod*[(((tabify (start-pos exact-integer? - (send this text get-start-position))) + (send this get-start-position))) void?))]{ Tabs the line containing by @racket[start-pos] } - @defmethod*[(((tabify-selection (start exact-integer?) (end exact-integer?)) + @defmethod*[(((tabify-selection (start exact-integer? (send this get-start-position)) + (end exact-integer? (send this get-end-position))) void?))]{ Sets the tabbing for the lines containing positions @racket[start] through @racket[end]. From be3aa544ad39b0202000e42d22617fe6dd7d3328 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 14 Jul 2011 18:51:13 -0400 Subject: [PATCH 254/746] Fix unbalanced curly brackets. (cherry picked from commit 937d0ad7223bc9bddf9cda0ecf4d613684d8f1b0) --- collects/scribblings/reference/enter.scrbl | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/scribblings/reference/enter.scrbl b/collects/scribblings/reference/enter.scrbl index 8a5d915f26..cd829dd462 100644 --- a/collects/scribblings/reference/enter.scrbl +++ b/collects/scribblings/reference/enter.scrbl @@ -40,3 +40,4 @@ Additional @racket[flag]s can customize aspects of @racket[enter!]: again. In some cases this might not be desirable (e.g., in a tool that uses @racket[racket/enter])---use a @racket[#:dont-re-require-enter] to diable this.}] +} From c4ca803955146c8af13e5c85040445ab5abf3dfe Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 14 Jul 2011 21:13:28 -0600 Subject: [PATCH 255/746] fix typo; eliminate "this" as a noun; otherminor improvements (cherry picked from commit 5e5172baabf9ab34451da2cd027081c8a2c258e6) --- collects/scribblings/reference/enter.scrbl | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/collects/scribblings/reference/enter.scrbl b/collects/scribblings/reference/enter.scrbl index cd829dd462..c055070850 100644 --- a/collects/scribblings/reference/enter.scrbl +++ b/collects/scribblings/reference/enter.scrbl @@ -5,9 +5,13 @@ @note-init-lib[racket/enter] -@defform*[[(enter! module-path) - (enter! #f) - (enter! module-path flag ...+)]]{ +@defform*/subs[[(enter! module-path) + (enter! #f) + (enter! module-path flag ...+)] + ([flag #:quiet + #:verbose-reload + #:verbose + #:dont-re-require-enter])]{ Intended for use in a @tech{REPL}, such as when @exec{racket} is started in interactive mode. When a @racket[module-path] is provided @@ -28,16 +32,19 @@ are first loaded (either directly or indirectly through transitive Additional @racket[flag]s can customize aspects of @racket[enter!]: @itemize[ -@item{When @racket[enter!] loads or re-loads a module from a file, it - can print a message to @racket[(current-error-port)]. Use a + + @item{When @racket[enter!] loads or re-loads a module from a file, it + can print a message to @racket[(current-error-port)]. Use the @racket[#:verbose] flag to print a message about such loads and re-loads, @racket[#:verbose-reload] to print a message only for re-loaded modules, and @racket[#:quiet] for no printouts. The default reporting corresponds to @racket[#:verbose-reload].} -@item{After switching namespaces to the designated module, + + @item{After switching namespaces to the designated module, @racket[enter!] automatically requires @racket[racket/enter] into the namespace, so that @racket[enter!] can be used to switch namespaces - again. In some cases this might not be desirable (e.g., in a tool - that uses @racket[racket/enter])---use a - @racket[#:dont-re-require-enter] to diable this.}] + again. In some cases, requiring @racket[racket/enter] + might not be desirable (e.g., in a tool + that uses @racket[racket/enter]); use the + @racket[#:dont-re-require-enter] flag to disable the require.}] } From e1dbfe67e3e04356c48f7dd27d4bd0b9331b41be Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 14 Jul 2011 21:13:47 -0600 Subject: [PATCH 256/746] remove obsolete reference to '#%mred-kernel (cherry picked from commit 1c4722eaeea8a62af46a1acd3a6ca15460b14bb2) --- collects/scribblings/reference/startup.scrbl | 3 +-- src/racket/src/module.c | 12 ++---------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/collects/scribblings/reference/startup.scrbl b/collects/scribblings/reference/startup.scrbl index e863e83b29..228ac08e93 100644 --- a/collects/scribblings/reference/startup.scrbl +++ b/collects/scribblings/reference/startup.scrbl @@ -44,8 +44,7 @@ On start-up, the top-level environment contains no bindings---not even that start with @racketidfont{#%} are defined, but they are not meant for direct use, and the set of such modules can change. For example, the @indexed-racket['#%kernel] module is eventually used to bootstrap -the implemetation of @racketmodname[racket/base], and -@racket['#%mred-kernel] is used for @racketmodname[racket/gui/base]. +the implemetation of @racketmodname[racket/base]. The first action of Racket or GRacket is to initialize @racket[current-library-collection-paths] to the result of diff --git a/src/racket/src/module.c b/src/racket/src/module.c index 53da09ec52..c3a345e11c 100644 --- a/src/racket/src/module.c +++ b/src/racket/src/module.c @@ -3403,18 +3403,10 @@ static Scheme_Module *module_load(Scheme_Object *name, Scheme_Env *env, const ch m = (Scheme_Module *)scheme_hash_get(env->module_registry->loaded, name); if (!m) { - char *mred_note; - - if (!strcmp(SCHEME_SYM_VAL(SCHEME_PTR_VAL(name)), "#%mred-kernel") - && !(scheme_strncmp(scheme_banner(), "Welcome to Racket", 17))) - mred_note = "; need to run in gracket instead of racket"; - else - mred_note = ""; - scheme_raise_exn(MZEXN_FAIL_CONTRACT, - "%s: unknown module: %D%s", + "%s: unknown module: %D", who ? who : "require", - name, mred_note); + name); return NULL; } } From f790a77e4004e65c39c504e842de065981218d34 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 14 Jul 2011 21:20:17 -0600 Subject: [PATCH 257/746] places: fix printing of symbol resolved module paths (cherry picked from commit 62acb298bdc79e1f16df8e6a4a95d952388a82fa) --- src/racket/src/print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racket/src/print.c b/src/racket/src/print.c index b71c5b28c5..0cab9a93de 100644 --- a/src/racket/src/print.c +++ b/src/racket/src/print.c @@ -2429,7 +2429,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, int is_sym; if (notdisplay) print_utf8_string(pp, "# Date: Fri, 15 Jul 2011 03:27:27 -0400 Subject: [PATCH 258/746] Standartize the vocabulary to "the function returns" and "set! mutates" (cherry picked from commit c31d352f2bb9498daed8bc4757655c4396b4ba2e) --- collects/2htdp/batch-io.rkt | 2 +- .../private/clauses-spec-and-process.rkt | 2 +- collects/2htdp/private/launch-many-worlds.rkt | 2 +- collects/2htdp/private/world.rkt | 4 +-- collects/2htdp/tests/test-image.rkt | 2 +- collects/2htdp/universe.rkt | 4 +-- collects/htdp/convert.rkt | 2 +- collects/htdp/error-composition.scrbl | 25 ++++++++++++------- collects/htdp/hangman.rkt | 2 +- collects/htdp/htdp-lib.scrbl | 8 +++--- collects/htdp/tests/convert.rkt | 4 +-- collects/lang/private/advanced-funs.rkt | 6 ++--- collects/lang/private/beginner-funs.rkt | 12 ++++----- collects/lang/private/intermediate-funs.rkt | 2 +- collects/lang/private/teachprims.rkt | 4 +-- .../scribblings/htdp-langs/advanced.scrbl | 13 +++++----- collects/scribblings/htdp-langs/prim-ops.rkt | 12 ++++----- collects/tests/htdp-lang/intm-adv.rktl | 2 +- 18 files changed, 58 insertions(+), 50 deletions(-) diff --git a/collects/2htdp/batch-io.rkt b/collects/2htdp/batch-io.rkt index c44a1ff5ca..4684b6218c 100644 --- a/collects/2htdp/batch-io.rkt +++ b/collects/2htdp/batch-io.rkt @@ -41,7 +41,7 @@ write-file ;; String String -> String ;; (write-file filename str) writes str to filename; - ;; produces the file name as a confirmation that the write succeeded + ;; returns the file name as a confirmation that the write succeeded ) ;; ----------------------------------------------------------------------------- diff --git a/collects/2htdp/private/clauses-spec-and-process.rkt b/collects/2htdp/private/clauses-spec-and-process.rkt index 04adcdbbea..df541abd53 100644 --- a/collects/2htdp/private/clauses-spec-and-process.rkt +++ b/collects/2htdp/private/clauses-spec-and-process.rkt @@ -91,7 +91,7 @@ (if r ((third s) r) (fourth s))) Spec)) -;; check whether rec? occurs, produce list of keyword x clause pairs +;; check whether rec? occurs, returns list of keyword x clause pairs (define (clauses-use-kwd stx:list ->rec? tag kwds) (define kwd-in? (->kwds-in kwds)) (map (lambda (stx) diff --git a/collects/2htdp/private/launch-many-worlds.rkt b/collects/2htdp/private/launch-many-worlds.rkt index 7049734e6d..3aabcce6a6 100644 --- a/collects/2htdp/private/launch-many-worlds.rkt +++ b/collects/2htdp/private/launch-many-worlds.rkt @@ -6,7 +6,7 @@ launch-many-worlds ;; (launch-many-worlds e1 ... e2) ;; run expressions e1 through e2 in parallel, - ;; produce all values + ;; return all values ) (define-syntax-rule diff --git a/collects/2htdp/private/world.rkt b/collects/2htdp/private/world.rkt index bbe007b854..7099212e7e 100644 --- a/collects/2htdp/private/world.rkt +++ b/collects/2htdp/private/world.rkt @@ -129,7 +129,7 @@ (height (if (pair? to-draw) (third to-draw) #f))) ;; the visible world - (field [enable-images-button void] ;; used if stop-when call produces #t + (field [enable-images-button void] ;; used if stop-when call returns #t [disable-images-button void] [visible (new pasteboard%)]) @@ -334,7 +334,7 @@ (show (ppdraw))) ;; -> Scene - ;; produce the scene for the this state + ;; return the scene for the this state (define/public (ppdraw) (check-scene-result (name-of draw 'your-draw) (draw (send world get)))) diff --git a/collects/2htdp/tests/test-image.rkt b/collects/2htdp/tests/test-image.rkt index 26bc640223..c237ccfefa 100644 --- a/collects/2htdp/tests/test-image.rkt +++ b/collects/2htdp/tests/test-image.rkt @@ -1380,7 +1380,7 @@ => 128) -;; Rotation by 0 should produce an equivalent object +;; Rotation by 0 should return an equivalent object (test (rotate 0 (make-object image-snip% green-blue-20x10-bitmap)) => (to-img (make-object image-snip% green-blue-20x10-bitmap))) diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index 7d382c7049..c28e444a8b 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -35,7 +35,7 @@ (provide launch-many-worlds ;; (launch-many-worlds e1 ... e2) - ;; run expressions e1 through e2 in parallel, produce all values in same order + ;; run expressions e1 through e2 in parallel, return all values in same order ) (provide-primitive @@ -123,7 +123,7 @@ ;; ****************************************************************** DEFAULT #'(lambda (u w) (make-bundle u '() '())) ;; this is the wrong default function - ;; instead of K there should be a function that produces a bundle + ;; instead of K there should be a function that returns a bundle (function-with-arity 2) ;; ****************************************************************** ] diff --git a/collects/htdp/convert.rkt b/collects/htdp/convert.rkt index 57fe05b29f..9e994bb831 100644 --- a/collects/htdp/convert.rkt +++ b/collects/htdp/convert.rkt @@ -91,7 +91,7 @@ ;; ------------------------------------------------------------------------ (define OUT-ERROR - "The conversion function must produce a number; result: ~e") + "The conversion function must return a number, but it returned ~e") ;; ============================================================================ ;; MODEL diff --git a/collects/htdp/error-composition.scrbl b/collects/htdp/error-composition.scrbl index 1d3107a898..67b39533f4 100755 --- a/collects/htdp/error-composition.scrbl +++ b/collects/htdp/error-composition.scrbl @@ -2,10 +2,9 @@ @(require scribble/manual (for-label [only-in lang/htdp-advanced set!] - [only-in lang/htdp-intermediate let] - [only-in lang/htdp-beginner define] - [only-in racket/base syntax-local-expand-expression] - )) + [only-in lang/htdp-intermediate let] + [only-in lang/htdp-beginner define] + [only-in racket/base syntax-local-expand-expression])) @(require scribble/decode) @@ -51,7 +50,7 @@ from other teachpacks. nor antagonistic.} @item{If an expression contains multiple errors, report the leftmost - error first. E.g., the error in @racket{(define 1 2 3)} is + error first. E.g., the error in @racket[(define 1 2 3)] is @samp{expected the variable name, but found a number}, not @samp{expected 2 parts after define, but found 3}. Before raising an error about a sub-part of a macro, call @@ -71,7 +70,7 @@ Use only the following vocabulary words to describe code: @list[@para{structure name} @para{type name} @para{field name} @para{binding}]]] @itemize[ - @item{Use binding for the square-braced pair in a @racket{let} + @item{Use binding for the square-braced pair in a @racket[let] and similar binding forms.} @item{Use @word{argument} for actual arguments and @word{variable} for @@ -86,6 +85,8 @@ Use only the following vocabulary words to describe code: @section{Words For Describing Runtime Behavior} +Use the following vocabulary words to describe how code runs: + @itemize[ @item{When specifying a function's behavior, say @samp{the function takes ... and returns ...}} @@ -94,12 +95,18 @@ Use only the following vocabulary words to describe code: expects ... but received ...}} @item{As much as possible, identify expressions and the value they evaluate - to, e.g. @samp{the value of @racket{(f x)} is 5}. If it is necessary to + to, e.g. @samp{the value of @racket[(f x)] is 5}. If it is necessary to mention evaluation order, such as when the context discusses mutable state, say that the expression @samp{evaluates to} a value. Function calls are a special case of expression. Prefer @samp{the function call returns ...} to @samp{the function call evaluates to ...}, except when trying to draw attention to - the evaluation of the arguments.}] + the evaluation of the arguments.} + + @item{@racket[set!] and + @racketidfont{set-}@racket[_structure-name]@racketidfont{-}@racket[_field-name]@racketidfont{!} + @word{mutate} variables and structure instances, respectively. Avoid using + the verb @word{sets} when discussing mutation, and reserve the verbs + @word{changes} and @word{updates} for functional updates.}] @section{Prohibited Words} @@ -157,7 +164,7 @@ not appreciate anyway). [Rationale: Students learn this distinction when they learn about lambda. The first is the lambda implicit in the definition, the second is the variable introduced by the definition that can appear - as the first argument to @racket{set!}, the third is the particular + as the first argument to @racket[set!], the third is the particular sequence of letters. But BSL should avoid this complexity, and ASL’s error messages should maintain consistency with BSL.]} diff --git a/collects/htdp/hangman.rkt b/collects/htdp/hangman.rkt index ed5501c46b..9b58179a08 100644 --- a/collects/htdp/hangman.rkt +++ b/collects/htdp/hangman.rkt @@ -114,7 +114,7 @@ (define message-panel #f) ;; setup-gui : str ->* message% panel% -;; to produce a status message and a panel where winning/losing can be announced +;; to return a status message and a panel where winning/losing can be announced ;; effect: set up a new frame, arrange the GUI, and display (blank) status word (define (setup-gui status) (local (#| -------------------------------------------------------------- diff --git a/collects/htdp/htdp-lib.scrbl b/collects/htdp/htdp-lib.scrbl index 154150320a..90e3eb390c 100755 --- a/collects/htdp/htdp-lib.scrbl +++ b/collects/htdp/htdp-lib.scrbl @@ -154,12 +154,12 @@ they can be syntactically restricted to application positions. @racket[id] is exported as the primitive operator named @racket[id]. An alternative to @racket[define-higher-order-primitive].} -@defform[(first-order->higher-order expr)]{ +@defform[(first-order->higher-order expression)]{ -If @racket[expr] is an identifier for a first-order function (either a -primitive or a function defined within Beginner Student), produces the +If @racket[expression] is the name of a first-order function (either a +primitive or a function defined within Beginner Student), returns the function as a value; otherwise, the form is equivalent to -@racket[expr]. +@racket[expression]. This form is mainly useful for implementing syntactic forms that, like the application of a higher-order primitive, allow first-order bindings diff --git a/collects/htdp/tests/convert.rkt b/collects/htdp/tests/convert.rkt index 313aa9e310..9ff964b336 100644 --- a/collects/htdp/tests/convert.rkt +++ b/collects/htdp/tests/convert.rkt @@ -35,11 +35,11 @@ (convert-file IN f2c OUT) (with-input-from-file OUT check-convert-out) -(check-error (convert-file IN list OUT) "convert: The conversion function must produce a number; result: (212)") +(check-error (convert-file IN list OUT) "convert: The conversion function must return a number; but it returned (212)") (check-error (convert-file IN first OUT) "first: expected argument of type ; given 212") -(check-error (convert-file IN fx OUT) "convert: The conversion function must produce a number; result: xyz") +(check-error (convert-file IN fx OUT) "convert: The conversion function must return a number; but it returned xyz") (check-error (convert-file IN f2c 10) "convert-file: expected as third argument, given: 10") diff --git a/collects/lang/private/advanced-funs.rkt b/collects/lang/private/advanced-funs.rkt index a64e3157c0..42c59cf9c7 100644 --- a/collects/lang/private/advanced-funs.rkt +++ b/collects/lang/private/advanced-funs.rkt @@ -31,7 +31,7 @@ (with-input-from-string (string (-> any) -> any) "Turns the given string into input for read* operations.") (with-output-to-string (string (-> any) -> any) - "Produces a string from all write/display/print operations.") + "Returns a string from all write/display/print operations.") (print (any -> void) @@ -63,7 +63,7 @@ (assoc (any (listof any) -> (listof any) or false) - "Produces the first element on the list whose first is equal? to v; otherwise it produces false.")) + "Returns the first element on the list whose first is equal? to v; otherwise it returns false.")) ("Misc" (gensym (-> symbol?) @@ -75,7 +75,7 @@ (force (delay -> any) "Finds the delayed value; see also delay.") (promise? (any -> boolean) "Determines if a value is delayed.") - (void (-> void) "Produces a void value.") + (void (-> void) "Returns a void value.") (void? (any -> boolean) "Determines if a value is void.")) ("Posns" diff --git a/collects/lang/private/beginner-funs.rkt b/collects/lang/private/beginner-funs.rkt index 27dc2860df..67a0c93351 100644 --- a/collects/lang/private/beginner-funs.rkt +++ b/collects/lang/private/beginner-funs.rkt @@ -290,13 +290,13 @@ "Evaluates the number of items on a list.") (memq (any (listof any) -> (union false list)) "Determines whether some value is on some list" - " if so, it produces the suffix of the list that starts with x" - " if not, it produces false." + " if so, it returns the suffix of the list that starts with x" + " if not, it returns false." " (It compares values with the eq? predicate.)") (memv (any (listof any) -> (union false list)) "Determines whether some value is on the list" - " if so, it produces the suffix of the list that starts with x" - " if not, it produces false." + " if so, it returns the suffix of the list that starts with x" + " if not, it returns false." " (It compares values with the eqv? predicate.)") ((beginner-member? member?) (any (listof any) -> boolean) "Determines whether some value is on the list" @@ -405,7 +405,7 @@ (string (char ... -> string) "Builds a string of the given characters.") (make-string (nat char -> string) - "Produces a string of given length" + "Returns a string of given length" " from a single given character.") (string-ref (string nat -> char) "Extracts the i-the character from a string.") @@ -455,7 +455,7 @@ "Converts a string into a symbol.") (string->number (string -> (union number false)) "Converts a string into a number," - " produce false if impossible.") + " return false if impossible.") (string->list (string -> (listof char)) "Converts a string into a list of characters.") (list->string ((listof char) -> string) diff --git a/collects/lang/private/intermediate-funs.rkt b/collects/lang/private/intermediate-funs.rkt index 4018c35f3d..67e73b3d98 100644 --- a/collects/lang/private/intermediate-funs.rkt +++ b/collects/lang/private/intermediate-funs.rkt @@ -52,7 +52,7 @@ "Finds the (first) element of the list that maximizes the output of the function.") (memf ((X -> any) (listof X) -> (union false (listof X))) - "Determines whether the first argument produces a non-false value for any item in the second argument.") + "Determines whether the function fiven as the first argument returns a non-false value for any item in the second argument.") (apply ((X-1 ... X-N -> Y) X-1 ... X-i (list X-i+1 ... X-N) -> Y) "Applies a function using items from a list as the arguments.") (compose ((Y-1 -> Z) ... (Y-N -> Y-N-1) (X-1 ... X-N -> Y-N) -> (X-1 ... X-N -> Z)) diff --git a/collects/lang/private/teachprims.rkt b/collects/lang/private/teachprims.rkt index c9b191c341..a3145367f1 100644 --- a/collects/lang/private/teachprims.rkt +++ b/collects/lang/private/teachprims.rkt @@ -352,8 +352,8 @@ namespace. (define r (f i)) (unless (char? r) (hocheck 'build-string - "the second argument must be a function that produces a character, ~ - given ~e, which produced ~e for ~e" f r i)) + "the second argument must be a function that returns a character, ~ + given ~e, which returned ~e when given ~e" f r i)) r)))) diff --git a/collects/scribblings/htdp-langs/advanced.scrbl b/collects/scribblings/htdp-langs/advanced.scrbl index 2402c36abc..e820ec6a65 100644 --- a/collects/scribblings/htdp-langs/advanced.scrbl +++ b/collects/scribblings/htdp-langs/advanced.scrbl @@ -91,7 +91,8 @@ @; ---------------------------------------------------------------------- @section[#:tag "advanced-syntax"]{Syntax for Advanced} -In Advanced, @racket[set!] can be used to change variables. @racket[define] and +In Advanced, @racket[set!] can be used to mutate variables, and +@racket[define-struct]'s structures are mutatable. @racket[define] and @racket[lambda] can define functions of zero arguments, and function calls can invoke functions of zero arguments. @@ -155,17 +156,17 @@ the @racket[begin] expression is the value of the first @racket[expression].} @defform[(set! variable expression)]{ -Evaluates @racket[expression], and then changes the definition @racket[variable] +Evaluates @racket[expression], and then mutates the @racket[variable] to have @racket[expression]'s value. The @racket[variable] must be defined by @racket[define], @racket[letrec], @racket[let*], or @racket[let].} @defform[(delay expression)]{ -Produces a ``promise'' to evaluate @racket[expression]. The @racket[expression] +Returns a ``promise'' to evaluate @racket[expression]. The @racket[expression] is not evaluated until the promise is forced with @racket[force]; when the promise is forced, the result is recorded, so that any further -@racket[force] of the promise immediately produces the remembered value.} +@racket[force] of the promise immediately returns the remembered value.} @@ -262,7 +263,7 @@ error.} @defform[(unless test-expression body-expression)]{ Like @racket[when], but the @racket[body-expression] is evaluated when the -@racket[test-expression] produces @racket[false] instead of @racket[true].} +@racket[test-expression] evaluates to @racket[false] instead of @racket[true].} @section[#:tag "advanced-common-syntax"]{Common Syntaxes} @@ -291,7 +292,7 @@ level as they did in the @secref["intermediate-lam"] level. @itemize[ @item{@racketidfont{set-}@racket[_structure-name]@racketidfont{-}@racket[_field-name]@racketidfont{!} : takes an instance of the structure and a value, and - changes the instance's field to the given value.}]} + mutates the instance's field to the given value.}]} define-wish cond else diff --git a/collects/scribblings/htdp-langs/prim-ops.rkt b/collects/scribblings/htdp-langs/prim-ops.rkt index 473e39851b..034e2fcbf7 100644 --- a/collects/scribblings/htdp-langs/prim-ops.rkt +++ b/collects/scribblings/htdp-langs/prim-ops.rkt @@ -312,22 +312,22 @@ (#,check-error-elem expression)]]{ Checks that the @racket[expression] reports an error, - where the error messages matches the string produced by the - @racket[matchexpression], if it is present.} + where the error messages matches the + value of @racket[matchexpression], if it is present.} @defform*[#:id [check-member-of check-member-of-id] [(check-member-of expression expression expression ...)]]{ - Checks that the first @racket[expression] produces the same value - as one of the following @racket[expression]s.} + Checks that the value of the first @racket[expression] as that of + one of the following @racket[expression]s.} @defform*[#:id [check-range check-range-id] [(check-range expression low-expression high-expression)]]{ - Checks that the first @racket[expression] produces a number in - between the numbers produced by @racket[low-expression] and + Checks that the value of the first @racket[expression] is a number in + between the value of the @racket[low-expression] and the @racket[high-expression], inclusive.} @; ---------------------------------------------------------------------- diff --git a/collects/tests/htdp-lang/intm-adv.rktl b/collects/tests/htdp-lang/intm-adv.rktl index ff76b0b5f8..841d5818b7 100644 --- a/collects/tests/htdp-lang/intm-adv.rktl +++ b/collects/tests/htdp-lang/intm-adv.rktl @@ -106,7 +106,7 @@ "foldl : first argument must be a function that expects two arguments, given #") (htdp-err/rt-test (build-string 2 add1) - "build-string : the second argument must be a function that produces a character, given #, which produced 1 for 0") + "build-string : the second argument must be a function that returns a character, given #, which returned 1 when given 0") (htdp-test 0 '+ (+)) (htdp-test 1 '+ (+ 1)) From 29e8c44ba9b9d45342bcb8d5dd646c575809078e Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Fri, 15 Jul 2011 03:34:59 -0400 Subject: [PATCH 259/746] Roll back the "expr -> expression" change in the grammar documentation of the teaching languages. The extra width was breaking some browsers. (cherry picked from commit 7134d679216ccfcdd4e5bccbee8cac2ce582ab48) --- .../scribblings/htdp-langs/advanced.scrbl | 60 +++++++++---------- .../htdp-langs/beginner-abbr.scrbl | 22 +++---- .../scribblings/htdp-langs/beginner.scrbl | 20 +++---- .../htdp-langs/intermediate-lambda.scrbl | 32 +++++----- .../scribblings/htdp-langs/intermediate.scrbl | 34 +++++------ .../scribblings/htdp-langs/std-grammar.rkt | 16 ++--- 6 files changed, 92 insertions(+), 92 deletions(-) diff --git a/collects/scribblings/htdp-langs/advanced.scrbl b/collects/scribblings/htdp-langs/advanced.scrbl index e820ec6a65..3ae6901d29 100644 --- a/collects/scribblings/htdp-langs/advanced.scrbl +++ b/collects/scribblings/htdp-langs/advanced.scrbl @@ -15,40 +15,40 @@ (check-expect check-within check-error check-member-of check-range require) [program (code:line def-or-expr ...)] [def-or-expr definition - expression + expr test-case library-require] -[definition (define (name variable ...) expression) - (define name expression) +[definition (define (name variable ...) expr) + (define name expr) (define-struct name (name ...)) (define-datatype name (name name ...) ...)] -[expression (begin expression expression ...) - (begin0 expression expression ...) - (set! variable expression) - (delay expression) - (lambda (variable ...) expression) - (λ (variable ...) expression) - (local [definition ...] expression) - (letrec ([name expression] ...) expression) - (shared ([name expression] ...) expression) - (let ([name expression] ...) expression) - (let name ([name expression] ...) expression) - (let* ([name expression] ...) expression) - (recur name ([name expression] ...) expression) - (code:line (expression expression ...)) - (cond [expression expression] ... [expression expression]) - (cond [expression expression] ... [else expression]) - (case expression [(choice choice ...) expression] ... - [(choice choice ...) expression]) - (case expression [(choice choice ...) expression] ... - [else expression]) - (match expression [pattern expression] ...) - (if expression expression expression) - (when expression expression) - (unless expression expression) - (and expression expression expression ...) - (or expression expression expression ...) - (time expression) +[expr (begin expr expr ...) + (begin0 expr expr ...) + (set! variable expr) + (delay expr) + (lambda (variable ...) expr) + (λ (variable ...) expr) + (local [definition ...] expr) + (letrec ([name expr] ...) expr) + (shared ([name expr] ...) expr) + (let ([name expr] ...) expr) + (let name ([name expr] ...) expr) + (let* ([name expr] ...) expr) + (recur name ([name expr] ...) expr) + (code:line (expr expr ...)) + (cond [expr expr] ... [expr expr]) + (cond [expr expr] ... [else expr]) + (case expr [(choice choice ...) expr] ... + [(choice choice ...) expr]) + (case expr [(choice choice ...) expr] ... + [else expr]) + (match expr [pattern expr] ...) + (if expr expr expr) + (when expr expr) + (unless expr expr) + (and expr expr expr ...) + (or expr expr expr ...) + (time expr) (code:line name) (code:line @#,elem{@racketvalfont{'}@racket[_quoted]}) (code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]}) diff --git a/collects/scribblings/htdp-langs/beginner-abbr.scrbl b/collects/scribblings/htdp-langs/beginner-abbr.scrbl index 8c44194bf6..bcae7f7995 100644 --- a/collects/scribblings/htdp-langs/beginner-abbr.scrbl +++ b/collects/scribblings/htdp-langs/beginner-abbr.scrbl @@ -14,20 +14,20 @@ (check-expect check-within check-member-of check-range check-error require) [program (code:line def-or-expr ...)] [def-or-expr definition - expression + expr test-case library-require] -[definition (define (name variable variable ...) expression) - (define name expression) - (define name (lambda (variable variable ...) expression)) +[definition (define (name variable variable ...) expr) + (define name expr) + (define name (lambda (variable variable ...) expr)) (define-struct name (name ...))] -[expression (code:line (name expression expression ...)) - (code:line (prim-op expression ...)) - (cond [expression expression] ... [expression expression]) - (cond [expression expression] ... [else expression]) - (if expression expression expression) - (and expression expression expression ...) - (or expression expression expression ...) +[expr (code:line (name expr expr ...)) + (code:line (prim-op expr ...)) + (cond [expr expr] ... [expr expr]) + (cond [expr expr] ... [else expr]) + (if expr expr expr) + (and expr expr expr ...) + (or expr expr expr ...) name (code:line @#,elem{@racketvalfont{'}@racket[_quoted]}) (code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]}) diff --git a/collects/scribblings/htdp-langs/beginner.scrbl b/collects/scribblings/htdp-langs/beginner.scrbl index b14dbbdc49..8867fdb2dc 100644 --- a/collects/scribblings/htdp-langs/beginner.scrbl +++ b/collects/scribblings/htdp-langs/beginner.scrbl @@ -13,19 +13,19 @@ (check-expect check-within check-member-of check-range check-error require) [program (code:line def-or-expr ...)] [def-or-expr definition - expression + expr test-case library-require] -[definition (define (name variable variable ...) expression) - (define name expression) - (define name (lambda (variable variable ...) expression)) +[definition (define (name variable variable ...) expr) + (define name expr) + (define name (lambda (variable variable ...) expr)) (define-struct name (name ...))] -[expression (code:line (name expression expression ...)) - (cond [expression expression] ... [expression expression]) - (cond [expression expression] ... [else expression]) - (if expression expression expression) - (and expression expression expression ...) - (or expression expression expression ...) +[expr (code:line (name expr expr ...)) + (cond [expr expr] ... [expr expr]) + (cond [expr expr] ... [else expr]) + (if expr expr expr) + (and expr expr expr ...) + (or expr expr expr ...) name (code:line @#,elem{@racketvalfont{'}@racket[name]}) number diff --git a/collects/scribblings/htdp-langs/intermediate-lambda.scrbl b/collects/scribblings/htdp-langs/intermediate-lambda.scrbl index 8ebd883d1a..57a76e7316 100644 --- a/collects/scribblings/htdp-langs/intermediate-lambda.scrbl +++ b/collects/scribblings/htdp-langs/intermediate-lambda.scrbl @@ -12,25 +12,25 @@ (check-expect check-within check-member-of check-range check-error require) [program (code:line def-or-expr ...)] [def-or-expr definition - expression + expr test-case library-require] -[definition (define (name variable variable ...) expression) - (define name expression) +[definition (define (name variable variable ...) expr) + (define name expr) (define-struct name (name ...))] -[expression (lambda (variable variable ...) expression) - (λ (variable variable ...) expression) - (local [definition ...] expression) - (letrec ([name expression] ...) expression) - (let ([name expression] ...) expression) - (let* ([name expression] ...) expression) - (code:line (expression expression expression ...)) - (cond [expression expression] ... [expression expression]) - (cond [expression expression] ... [else expression]) - (if expression expression expression) - (and expression expression expression ...) - (or expression expression expression ...) - (time expression) +[expr (lambda (variable variable ...) expr) + (λ (variable variable ...) expr) + (local [definition ...] expr) + (letrec ([name expr] ...) expr) + (let ([name expr] ...) expr) + (let* ([name expr] ...) expr) + (code:line (expr expr expr ...)) + (cond [expr expr] ... [expr expr]) + (cond [expr expr] ... [else expr]) + (if expr expr expr) + (and expr expr expr ...) + (or expr expr expr ...) + (time expr) (code:line name) (code:line prim-op) (code:line @#,elem{@racketvalfont{'}@racket[_quoted]}) diff --git a/collects/scribblings/htdp-langs/intermediate.scrbl b/collects/scribblings/htdp-langs/intermediate.scrbl index c53c14c8c5..0e5f56601a 100644 --- a/collects/scribblings/htdp-langs/intermediate.scrbl +++ b/collects/scribblings/htdp-langs/intermediate.scrbl @@ -13,32 +13,32 @@ (check-expect check-within check-member-of check-range check-error require) [program (code:line def-or-expr ...)] [def-or-expr definition - expression + expr test-case library-require] -[definition (define (name variable variable ...) expression) - (define name expression) - (define name (lambda (variable variable ...) expression)) +[definition (define (name variable variable ...) expr) + (define name expr) + (define name (lambda (variable variable ...) expr)) (define-struct name (name ...))] -[expression (local [definition ...] expression) - (letrec ([name expr-for-let] ...) expression) - (let ([name expr-for-let] ...) expression) - (let* ([name expr-for-let] ...) expression) - (code:line (name expression expression ...) ) - (cond [expression expression] ... [expression expression]) - (cond [expression expression] ... [else expression]) - (if expression expression expression) - (and expression expression expression ...) - (or expression expression expression ...) - (time expression) +[expr (local [definition ...] expr) + (letrec ([name expr-for-let] ...) expr) + (let ([name expr-for-let] ...) expr) + (let* ([name expr-for-let] ...) expr) + (code:line (name expr expr ...) ) + (cond [expr expr] ... [expr expr]) + (cond [expr expr] ... [else expr]) + (if expr expr expr) + (and expr expr expr ...) + (or expr expr expr ...) + (time expr) (code:line name) (code:line @#,elem{@racketvalfont{'}@racket[_quoted]}) (code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]}) number string character] -[expr-for-let (lambda (variable variable ...) expression) - expression] +[expr-for-let (lambda (variable variable ...) expr) + expr] ] @prim-nonterms[("intermediate") define define-struct] diff --git a/collects/scribblings/htdp-langs/std-grammar.rkt b/collects/scribblings/htdp-langs/std-grammar.rkt index 4295d1fb23..1c891c8b7e 100644 --- a/collects/scribblings/htdp-langs/std-grammar.rkt +++ b/collects/scribblings/htdp-langs/std-grammar.rkt @@ -16,12 +16,12 @@ (racketgrammar* #:literals lits form ... - [test-case @#,racket[(check-expect expression expression)] - @#,racket[(check-within expression expression expression)] - @#,racket[(check-member-of expression expression (... ...))] - @#,racket[(check-range expression expression expression)] - @#,racket[(check-error expression expression)] - @#,racket[(check-error expression)]] + [test-case @#,racket[(check-expect expr expr)] + @#,racket[(check-within expr expr expr)] + @#,racket[(check-member-of expr expr (... ...))] + @#,racket[(check-range expr expr expr)] + @#,racket[(check-error expr expr)] + @#,racket[(check-error expr)]] (... [library-require @#,racket[(require string)] @#,racket[(require (lib string string ...))] @@ -55,8 +55,8 @@ @#,racket[(quasiquoted ...)] @#,elem{@racketvalfont{'}@racket[quasiquoted]} @#,elem{@racketvalfont{`}@racket[quasiquoted]} - @#,elem{@racketfont{,}@racket[expression]} - @#,elem{@racketfont[",@"]@racket[expression]}]))) + @#,elem{@racketfont{,}@racket[expr]} + @#,elem{@racketfont[",@"]@racket[expr]}]))) (define-syntax-rule (prim-nonterms (section-prefix) define define-struct) From 14cd4ae26c662e642b5ce14c7ea300746b9b2b31 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Fri, 15 Jul 2011 11:47:42 -0400 Subject: [PATCH 260/746] fixed bug in exception handling for drawing; Closes PR 12044 (cherry picked from commit 562252f5892420ca27dccf2e1c6f853629d3668d) --- collects/2htdp/private/world.rkt | 8 ++++++-- collects/2htdp/tests/bad-draw.rkt | 9 ++++----- collects/2htdp/tests/error-in-draw.rkt | 16 ++++++++++++++++ collects/2htdp/tests/error-in-tick.rkt | 17 +++++++++++++++++ collects/2htdp/tests/xtest | 2 ++ 5 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 collects/2htdp/tests/error-in-draw.rkt create mode 100644 collects/2htdp/tests/error-in-tick.rkt diff --git a/collects/2htdp/private/world.rkt b/collects/2htdp/private/world.rkt index 7099212e7e..c311430896 100644 --- a/collects/2htdp/private/world.rkt +++ b/collects/2htdp/private/world.rkt @@ -258,10 +258,14 @@ (pdraw)) (queue-callback (lambda () - (with-handlers ([exn? (handler #t)]) + (define H (handler #t)) + (with-handlers ([exn? H]) ; (define tag (object-name transform)) (define nw (transform (send world get) arg ...)) - (define (d) (pdraw) (set-draw#!)) + (define (d) + (with-handlers ((exn? H)) + (pdraw)) + (set-draw#!)) ;; --- ;; [Listof (Box [d | void])] (define w '()) diff --git a/collects/2htdp/tests/bad-draw.rkt b/collects/2htdp/tests/bad-draw.rkt index 793cbdab91..2846f66f36 100644 --- a/collects/2htdp/tests/bad-draw.rkt +++ b/collects/2htdp/tests/bad-draw.rkt @@ -2,11 +2,10 @@ (require 2htdp/universe) -(define s "") -(define x 0) +(define txt "expected to return a scene but this is a string") -(with-handlers ((exn? (lambda _ "success!"))) +(with-handlers ((exn? (lambda (e) (unless (string=? (exn-message e) txt) (raise e))))) (big-bang 0 - (on-tick (lambda (w) (begin (set! x (+ x 1)) w))) - (to-draw (lambda (w) (set! s (number->string w)))))) + (on-tick add1) + (to-draw (lambda (w) (error txt))))) diff --git a/collects/2htdp/tests/error-in-draw.rkt b/collects/2htdp/tests/error-in-draw.rkt new file mode 100644 index 0000000000..c37782036e --- /dev/null +++ b/collects/2htdp/tests/error-in-draw.rkt @@ -0,0 +1,16 @@ +#lang racket + +(require 2htdp/universe) +(require 2htdp/image) + +(define (f x) + (cond + [(= x 0) (circle 10 'solid 'red)] + [(= x 1) (circle 20 'solid 'red)] + [else (error txt)])) + +(define txt "all questions were #f") + +(with-handlers ([exn? (lambda (e) (unless (string=? (exn-message e) txt) (raise e)))]) + (big-bang 0 (on-tick add1) (to-draw f)) + (error 'error-in-draw "test failed")) diff --git a/collects/2htdp/tests/error-in-tick.rkt b/collects/2htdp/tests/error-in-tick.rkt new file mode 100644 index 0000000000..3156ac3a6e --- /dev/null +++ b/collects/2htdp/tests/error-in-tick.rkt @@ -0,0 +1,17 @@ +#lang racket + +(require 2htdp/universe) +(require 2htdp/image) + +(define (f x) (circle 10 'solid 'red)) + +(define (g x) + (cond + [(= x 0) 1] + [else (error txt)])) + +(define txt "all questions were #f") + +(with-handlers ([exn? (lambda (e) (unless (string=? (exn-message e) txt) (raise e)))]) + (big-bang 0 (on-tick g) (to-draw f)) + (error 'error-in-tick "test failed")) diff --git a/collects/2htdp/tests/xtest b/collects/2htdp/tests/xtest index 25463109d2..90f598586c 100755 --- a/collects/2htdp/tests/xtest +++ b/collects/2htdp/tests/xtest @@ -9,6 +9,8 @@ run() { } run bad-draw.rkt +run error-in-tick.rkt +run error-in-draw.rkt run -t batch-io.rkt run clause-once.rkt run full-scene-visible.rkt From 0372e02294ccef805e9bb71f9dcadbf2fc82c8d1 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Fri, 15 Jul 2011 12:20:11 -0400 Subject: [PATCH 261/746] documented error reporting functions (Cherry picked from 9193203, and slightly edited for conflicts due to code shuffling.) --- collects/htdp/error-reporting.scrbl | 134 +++++++++++++----- collects/htdp/error.rkt | 209 +++++++++++++++------------- collects/htdp/htdp.scrbl | 27 +++- 3 files changed, 237 insertions(+), 133 deletions(-) diff --git a/collects/htdp/error-reporting.scrbl b/collects/htdp/error-reporting.scrbl index 452e82cbf5..d553cc4bf3 100755 --- a/collects/htdp/error-reporting.scrbl +++ b/collects/htdp/error-reporting.scrbl @@ -1,49 +1,121 @@ #lang scribble/doc -@(require scribble/manual - (for-label htdp/error) - ) +@(require scribble/manual (for-label htdp/error 2htdp/image racket)) @title[#:tag "error-reporting"]{Error Reporting Functions} @defmodule[htdp/error] -To provide uniform error messages from the TeachPacks, this module -provides several functions: +To provide uniform error messages from teachpacks, this module provides several functions: -@defproc[(check-arg) void?]{ +@defproc[(check-arg [name (or/c symbol? string?)] + [chk boolean?] + [expected any/c] + [position (or/c (and/c positive? integer?) string?)] + [given any/c]) + void?]{ + Checks an flat-valued argument to function @scheme[name]. + Reports an error for function @scheme[name] + telling students what kind of data is @scheme[expected] at the @scheme[position]-th argument + and displaying what value was actually @scheme[given], + unless @scheme[chk] is @scheme[true].} + +@defproc[(check-arity [name (or/c symbol? string?)] + [arg# (or/c (and/c positive? integer?) string?)?] + [args list?]) + void?]{ + Checks the arity of a procedure-valued argument to function @scheme[name]. + Reports an error for function @scheme[name] + telling students that @scheme[(length args)] arguments were provided but + @scheme[arg#] were expected, unless @scheme[(= (length args) arg#)] + produces @scheme[true].} + +@defproc[(check-proc [name (or/c symbol? string?)] + [proc any/c] + [expected natural?] + [arg# (or/c (and/c positive? integer?) string?)] + [arg-err string?]) + void?]{ + Checks [the properties of] a procedure-valued argument to function @scheme[name]. + Reports an error for function @scheme[name] + telling students that a procedure was expected at position @scheme[arg#] + and that this procedure should be of arity @scheme[expected], + unless the @scheme[proc] is a function and has the @scheme[expected] arity. + The string @scheme[arg-err] is used to describe the higher-order argument.} + +@defproc[(check-result [name (or/c symbol? string?)] + [pred? (-> any/c boolean?)] + [kind (or/c symbol? string?)] + [returned any/c] ...+) + void?]{ + Checks the expected result of a procedure-valued argument. + If the result satisfies @scheme[pred?], it is returned. + Otherwise, the function reports an error for function @scheme[name] + telling students what @scheme[kind] of value is expected and what the + @scheme[returned] value is. NOTE: if there is more than one + @scheme[returned] value, the function uses the second value. (MF: I forgot + why.)} + + +@defproc[(check-list-list [name (or/c symbol? string?)] + [chk (or/c string? false/c)] + [pred? any/c] + [given any/c]) + void?]{ + Checks a list-of-lists-valued argument to function @scheme[name]. + Reports an error for function @scheme[name] if a list-of-lists contains + a value of the wrong kind---signaled via a string-valued @scheme[chk]. + The @scheme[given] value is the element that went wrong. Rarely used.} + +@defproc[(check-color [name (or/c symbol? string?)] + [arg# natural?] + [given any/c]) + void?]{ + Checks a color-valued argument to function @scheme[name]. + Deprecated. Use @scheme[image-color?] instead. } -@defproc[(check-arity) void?]{ +@defproc[(check-fun-res [f procedure?] + [pred? (-> any/c boolean?)] + [type (or/c symbol? string?)]) + void?]{ + Creates a callback from @scheme[f] and uses @scheme[check-result] to make + sure the result is a piece of data that satisfies @scheme[pred?], + described as @scheme[type]. } -@defproc[(check-proc) void?]{ - } +@defproc[(natural? [o any/c]) boolean?]{ + Determines whether the given value is a natural number.} -@defproc[(check-result) void?]{ - } - -@defproc[(check-list-list) void?]{ - } - -@defproc[(check-color) void?]{ - } - -@defproc[(check-fun-res) void?]{ - } - -@defproc[(check-dependencies) void?]{ - } - -@defproc[(natural?) void?]{ - } - -@defproc[(find-non) void?]{ - } +@defproc[(find-non [pred? (-> any/c boolean?)] [l list?]) (or/c any/c false/c)]{ + Find an element of @scheme[l] for which @scheme[(pred? l)] produces + @scheme[true]; otherwise return @scheme[false].} -@defproc[(tp-exn?) void?]{ +@defproc[(check-dependencies [name (or/c symbol? string?)] + [chk boolean?] + [fmt format-string?] + [arg any/c] ...) + void?]{ + Unless @scheme[chk] is @scheme[true], it raises an error called + @scheme[name] whose message is composed from @scheme[fmt] and the + @scheme[arg]s. } -@defproc[(number->ord) void?]{ +@defproc[(tp-error [name (or/c symbol? string?)] + [fmt format-string?] + [arg any/c] ...) + void?]{ + Signals an @racket[exn:fail:contract] from @scheme[fmt] and @scheme[arg] + for a function called @scheme[name].} + +@defproc[(tp-exn? [o any/c]) boolean?]{ + Determine whether the given object is a teachpack exception + MF: Guillaume seems to have deprecated these structures. } +@defproc[(number->ord [n natural?]) string?]{ + Convert a position number into a string, e.g., 1 into ``first'' and so + on.} + +MF: These library and its uses needs to be cleaned up. + diff --git a/collects/htdp/error.rkt b/collects/htdp/error.rkt index 21883517a1..3e589b01ed 100644 --- a/collects/htdp/error.rkt +++ b/collects/htdp/error.rkt @@ -1,82 +1,59 @@ -#lang scheme/base -(require scheme/class - lang/private/rewrite-error-message) +#lang racket/base -;; -------------------------------------------------------------------------- -(provide check-arg check-arity check-proc check-result - check-list-list check-color - check-fun-res check-dependencies +(require lang/private/rewrite-error-message) + +;; ----------------------------------------------------------------------------- +;; this module provides one-point functionality to report errors in teachpacks + +;; ----------------------------------------------------------------------------- +(provide check-arg + check-list-list + check-arity + check-proc + check-result + check-fun-res + check-color + check-dependencies natural? - find-non tp-exn? number->ord + number->ord + find-non + tp-exn? tp-error) -(define (natural? w) - (and (number? w) (integer? w) (>= w 0))) - -;; (_ -> Boolean) (listof X) -> (union X false) -(define (find-non pred? l) - (let ([r (filter (compose not pred?) l)]) - (if (null? r) #f (car r)))) - - -;(: check-fun-res (∀ (γ) (∀ (β α ...) (α ...α -> β)) (_ -γ-> boolean) _ -> γ)) -(define (check-fun-res f pred? type) - (lambda x - (define r (apply f x)) - (check-result (object-name f) pred? type r) - r)) - -;; check-dependencies : Symbol x Boolean x FormatString x Any* -> Void -(define (check-dependencies pname condition fmt . args) +;; check-arg : sym bool str (or/c str non-negative-integer) TST -> void +(define (check-arg pname condition expected arg-posn given) (unless condition - (tp-error pname (apply format fmt args)))) - -#| Tests ------------------------------------------------------------------ - (not (find-non list? '((1 2 3) (a b c)))) - (symbol? (find-non number? '(1 2 3 a))) - (symbol? (find-non list? '((1 2 3) a (b c)))) - |# - -(define-struct (tp-exn exn) ()) - -(define (tp-error name fmt . args) - (raise - (make-exn:fail:contract #; make-tp-exn - (string-append (format "~a: " name) (apply format fmt args)) - (current-continuation-marks)))) - -(define (number->ord i) - (if (= i 0) - "zeroth" - (case (modulo i 10) - [(0 4 5 6 7 8 9) (format "~ath" i)] - [(1) (format "~ast" i)] - [(2) (format "~and" i)] - [(3) (format "~ard" i)]))) - -;; spell-out : number-or-string -> string -(define (spell-out arg-posn) - (cond - [(string? arg-posn) arg-posn] - [(number? arg-posn) - (case arg-posn - [(1) "first"] - [(2) "second"] - [(3) "third"] - [(4) "fourth"] - [(5) "fifth"] - [(6) "sixth"] - [(7) "seventh"] - [(8) "eighth"] - [(9) "ninth"] - [(10) "tenth"] - [else (number->ord arg-posn)])])) + (tp-error pname "expects ~a as ~a argument, given ~e" + (add-article expected) + (spell-out arg-posn) + given))) ;; Symbol (union true String) String X -> void (define (check-list-list pname condition pred given) (when (string? condition) (tp-error pname (string-append condition (format "\nin ~e" given))))) +;; check-arity : sym num (list-of TST) -> void +(define (check-arity name arg# args) + (unless (= (length args) arg#) + (tp-error name (argcount-error-message arg# (length args))))) + +;; check-proc : sym (... *->* ...) num (union sym str) (union sym str) -> void +(define (check-proc name f exp-arity arg# arg-err) + (unless (procedure? f) + (tp-error name "expected a function as ~a argument; given ~e" arg# f)) + (let ([arity-of-f (procedure-arity f)]) + (unless (procedure-arity-includes? f exp-arity) + (tp-error name "expected function of ~a as ~a argument; given function of ~a " + arg-err arg# + (cond + [(number? arity-of-f) + (if (= arity-of-f 1) + (format "1 argument") + (format "~s arguments" arity-of-f))] + [(arity-at-least? arity-of-f) "variable number of arguments"] + [else (format "multiple arities (~s)" arity-of-f)]))))) + ;; Symbol (_ -> Boolean) String X X *-> X (define (check-result pname pred? expected given . other-given) (if (pred? given) @@ -111,33 +88,75 @@ "expected the name ~e to be a color, but did not recognize it" given)))) -;; check-arg : sym bool str (or/c str non-negative-integer) TST -> void -(define (check-arg pname condition expected arg-posn given) +;; (: check-fun-res (∀ (γ) (∀ (β α ...) (α ...α -> β)) (_ -γ-> boolean) _ -> γ)) +(define (check-fun-res f pred? type) + (lambda x + (check-result (object-name f) pred? type (apply f x)))) + +;; check-dependencies : Symbol x Boolean x FormatString x Any* -> Void +(define (check-dependencies pname condition fmt . args) (unless condition - (tp-error pname "expects a ~a as ~a argument, given ~e" - expected - (spell-out arg-posn) - given))) + (tp-error pname (apply format fmt args)))) -;; check-arity : sym num (list-of TST) -> void -(define (check-arity name arg# args) - (if (= (length args) arg#) - (void) - (tp-error name (argcount-error-message arg# (length args))))) +(define-struct (tp-exn exn) ()) -;; check-proc : -;; sym (... *->* ...) num (union sym str) (union sym str) -> void -(define (check-proc proc f exp-arity arg# arg-err) - (unless (procedure? f) - (tp-error proc "expected a function as ~a argument; given ~e" arg# f)) - (let ([arity-of-f (procedure-arity f)]) - (unless (procedure-arity-includes? f exp-arity) ; (and (number? arity-of-f) (>= arity-of-f exp-arity)) - (tp-error proc "expected function of ~a as ~a argument; given function of ~a " - arg-err arg# - (cond - [(number? arity-of-f) - (if (= arity-of-f 1) - (format "1 argument") - (format "~s arguments" arity-of-f))] - [(arity-at-least? arity-of-f) "variable number of arguments"] - [else (format "multiple arities (~s)" arity-of-f)]))))) +(define (tp-error name fmt . args) + (raise + (make-exn:fail:contract + (string-append (format "~a: " name) (apply format fmt args)) + (current-continuation-marks)))) + +(define (number->ord i) + (if (= i 0) + "zeroth" + (case (modulo i 10) + [(0 4 5 6 7 8 9) (format "~ath" i)] + [(1) (format "~ast" i)] + [(2) (format "~and" i)] + [(3) (format "~ard" i)]))) + +;; (_ -> Boolean) (listof X) -> (union X false) +;; (not (find-non list? '((1 2 3) (a b c)))) +;; (symbol? (find-non number? '(1 2 3 a))) +;; (symbol? (find-non list? '((1 2 3) a (b c)))) +(define (find-non pred? l) + (let ([r (filter (compose not pred?) l)]) + (if (null? r) #f (car r)))) + +(define (natural? w) + (and (number? w) (integer? w) (>= w 0))) + +;; add-article : anything -> string +;; (add-article 'color) should be "a color" +;; (add-article 'acronym) should be "an acronym" +(define (add-article thing) + (let ((s (format "~a" thing))) + (string-append + (if (starts-with-vowel? s) + "an " + "a ") + s))) + +;; starts-with-vowel? : string -> boolean +(define (starts-with-vowel? s) + (and + (not (string=? s "")) + (member (string-ref s 0) (list #\a #\e #\i #\o #\u)))) + +;; spell-out : number-or-string -> string +(define (spell-out arg-posn) + (cond + [(string? arg-posn) arg-posn] + [(number? arg-posn) + (case arg-posn + [(1) "first"] + [(2) "second"] + [(3) "third"] + [(4) "fourth"] + [(5) "fifth"] + [(6) "sixth"] + [(7) "seventh"] + [(8) "eighth"] + [(9) "ninth"] + [(10) "tenth"] + [else (number->ord arg-posn)])])) diff --git a/collects/htdp/htdp.scrbl b/collects/htdp/htdp.scrbl index fa1149e6a9..bc1bdb43e7 100644 --- a/collects/htdp/htdp.scrbl +++ b/collects/htdp/htdp.scrbl @@ -22,12 +22,26 @@ file from the filesystem.} Under the hood, HtDP Teachpacks and HtDP Libraries are implemented the same way, using normal Racket @secref[#:doc '(lib "scribblings/guide/guide.scrbl") "modules"]. -When implementing an extension intended for students, pay a special attention to -the error messages. The error messages of DrRacket's teaching languages go to -great length to ensure that students are never confronted with messages that -uses vocabulary or phrases the students has not learned yet. The teaching languages -also ensure that students cannot stumble by accident onto challenging or -confusing features intended for professional or for higher-level students. +When implementing such an extension for students, pay a special attention +to two aspects: +@itemlist[#:style 'ordered + +@item{@bold{choice of construct}: The teaching languages limit the +expressive power in comparison to plain Racket. One goal is to teach +``design subject to constraints,'' and the other one is to help restrict +the set of explanations for student errors. With regard to the first, we +consider it imperative that new teachpacks and libraries avoid features +intended for upper-level students or professionals.} + +@item{@bold{error messages}: The error messages from the teaching languages +go to great length to never confront students messages that uses vocabulary +or phrases outside of the scope of the chosen level. While teachpacks and +libraries can be used at all levels, they should ideally restrict the +vocabulary in error message to the lowest level language in which they are +to be used.} + +] + This manual describes library support for authors of HtDP Teachpacks, libraries, and customized teaching languages. Use the HtDP @@ -39,7 +53,6 @@ of DrRacket's teaching languages. @local-table-of-contents[#:style 'immediate-only] - @include-section["error-composition.scrbl"] @include-section["error-reporting.scrbl"] From fecc46f97df65248d4a58361d298152e842b11ee Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Fri, 15 Jul 2011 14:50:34 -0400 Subject: [PATCH 262/746] adjusted expected error messages to accommodate Stephen's change (cherry picked from commit 6c51155fec1f54c7c0b0d01aaa1c6e0ffac86fa8) --- collects/2htdp/tests/test-image.rkt | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/collects/2htdp/tests/test-image.rkt b/collects/2htdp/tests/test-image.rkt index c237ccfefa..c074c2623b 100644 --- a/collects/2htdp/tests/test-image.rkt +++ b/collects/2htdp/tests/test-image.rkt @@ -1972,56 +1972,56 @@ (test/exn (rectangle 10 10 "solid" (make-pen "black" 12 "solid" "round" "round")) => - #rx"^rectangle: expects a image-color") + #rx"^rectangle: expects an image-color") (test/exn (rectangle 10 10 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^rectangle: expects a image-color") + #rx"^rectangle: expects an image-color") (test/exn (circle 10 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^circle: expects a image-color") + #rx"^circle: expects an image-color") (test/exn (ellipse 10 10 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^ellipse: expects a image-color") + #rx"^ellipse: expects an image-color") (test/exn (triangle 10 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^triangle: expects a image-color") + #rx"^triangle: expects an image-color") (test/exn (right-triangle 10 12 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^right-triangle: expects a image-color") + #rx"^right-triangle: expects an image-color") (test/exn (isosceles-triangle 10 120 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^isosceles-triangle: expects a image-color") + #rx"^isosceles-triangle: expects an image-color") (test/exn (square 10 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^square: expects a image-color") + #rx"^square: expects an image-color") (test/exn (rhombus 40 45 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^rhombus: expects a image-color") + #rx"^rhombus: expects an image-color") (test/exn (regular-polygon 40 6 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^regular-polygon: expects a image-color") + #rx"^regular-polygon: expects an image-color") (test/exn (star 40 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^star: expects a image-color") + #rx"^star: expects an image-color") (test/exn (star-polygon 40 7 3 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^star-polygon: expects a image-color") + #rx"^star-polygon: expects an image-color") (test/exn (polygon (list (make-posn 0 0) (make-posn 100 0) (make-posn 100 100)) 'solid (make-pen "black" 12 "solid" "round" "round")) => - #rx"^polygon: expects a image-color") + #rx"^polygon: expects an image-color") (test/exn (polygon (list (make-posn 0 0+1i) (make-posn 100 0) (make-posn 100 100)) 'solid (make-pen "black" 12 "solid" "round" "round")) => From a0ccf20b30a88b26a4eea3eb9f37f836a15cd756 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 15 Jul 2011 12:54:09 -0600 Subject: [PATCH 263/746] macro-stepper: disable taint display until correct Merge to release branch (cherry picked from commit 91a2e283a672453b462e3c88444cf53691c3ba8e) --- collects/macro-debugger/syntax-browser/properties.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/macro-debugger/syntax-browser/properties.rkt b/collects/macro-debugger/syntax-browser/properties.rkt index fde507ef0c..65dbcafadd 100644 --- a/collects/macro-debugger/syntax-browser/properties.rkt +++ b/collects/macro-debugger/syntax-browser/properties.rkt @@ -203,7 +203,8 @@ (display-extra-source-info stx) (display-symbol-property-info stx) (display-marks stx) - (display-taint stx)) + ;; Disable until correct: + (when #f (display-taint stx))) ;; display-source-info : syntax -> void (define/private (display-source-info stx) From 9f5ad021f12b3eb380e64c8b8109a7b42f9b3eca Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 15 Jul 2011 19:39:50 -0600 Subject: [PATCH 264/746] fix errortrace The `eq?'ness of syntax objects used to reconstruct the result was broken by disarming. The solution is to reconstruct based on the disarmed syntax object instead of the original. Merge to 5.1.2. (cherry picked from commit 0f61d62ea18e27f1a858a9a44ff70cc7fbda25cb) --- collects/errortrace/stacktrace.rkt | 39 +++++++++++++++--------------- collects/tests/errortrace/wrap.rkt | 25 +++++++++++++++++++ 2 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 collects/tests/errortrace/wrap.rkt diff --git a/collects/errortrace/stacktrace.rkt b/collects/errortrace/stacktrace.rkt index 551c043e9b..3501cb952c 100644 --- a/collects/errortrace/stacktrace.rkt +++ b/collects/errortrace/stacktrace.rkt @@ -306,8 +306,9 @@ (define (make-annotate top? name) (lambda (expr phase) + (define disarmed-expr (disarm expr)) (test-coverage-point - (kernel-syntax-case/phase (disarm expr) phase + (kernel-syntax-case/phase disarmed-expr phase [_ (identifier? expr) (let ([b (identifier-binding expr phase)]) @@ -354,13 +355,13 @@ (rearm expr (rebuild - expr + disarmed-expr (list (cons #'rhs with-coverage)))))] [(begin . exprs) top? (rearm expr - (annotate-seq expr + (annotate-seq disarmed-expr (syntax exprs) annotate-top phase))] [(define-syntaxes (name ...) rhs) @@ -372,7 +373,7 @@ (add1 phase)))]) (rearm expr - (rebuild expr (list (cons #'rhs marked)))))] + (rebuild disarmed-expr (list (cons #'rhs marked)))))] [(define-values-for-syntax (name ...) rhs) top? @@ -383,7 +384,7 @@ (add1 phase)))]) (rearm expr - (rebuild expr (list (cons #'rhs marked)))))] + (rebuild disarmed-expr (list (cons #'rhs marked)))))] [(module name init-import mb) (syntax-case (disarm #'mb) () @@ -397,7 +398,7 @@ (rearm expr (rebuild - expr + disarmed-expr (list (cons mb (rearm @@ -442,21 +443,21 @@ expr (keep-lambda-properties expr - (rebuild expr (map cons clauses clausel))))))] + (rebuild disarmed-expr (map cons clauses clausel))))))] ;; Wrap RHSs and body [(let-values ([vars rhs] ...) . body) (with-mark expr (rearm expr - (annotate-let expr phase + (annotate-let disarmed-expr phase (syntax (vars ...)) (syntax (rhs ...)) (syntax body))))] [(letrec-values ([vars rhs] ...) . body) (let ([fm (rearm expr - (annotate-let expr phase + (annotate-let disarmed-expr phase (syntax (vars ...)) (syntax (rhs ...)) (syntax body)))]) @@ -478,7 +479,7 @@ (with-mark expr (rearm expr - (rebuild expr (list (cons #'rhs new-rhs))))))] + (rebuild disarmed-expr (list (cons #'rhs new-rhs))))))] ;; Wrap subexpressions only [(begin e) @@ -490,12 +491,12 @@ (with-mark expr (rearm expr - (annotate-seq expr #'body annotate phase)))] + (annotate-seq disarmed-expr #'body annotate phase)))] [(begin0 . body) (with-mark expr (rearm expr - (annotate-seq expr #'body annotate phase)))] + (annotate-seq disarmed-expr #'body annotate phase)))] [(if tst thn els) (let ([w-tst (annotate (syntax tst) phase)] [w-thn (annotate (syntax thn) phase)] @@ -503,22 +504,22 @@ (with-mark expr (rearm expr - (rebuild expr (list (cons #'tst w-tst) - (cons #'thn w-thn) - (cons #'els w-els))))))] + (rebuild disarmed-expr (list (cons #'tst w-tst) + (cons #'thn w-thn) + (cons #'els w-els))))))] [(if tst thn) (let ([w-tst (annotate (syntax tst) phase)] [w-thn (annotate (syntax thn) phase)]) (with-mark expr (rearm expr - (rebuild expr (list (cons #'tst w-tst) - (cons #'thn w-thn))))))] + (rebuild disarmed-expr (list (cons #'tst w-tst) + (cons #'thn w-thn))))))] [(with-continuation-mark . body) (with-mark expr (rearm expr - (annotate-seq expr (syntax body) + (annotate-seq disarmed-expr (syntax body) annotate phase)))] ;; Wrap whole application, plus subexpressions @@ -538,7 +539,7 @@ [else (with-mark expr (rearm expr - (annotate-seq expr (syntax body) + (annotate-seq disarmed-expr (syntax body) annotate phase)))])] [_else diff --git a/collects/tests/errortrace/wrap.rkt b/collects/tests/errortrace/wrap.rkt new file mode 100644 index 0000000000..6bbc5fae7d --- /dev/null +++ b/collects/tests/errortrace/wrap.rkt @@ -0,0 +1,25 @@ +#lang racket/base + +(define err-stx #'(error '"bad")) + +(define (try expr) + (define out-str + (parameterize ([current-namespace (make-base-namespace)]) + (parameterize ([current-compile (dynamic-require 'errortrace/errortrace-lib + 'errortrace-compile-handler)] + [error-display-handler (dynamic-require 'errortrace/errortrace-lib + 'errortrace-error-display-handler)]) + (let ([o (open-output-string)]) + (parameterize ([current-error-port o]) + (call-with-continuation-prompt + (lambda () + (eval expr)))) + (get-output-string o))))) + (unless (regexp-match? (regexp-quote (format "~s" (syntax->datum err-stx))) + out-str) + (error 'test "not in context for: ~s" (syntax->datum expr)))) + +(try #`(begin (module m racket/base #,err-stx) (require 'm))) +(try err-stx) +(try #`(syntax-case 'a () + (_ #,err-stx))) From 4e5ac3c261cb48c260d6584e5b572bf0f96e0737 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 15 Jul 2011 13:02:40 -0600 Subject: [PATCH 265/746] typo (cherry picked from commit 9e0a86696935d39b9efcd7fb512ce66c43246a89) --- collects/scribblings/raco/exe-api.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/raco/exe-api.scrbl b/collects/scribblings/raco/exe-api.scrbl index 4d66b1b775..4fb80755d5 100644 --- a/collects/scribblings/raco/exe-api.scrbl +++ b/collects/scribblings/raco/exe-api.scrbl @@ -159,7 +159,7 @@ below. When a module declares run-time paths via path (for use both by immediate execution and for creating a distribution that contains the executable). -If @racket[collects-dest] is a path insteda of @racket[#f], then +If @racket[collects-dest] is a path instead of @racket[#f], then instead of embedding collection-based modules into the executable, the modules (in compiled form, only) are copied into collections in the @racket[collects-dest] directory. From f4bb576511de02c8d3c2878123eae01ff9d8f17d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 06:27:38 -0600 Subject: [PATCH 266/746] limit build parallelism to 4 on a 32-bit machine Merge to 5.1.2 (cherry picked from commit e57b7b9e54b1081d94c41913735d01a72e281aa0) --- collects/setup/option-unit.rkt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/collects/setup/option-unit.rkt b/collects/setup/option-unit.rkt index 88650880e0..30c5d6c468 100644 --- a/collects/setup/option-unit.rkt +++ b/collects/setup/option-unit.rkt @@ -27,7 +27,10 @@ (define setup-program-name (make-parameter "raco setup")) - (define-flag-param parallel-workers (min (processor-count) 8)) + (define-flag-param parallel-workers (min (processor-count) + (if (fixnum? (arithmetic-shift 1 40)) + 8 ; 64-bit machine + 4))) ; 32-bit machine (define-flag-param verbose #f) (define-flag-param make-verbose #f) (define-flag-param compiler-verbose #f) From b560fc83aaffd9088a7df67b1e90a3b43d668862 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 07:51:59 -0600 Subject: [PATCH 267/746] fix taint behavior of some syntax operations `syntax-local-get-shadower' and `syntax-make-delta-introducer' both taint their results when a given syntax object is tainted (cherry picked from commit 4307bcace5070a777b48855caec389133eaffdaf) --- .../scribblings/reference/stx-trans.scrbl | 9 +++++- collects/tests/racket/stx.rktl | 31 +++++++++++++++++++ src/racket/src/env.c | 7 +++++ src/racket/src/syntax.c | 14 +++++++-- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/collects/scribblings/reference/stx-trans.scrbl b/collects/scribblings/reference/stx-trans.scrbl index 7120454734..4d0c387ea7 100644 --- a/collects/scribblings/reference/stx-trans.scrbl +++ b/collects/scribblings/reference/stx-trans.scrbl @@ -623,6 +623,9 @@ Thus, the result is an identifier corresponding to the innermost shadowing of @racket[id-stx] in the current context if it is shadowed, and a module-contextless version of @racket[id-stx] otherwise. +If @racket[id-stx] is @tech{tainted} or @tech{armed}, then the +resulting identifier is @tech{tainted}. + @transform-time[]} @@ -699,7 +702,11 @@ instance of @racket[_orig-id], so that it captures uses with the same lexical context as the use of @racket[_m-id]. More typically, however, @racket[syntax-local-make-delta-introducer] -should be used, since it cooperates with @tech{rename transformers}.} +should be used, since it cooperates with @tech{rename transformers}. + +If @racket[ext-stx] is @tech{tainted} or @tech{armed}, then an +identifier result from the created procedure is @tech{tainted}.} + @defproc[(syntax-local-make-delta-introducer [id identifier?]) (identifier? . -> . identifier?)]{ diff --git a/collects/tests/racket/stx.rktl b/collects/tests/racket/stx.rktl index 70b593f317..d6d10758de 100644 --- a/collects/tests/racket/stx.rktl +++ b/collects/tests/racket/stx.rktl @@ -1526,6 +1526,37 @@ (test #t syntax-tainted? (syntax-touch (round-trip (syntax-arm (quote-syntax foo))))) (test #t syntax-tainted? (round-trip (syntax-touch (syntax-arm (quote-syntax foo)))))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check that attacks are thwarted via `syntax-local-get-shadower' +;; or `make-syntax-delta-introducer': + +(module secret-value-42 racket + (define secret 42) + (define-syntax-rule (m) (even? secret)) + (provide m)) +(require 'secret-value-42) + +(define-syntax (evil-via-shadower stx) + (syntax-case stx () + [(_ e) + (let* ([ee (local-expand #'e 'expression null)] + [id (with-syntax ([(app f x) ee]) #'f)] + [okid (syntax-local-get-shadower id)]) + #`(let ([#,okid values]) + #,ee))])) + +(define-syntax (evil-via-delta-introducer stx) + (syntax-case stx () + [(_ e) + (let* ([ee (local-expand #'e 'expression null)] + [id (with-syntax ([(app f x) ee]) #'f)] + [okid ((make-syntax-delta-introducer id #'e) #'even?)]) + #`(let ([#,okid values]) + #,ee))])) + +(syntax-test #'(evil-via-shadower (m))) +(syntax-test #'(evil-via-delta-introducer (m))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/src/racket/src/env.c b/src/racket/src/env.c index 2787e824d6..0273f4959d 100644 --- a/src/racket/src/env.c +++ b/src/racket/src/env.c @@ -2088,6 +2088,10 @@ local_get_shadower(int argc, Scheme_Object *argv[]) sym = scheme_stx_strip_module_context(sym); /* Add current module context, if any */ sym = local_module_introduce(1, &sym); + + if (!scheme_stx_is_clean(orig_sym)) + sym = scheme_stx_taint(sym); + return sym; } @@ -2102,6 +2106,9 @@ local_get_shadower(int argc, Scheme_Object *argv[]) result = scheme_add_rename(result, rn); + if (!scheme_stx_is_clean(orig_sym)) + result = scheme_stx_taint(result); + return result; } } diff --git a/src/racket/src/syntax.c b/src/racket/src/syntax.c index c37049d23c..08f673025b 100644 --- a/src/racket/src/syntax.c +++ b/src/racket/src/syntax.c @@ -7970,7 +7970,7 @@ Scheme_Object *scheme_transfer_srcloc(Scheme_Object *to, Scheme_Object *from) static Scheme_Object *delta_introducer(int argc, struct Scheme_Object *argv[], Scheme_Object *p) { - Scheme_Object *r, *delta; + Scheme_Object *r, *delta, *taint_p; r = argv[0]; @@ -7978,11 +7978,15 @@ static Scheme_Object *delta_introducer(int argc, struct Scheme_Object *argv[], S scheme_wrong_type("delta-introducer", "syntax", 0, argc, argv); delta = SCHEME_PRIM_CLOSURE_ELS(p)[0]; + taint_p = SCHEME_PRIM_CLOSURE_ELS(p)[1]; for(; !SCHEME_NULLP(delta); delta = SCHEME_CDR(delta)) { r = scheme_add_remove_mark(r, SCHEME_CAR(delta)); } + if (SCHEME_TRUEP(taint_p)) + r = scheme_stx_taint(r); + return r; } @@ -8018,7 +8022,7 @@ static Scheme_Object *extract_phase(const char *who, int pos, int argc, Scheme_O Scheme_Object *scheme_syntax_make_transfer_intro(int argc, Scheme_Object **argv) { - Scheme_Object *orig_m1, *m1, *m2, *delta, *a[1]; + Scheme_Object *orig_m1, *m1, *m2, *delta, *a[2]; int l1, l2; Scheme_Object *phase; @@ -8091,8 +8095,12 @@ Scheme_Object *scheme_syntax_make_transfer_intro(int argc, Scheme_Object **argv) } a[0] = delta; + if (scheme_stx_is_clean(argv[0])) + a[1] = scheme_false; + else + a[2] = scheme_true; - return scheme_make_prim_closure_w_arity(delta_introducer, 1, a, "delta-introducer", 1, 1); + return scheme_make_prim_closure_w_arity(delta_introducer, 2, a, "delta-introducer", 1, 1); } static Scheme_Object *bound_eq(int argc, Scheme_Object **argv) From af3db4d9fe021d67b84edc758fd1e8dbed7e7409 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 14:16:49 -0600 Subject: [PATCH 268/746] change GDK_POINTER_MOTION_HINT_MASK back to GDK_POINTER_MOTION_MASK because HINT doesn't works as expected, and the problem it seemed to solve at one time (slow resize in DrRacket) seems to have been fixed some other way. GDK_MOUSE_MOTION_MASK isn't needed, since GDK_POINTER_MOTION_MASK covers it. Merge to 5.1.2 (cherry picked from commit 5edc0c70afc1e2aeada096f0eb50c92c0f9d8b65) --- collects/mred/private/wx/gtk/canvas.rkt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/collects/mred/private/wx/gtk/canvas.rkt b/collects/mred/private/wx/gtk/canvas.rkt index 5f73c3153b..052725277e 100644 --- a/collects/mred/private/wx/gtk/canvas.rkt +++ b/collects/mred/private/wx/gtk/canvas.rkt @@ -391,8 +391,7 @@ GDK_KEY_RELEASE_MASK GDK_BUTTON_PRESS_MASK GDK_BUTTON_RELEASE_MASK - GDK_POINTER_MOTION_HINT_MASK - GDK_BUTTON_MOTION_MASK + GDK_POINTER_MOTION_MASK GDK_FOCUS_CHANGE_MASK GDK_ENTER_NOTIFY_MASK GDK_LEAVE_NOTIFY_MASK)) From 34b3045b9bd4110123189320500817fb07f9ce25 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 14:18:08 -0600 Subject: [PATCH 269/746] fix SGC Merge to 5.1.2 (cherry picked from commit 3f0914080bf4a48b241ffe05b70e098dfed3f01c) --- src/racket/sgc/sgc.c | 6 ++++-- src/racket/sgc/sgc.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/racket/sgc/sgc.c b/src/racket/sgc/sgc.c index 888f71dd4b..e29e7166e0 100644 --- a/src/racket/sgc/sgc.c +++ b/src/racket/sgc/sgc.c @@ -2108,9 +2108,11 @@ void GC_dump(void) FPRINTF(STDERR, "End Map\n"); } -intptr_t GC_get_memory_use() +long GC_get_memory_use() { - return mem_real_use; + /* returns a `long' instead of `intptr_t' for compatibility + with the Boehm GC */ + return (long)mem_real_use; } void GC_end_stubborn_change(void *p) diff --git a/src/racket/sgc/sgc.h b/src/racket/sgc/sgc.h index 30e8001408..a68844e80c 100644 --- a/src/racket/sgc/sgc.h +++ b/src/racket/sgc/sgc.h @@ -34,7 +34,7 @@ SGC_EXTERN void *GC_base(void *); SGC_EXTERN void GC_dump(void); -SGC_EXTERN intptr_t GC_get_memory_use(); +SGC_EXTERN long GC_get_memory_use(); SGC_EXTERN void GC_end_stubborn_change(void *); From 9e3ee9e2f840148bbded9bb51f846ab19a996095 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 19:27:11 -0600 Subject: [PATCH 270/746] fix cm to configure reader when reading .dep files Merge to 5.1.2 (cherry picked from commit 7af5d490ad3acfe0488f7550e533956303591ce4) --- collects/compiler/cm.rkt | 23 ++++++++++++++--------- collects/syntax/modread.rkt | 20 ++------------------ collects/syntax/private/modread.rkt | 20 ++++++++++++++++++++ 3 files changed, 36 insertions(+), 27 deletions(-) create mode 100644 collects/syntax/private/modread.rkt diff --git a/collects/compiler/cm.rkt b/collects/compiler/cm.rkt index d1f6f615a0..53e44a32fa 100644 --- a/collects/compiler/cm.rkt +++ b/collects/compiler/cm.rkt @@ -7,7 +7,8 @@ scheme/list scheme/path racket/promise - openssl/sha1) + openssl/sha1 + syntax/private/modread) (provide make-compilation-manager-load/use-compiled-handler managed-compile-zo @@ -465,11 +466,13 @@ -inf.0)) (define (try-file-sha1 path dep-path) - (with-handlers ([exn:fail:filesystem? (lambda (exn) #f)]) - (string-append - (call-with-input-file* path sha1) - (with-handlers ([exn:fail:filesystem? (lambda (exn) "")]) - (call-with-input-file* dep-path (lambda (p) (cdadr (read p)))))))) + (with-module-reading-parameterization + (lambda () + (with-handlers ([exn:fail:filesystem? (lambda (exn) #f)]) + (string-append + (call-with-input-file* path sha1) + (with-handlers ([exn:fail:filesystem? (lambda (exn) "")]) + (call-with-input-file* dep-path (lambda (p) (cdadr (read p)))))))))) (define (get-compiled-sha1 mode path) (define-values (dir name) (get-compilation-dir+name mode path)) @@ -492,9 +495,11 @@ (define orig-path (simple-form-path path0)) (define (read-deps path) (with-handlers ([exn:fail:filesystem? (lambda (ex) (list (version) '#f))]) - (call-with-input-file - (path-add-suffix (get-compilation-path mode path) #".dep") - read))) + (with-module-reading-parameterization + (lambda () + (call-with-input-file + (path-add-suffix (get-compilation-path mode path) #".dep") + read))))) (define (do-check) (let* ([main-path orig-path] [alt-path (rkt->ss orig-path)] diff --git a/collects/syntax/modread.rkt b/collects/syntax/modread.rkt index 2a29d7bf90..9c95c6a9a7 100644 --- a/collects/syntax/modread.rkt +++ b/collects/syntax/modread.rkt @@ -1,27 +1,11 @@ (module modread mzscheme - (require racket/contract) + (require racket/contract + "private/modread.rkt") (provide with-module-reading-parameterization) (provide/contract [check-module-form ((or/c syntax? eof-object?) symbol? (or/c string? path? false/c) . -> . any)]) - (define (with-module-reading-parameterization thunk) - (parameterize ([read-case-sensitive #t] - [read-square-bracket-as-paren #t] - [read-curly-brace-as-paren #t] - [read-accept-box #t] - [read-accept-compiled #t] - [read-accept-bar-quote #t] - [read-accept-graph #t] - [read-decimal-as-inexact #t] - [read-accept-dot #t] - [read-accept-infix-dot #t] - [read-accept-quasiquote #t] - [read-accept-reader #t] - [read-accept-lang #t] - [current-readtable #f]) - (thunk))) - (define (raise-wrong-module-name filename expected-name name) (error 'load-handler "expected a `module' declaration for `~a' in ~s, found: ~a" diff --git a/collects/syntax/private/modread.rkt b/collects/syntax/private/modread.rkt new file mode 100644 index 0000000000..749c1d3f66 --- /dev/null +++ b/collects/syntax/private/modread.rkt @@ -0,0 +1,20 @@ +#lang racket/base + +(provide with-module-reading-parameterization) + +(define (with-module-reading-parameterization thunk) + (parameterize ([read-case-sensitive #t] + [read-square-bracket-as-paren #t] + [read-curly-brace-as-paren #t] + [read-accept-box #t] + [read-accept-compiled #t] + [read-accept-bar-quote #t] + [read-accept-graph #t] + [read-decimal-as-inexact #t] + [read-accept-dot #t] + [read-accept-infix-dot #t] + [read-accept-quasiquote #t] + [read-accept-reader #t] + [read-accept-lang #t] + [current-readtable #f]) + (thunk))) From ed4185cae9c35914b0d8304a2938a4b7035ef315 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 19:28:30 -0600 Subject: [PATCH 271/746] don't compile test file with image constant (cherry picked from commit bd10ccc1b7e3ea56d0fb80268b52e26638f575f8) --- collects/tests/drracket/info.rkt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 collects/tests/drracket/info.rkt diff --git a/collects/tests/drracket/info.rkt b/collects/tests/drracket/info.rkt new file mode 100644 index 0000000000..7317c84abd --- /dev/null +++ b/collects/tests/drracket/info.rkt @@ -0,0 +1,5 @@ +#lang setup/infotab + +(define compile-omit-paths + '("image-and-comment-box.rkt")) + From bc46623ecae1d05bc77c612d252ac67bfe68a81f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 20:15:15 -0600 Subject: [PATCH 272/746] restore deinprogramm reader module suffix (cherry picked from commit fc914dfac8a3768653816e03ae767d509797ffb4) --- collects/deinprogramm/deinprogramm-langs.rkt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/collects/deinprogramm/deinprogramm-langs.rkt b/collects/deinprogramm/deinprogramm-langs.rkt index 20f243d2ee..08935ec5cb 100644 --- a/collects/deinprogramm/deinprogramm-langs.rkt +++ b/collects/deinprogramm/deinprogramm-langs.rkt @@ -1379,7 +1379,7 @@ (sharing-printing #f) (abbreviate-cons-as-list #t) (allow-sharing? #f) - (reader-module '(lib "DMdA-beginner-reader.rkt" "deinprogramm")) + (reader-module '(lib "DMdA-beginner-reader.ss" "deinprogramm")) (stepper:supported #t))) (add-deinprogramm-language @@ -1394,7 +1394,7 @@ (sharing-printing #f) (abbreviate-cons-as-list #t) (allow-sharing? #f) - (reader-module '(lib "DMdA-vanilla-reader.rkt" "deinprogramm")) + (reader-module '(lib "DMdA-vanilla-reader.ss" "deinprogramm")) (stepper:supported #t))) (add-deinprogramm-language @@ -1409,7 +1409,7 @@ (sharing-printing #t) (abbreviate-cons-as-list #t) (allow-sharing? #t) - (reader-module '(lib "DMdA-assignments-reader.rkt" "deinprogramm")) + (reader-module '(lib "DMdA-assignments-reader.ss" "deinprogramm")) (stepper:supported #f) (debugger:supported #t))) @@ -1425,6 +1425,6 @@ (sharing-printing #t) (abbreviate-cons-as-list #t) (allow-sharing? #t) - (reader-module '(lib "DMdA-advanced-reader.rkt" "deinprogramm")) + (reader-module '(lib "DMdA-advanced-reader.ss" "deinprogramm")) (stepper:supported #f) (debugger:supported #t)))))) From 5a5430f91e166a011259e36aa39ec3adddc94abf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 21:01:45 -0600 Subject: [PATCH 273/746] revert unnecessary refactoring --- intended to avoid creating a dependency that already exists Merge 5.1.2 (cherry picked from commit ab0e78122c7c80992da73a60ae89ea4512b02494) --- collects/compiler/cm.rkt | 4 ++-- collects/syntax/modread.rkt | 20 ++++++++++++++++++-- collects/syntax/private/modread.rkt | 20 -------------------- 3 files changed, 20 insertions(+), 24 deletions(-) delete mode 100644 collects/syntax/private/modread.rkt diff --git a/collects/compiler/cm.rkt b/collects/compiler/cm.rkt index 53e44a32fa..c507351762 100644 --- a/collects/compiler/cm.rkt +++ b/collects/compiler/cm.rkt @@ -1,14 +1,14 @@ #lang scheme/base (require syntax/modcode syntax/modresolve + syntax/modread setup/main-collects unstable/file scheme/file scheme/list scheme/path racket/promise - openssl/sha1 - syntax/private/modread) + openssl/sha1) (provide make-compilation-manager-load/use-compiled-handler managed-compile-zo diff --git a/collects/syntax/modread.rkt b/collects/syntax/modread.rkt index 9c95c6a9a7..2a29d7bf90 100644 --- a/collects/syntax/modread.rkt +++ b/collects/syntax/modread.rkt @@ -1,11 +1,27 @@ (module modread mzscheme - (require racket/contract - "private/modread.rkt") + (require racket/contract) (provide with-module-reading-parameterization) (provide/contract [check-module-form ((or/c syntax? eof-object?) symbol? (or/c string? path? false/c) . -> . any)]) + (define (with-module-reading-parameterization thunk) + (parameterize ([read-case-sensitive #t] + [read-square-bracket-as-paren #t] + [read-curly-brace-as-paren #t] + [read-accept-box #t] + [read-accept-compiled #t] + [read-accept-bar-quote #t] + [read-accept-graph #t] + [read-decimal-as-inexact #t] + [read-accept-dot #t] + [read-accept-infix-dot #t] + [read-accept-quasiquote #t] + [read-accept-reader #t] + [read-accept-lang #t] + [current-readtable #f]) + (thunk))) + (define (raise-wrong-module-name filename expected-name name) (error 'load-handler "expected a `module' declaration for `~a' in ~s, found: ~a" diff --git a/collects/syntax/private/modread.rkt b/collects/syntax/private/modread.rkt deleted file mode 100644 index 749c1d3f66..0000000000 --- a/collects/syntax/private/modread.rkt +++ /dev/null @@ -1,20 +0,0 @@ -#lang racket/base - -(provide with-module-reading-parameterization) - -(define (with-module-reading-parameterization thunk) - (parameterize ([read-case-sensitive #t] - [read-square-bracket-as-paren #t] - [read-curly-brace-as-paren #t] - [read-accept-box #t] - [read-accept-compiled #t] - [read-accept-bar-quote #t] - [read-accept-graph #t] - [read-decimal-as-inexact #t] - [read-accept-dot #t] - [read-accept-infix-dot #t] - [read-accept-quasiquote #t] - [read-accept-reader #t] - [read-accept-lang #t] - [current-readtable #f]) - (thunk))) From 4af675677d4246107d5c518cffe14f86859568db Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 21:12:22 -0600 Subject: [PATCH 274/746] fix printing of namespace with places enabled This commit goes with 62acb298bdc79e. (cherry picked from commit 701c9666d6091aa55aac0587b0d4240d13044569) --- collects/tests/racket/module.rktl | 17 +++++++++++++++++ src/racket/src/print.c | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/collects/tests/racket/module.rktl b/collects/tests/racket/module.rktl index bc9602488a..feb9b2f2b4 100644 --- a/collects/tests/racket/module.rktl +++ b/collects/tests/racket/module.rktl @@ -501,6 +501,23 @@ (let ([n-ns (eval '(module->namespace ''n) ns)]) (test 5 eval '(lambda (x) x) n-ns))))) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check printing of resolved module paths + +(let ([s (open-output-string)]) + (print (make-resolved-module-path (build-path (current-directory) "a.rkt")) s) + (test #t regexp-match? #rx"namespace 'scheme/base) s) + (test #t regexp-match? #rx"namespace ''n) s) + (test #t regexp-match? #rx"module->modname; - is_sym = SCHEME_SYMBOLP(SCHEME_PTR_VAL(modname)); + is_sym = !SCHEME_PATHP(SCHEME_PTR_VAL(modname)); print_utf8_string(pp, (is_sym ? "'" : "\""), 0, 1); print(SCHEME_PTR_VAL(modname), 0, 0, ht, mt, pp); PRINTADDRESS(pp, modname); From 253ba1376bb85e3ebcd0725f711aa7a91325c76f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 21:25:56 -0600 Subject: [PATCH 275/746] belated test case for cm ".dep"-read fix Merge to 5.1.2 (cherry picked from commit 67272f114b3ff33277397dc790197568b5abf416) --- collects/tests/racket/cm.rktl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/collects/tests/racket/cm.rktl b/collects/tests/racket/cm.rktl index 5d118799e3..036c985649 100644 --- a/collects/tests/racket/cm.rktl +++ b/collects/tests/racket/cm.rktl @@ -138,6 +138,14 @@ (delete-directory/files dir) +;; ---------------------------------------- +;; Check that cm sets reader for .dep files: + +(parameterize ([current-readtable (make-readtable #f #\( 'terminating-macro void)]) + (parameterize ([current-namespace (make-base-namespace)]) + (parameterize ([current-load/use-compiled (make-compilation-manager-load/use-compiled-handler)]) + (test (void) dynamic-require 'compiler/cm #f)))) + ;; ---------------------------------------- (report-errs) From 70fdc4ef90662217a3c34c1b83585ab545ae1dd9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 16 Jul 2011 21:40:14 -0600 Subject: [PATCH 276/746] fix source name of built-in modules Closes PR 12051 Merge to 5.1.2 (cherry picked from commit 92671ab3ea7803e1f0c906e86272c960bdf52ddd) --- collects/tests/racket/module.rktl | 8 ++++++++ src/racket/src/module.c | 2 ++ 2 files changed, 10 insertions(+) diff --git a/collects/tests/racket/module.rktl b/collects/tests/racket/module.rktl index feb9b2f2b4..f17c36a7bd 100644 --- a/collects/tests/racket/module.rktl +++ b/collects/tests/racket/module.rktl @@ -518,6 +518,14 @@ (print (module->namespace ''n) s) (test #t regexp-match? #rx"namespace ''#%network)]) + (test '#%network + variable-reference->module-source + (eval (datum->syntax #'here '(#%variable-reference))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/src/racket/src/module.c b/src/racket/src/module.c index c3a345e11c..a47702b8f2 100644 --- a/src/racket/src/module.c +++ b/src/racket/src/module.c @@ -4766,6 +4766,8 @@ Scheme_Env *scheme_primitive_module(Scheme_Object *name, Scheme_Env *for_env) src = prefix; else src = scheme_intern_resolved_module_path(src); + if (SCHEME_FALSEP(src)) + src = name; insp = scheme_get_param(config, MZCONFIG_CODE_INSPECTOR); } else { From f8c4f23b5cf13809c59a39a8c9c8eb41177c2ea7 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 19 Jul 2011 11:27:51 -0400 Subject: [PATCH 277/746] Manually constructed patch from Robby: fixes the executable problem. --- collects/lang/htdp-langs.rkt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/collects/lang/htdp-langs.rkt b/collects/lang/htdp-langs.rkt index 8bf2d11c0a..44ee9bdac2 100644 --- a/collects/lang/htdp-langs.rkt +++ b/collects/lang/htdp-langs.rkt @@ -475,16 +475,18 @@ ;; Extract snip-related modules: (let-values ([(snip-class-names data-class-names) (extract-used-classes port)]) + (define names (append snip-class-names data-class-names)) (list* '(lib "wxme/read.ss") '(lib "mred/mred.ss") reader-module (filter values - (map (λ (x) (string->lib-path x #t)) - (append - snip-class-names - data-class-names))))) + (append + (map (λ (x) (string->lib-path x #t)) + names) + (map (λ (x) (string->lib-path x #f)) + names))))) ;; Extract reader-related modules: (begin (file-position port 0) From 34530173f951083583b2909638f7dec0607f53bc Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 17 Jul 2011 07:51:12 -0600 Subject: [PATCH 278/746] fix `enter!' to set module source name Merge to 5.1.2 (cherry picked from commit 67936b7a66f088f9d49aff3e7e1052b1b7bc99de) --- collects/racket/enter.rkt | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/collects/racket/enter.rkt b/collects/racket/enter.rkt index 79169a5ba0..5efcb187f2 100644 --- a/collects/racket/enter.rkt +++ b/collects/racket/enter.rkt @@ -74,24 +74,30 @@ [path (path->complete-path path dir)] [path (normal-case-path (simplify-path path))]) ;; Record module timestamp and dependencies: + (define-values (ts actual-path) (get-timestamp path)) (let ([a-mod (mod name - (get-timestamp path) + ts (if code (append-map cdr (module-compiled-imports code)) null))]) (hash-set! loaded path a-mod)) ;; Evaluate the module: - (eval code)) + (parameterize ([current-module-declare-source actual-path]) + (eval code))) ;; Not a module: (begin (notify path) (orig path name))))) (define (get-timestamp path) - (file-or-directory-modify-seconds path #f - (lambda () - (if (regexp-match? #rx#"[.]rkt$" (path->bytes path)) - (file-or-directory-modify-seconds - (path-replace-suffix path #".ss") #f (lambda () -inf.0)) - -inf.0)))) + (let ([ts (file-or-directory-modify-seconds path #f (lambda () #f))]) + (if ts + (values ts path) + (if (regexp-match? #rx#"[.]rkt$" (path->bytes path)) + (let* ([alt-path (path-replace-suffix path #".ss")] + [ts (file-or-directory-modify-seconds alt-path #f (lambda () #f))]) + (if ts + (values ts alt-path) + (values -inf.0 path))) + (values -inf.0 path))))) (define (check-latest mod flags) (define mpi (module-path-index-join mod #f)) @@ -106,11 +112,12 @@ (define mod (hash-ref loaded npath #f)) (when mod (for-each loop (mod-depends mod)) - (define ts (get-timestamp npath)) + (define-values (ts actual-path) (get-timestamp npath)) (when (ts . > . (mod-timestamp mod)) (define orig (current-load/use-compiled)) (parameterize ([current-load/use-compiled (enter-load/use-compiled orig #f flags)] - [current-module-declare-name rpath]) + [current-module-declare-name rpath] + [current-module-declare-source actual-path]) ((enter-load/use-compiled orig #t flags) npath (mod-name mod))))))))) From df42ae7cb7e3d7ff019197ee0be87b5df8d44891 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 17 Jul 2011 08:05:34 -0600 Subject: [PATCH 279/746] fix `get-module-path' and associated exception Closes PR 12029 (cherry picked from commit d8d762517f0a6f283527c15499be5ac08be080cf) --- collects/syntax/modcode.rkt | 6 ++---- collects/syntax/scribblings/modcode.scrbl | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/collects/syntax/modcode.rkt b/collects/syntax/modcode.rkt index cae33f1117..a722bceaee 100644 --- a/collects/syntax/modcode.rkt +++ b/collects/syntax/modcode.rkt @@ -10,7 +10,7 @@ make-exn:get-module-code) (provide/contract - [get-module-code (->* ((or/c path? module-path?)) + [get-module-code (->* (path?) (#:sub-path (and/c path-string? relative-path?) (and/c path-string? relative-path?) @@ -74,7 +74,7 @@ v)))) (lambda () (close-input-port p))))) - (define-struct (exn:get-module-code exn) (path)) + (define-struct (exn:get-module-code exn:fail) (path)) (define (get-module-code path #:sub-path [sub-path0 "compiled"] @@ -85,8 +85,6 @@ #:notify [notify void] #:source-reader [read-src-syntax read-syntax] #:rkt-try-ss? [rkt-try-ss? #t]) - (unless (path-string? path) - (raise-type-error 'get-module-code "path or string (sans nul)" path)) (let*-values ([(orig-path) (resolve path)] [(base orig-file dir?) (split-path path)] [(main-file alt-file) diff --git a/collects/syntax/scribblings/modcode.scrbl b/collects/syntax/scribblings/modcode.scrbl index 55e8a50c1f..68692e4fb7 100644 --- a/collects/syntax/scribblings/modcode.scrbl +++ b/collects/syntax/scribblings/modcode.scrbl @@ -5,7 +5,7 @@ @defmodule[syntax/modcode] -@defproc[(get-module-code [module-path-v module-path?] +@defproc[(get-module-code [path path?] [#:sub-path compiled-subdir0 (and/c path-string? relative-path?) "compiled"] [compiled-subdir (and/c path-string? relative-path?) compiled-subdir0] [#:compile compile-proc0 (any/c . -> . any) compile] @@ -24,7 +24,7 @@ any]{ Returns a compiled expression for the declaration of the module -specified by @racket[module-path-v]. +specified by @racket[path]. The @racket[compiled-subdir] argument defaults to @racket["compiled"]; it specifies the sub-directory to search for a compiled version of the @@ -74,7 +74,7 @@ A parameter whose value is used like @racket[open-input-file] to read a module source or @filepath{.zo} file.} -@defstruct[(exn:get-module-code exn) ([path path?])]{ +@defstruct[(exn:get-module-code exn:fail) ([path path?])]{ An exception structure type for exceptions raised by @racket[get-module-code].} From d8c7bd138ff07d6a2f6d07095cd7f0908a403135 Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Sun, 17 Jul 2011 16:48:12 -0400 Subject: [PATCH 280/746] Undoes the 'produces -> return' part of commit c31d352f, keeping the 'changes -> mutates' change and the assorted bug fixes it contained. (cherry picked from commit adf965e92ab90b6480f3fadef62d954d790a02cf) --- collects/2htdp/batch-io.rkt | 2 +- collects/2htdp/private/clauses-spec-and-process.rkt | 2 +- collects/2htdp/private/launch-many-worlds.rkt | 2 +- collects/2htdp/private/world.rkt | 4 ++-- collects/2htdp/tests/test-image.rkt | 2 +- collects/2htdp/universe.rkt | 4 ++-- collects/htdp/convert.rkt | 2 +- collects/htdp/error-composition.scrbl | 4 ++-- collects/htdp/hangman.rkt | 2 +- collects/htdp/htdp-lib.scrbl | 2 +- collects/htdp/tests/convert.rkt | 6 +++--- collects/lang/private/advanced-funs.rkt | 6 +++--- collects/lang/private/beginner-funs.rkt | 12 ++++++------ collects/lang/private/intermediate-funs.rkt | 4 ++-- collects/lang/private/teachprims.rkt | 4 ++-- collects/scribblings/htdp-langs/advanced.scrbl | 6 +++--- collects/tests/htdp-lang/intm-adv.rktl | 2 +- 17 files changed, 33 insertions(+), 33 deletions(-) diff --git a/collects/2htdp/batch-io.rkt b/collects/2htdp/batch-io.rkt index 4684b6218c..c44a1ff5ca 100644 --- a/collects/2htdp/batch-io.rkt +++ b/collects/2htdp/batch-io.rkt @@ -41,7 +41,7 @@ write-file ;; String String -> String ;; (write-file filename str) writes str to filename; - ;; returns the file name as a confirmation that the write succeeded + ;; produces the file name as a confirmation that the write succeeded ) ;; ----------------------------------------------------------------------------- diff --git a/collects/2htdp/private/clauses-spec-and-process.rkt b/collects/2htdp/private/clauses-spec-and-process.rkt index df541abd53..569ed216d3 100644 --- a/collects/2htdp/private/clauses-spec-and-process.rkt +++ b/collects/2htdp/private/clauses-spec-and-process.rkt @@ -91,7 +91,7 @@ (if r ((third s) r) (fourth s))) Spec)) -;; check whether rec? occurs, returns list of keyword x clause pairs +;; check whether rec? occurs, produces list of keyword x clause pairs (define (clauses-use-kwd stx:list ->rec? tag kwds) (define kwd-in? (->kwds-in kwds)) (map (lambda (stx) diff --git a/collects/2htdp/private/launch-many-worlds.rkt b/collects/2htdp/private/launch-many-worlds.rkt index 3aabcce6a6..7049734e6d 100644 --- a/collects/2htdp/private/launch-many-worlds.rkt +++ b/collects/2htdp/private/launch-many-worlds.rkt @@ -6,7 +6,7 @@ launch-many-worlds ;; (launch-many-worlds e1 ... e2) ;; run expressions e1 through e2 in parallel, - ;; return all values + ;; produce all values ) (define-syntax-rule diff --git a/collects/2htdp/private/world.rkt b/collects/2htdp/private/world.rkt index c311430896..a84b9f27c4 100644 --- a/collects/2htdp/private/world.rkt +++ b/collects/2htdp/private/world.rkt @@ -129,7 +129,7 @@ (height (if (pair? to-draw) (third to-draw) #f))) ;; the visible world - (field [enable-images-button void] ;; used if stop-when call returns #t + (field [enable-images-button void] ;; used if stop-when call produces #t [disable-images-button void] [visible (new pasteboard%)]) @@ -338,7 +338,7 @@ (show (ppdraw))) ;; -> Scene - ;; return the scene for the this state + ;; produce the scene for the this state (define/public (ppdraw) (check-scene-result (name-of draw 'your-draw) (draw (send world get)))) diff --git a/collects/2htdp/tests/test-image.rkt b/collects/2htdp/tests/test-image.rkt index c074c2623b..083dd16fe2 100644 --- a/collects/2htdp/tests/test-image.rkt +++ b/collects/2htdp/tests/test-image.rkt @@ -1380,7 +1380,7 @@ => 128) -;; Rotation by 0 should return an equivalent object +;; Rotation by 0 should produce an equivalent object (test (rotate 0 (make-object image-snip% green-blue-20x10-bitmap)) => (to-img (make-object image-snip% green-blue-20x10-bitmap))) diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index c28e444a8b..7d382c7049 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -35,7 +35,7 @@ (provide launch-many-worlds ;; (launch-many-worlds e1 ... e2) - ;; run expressions e1 through e2 in parallel, return all values in same order + ;; run expressions e1 through e2 in parallel, produce all values in same order ) (provide-primitive @@ -123,7 +123,7 @@ ;; ****************************************************************** DEFAULT #'(lambda (u w) (make-bundle u '() '())) ;; this is the wrong default function - ;; instead of K there should be a function that returns a bundle + ;; instead of K there should be a function that produces a bundle (function-with-arity 2) ;; ****************************************************************** ] diff --git a/collects/htdp/convert.rkt b/collects/htdp/convert.rkt index 9e994bb831..89319d6462 100644 --- a/collects/htdp/convert.rkt +++ b/collects/htdp/convert.rkt @@ -91,7 +91,7 @@ ;; ------------------------------------------------------------------------ (define OUT-ERROR - "The conversion function must return a number, but it returned ~e") + "The conversion function must produce a number; but it produced ~e") ;; ============================================================================ ;; MODEL diff --git a/collects/htdp/error-composition.scrbl b/collects/htdp/error-composition.scrbl index 67b39533f4..ec9c3ac272 100755 --- a/collects/htdp/error-composition.scrbl +++ b/collects/htdp/error-composition.scrbl @@ -89,7 +89,7 @@ Use the following vocabulary words to describe how code runs: @itemize[ @item{When specifying a function's behavior, say @samp{the function - takes ... and returns ...}} + takes ... and produces ...}} @item{When describing a contract violation, say @samp{the function expects ... but received ...}} @@ -98,7 +98,7 @@ Use the following vocabulary words to describe how code runs: to, e.g. @samp{the value of @racket[(f x)] is 5}. If it is necessary to mention evaluation order, such as when the context discusses mutable state, say that the expression @samp{evaluates to} a value. Function calls - are a special case of expression. Prefer @samp{the function call returns ...} + are a special case of expression. Prefer @samp{the function call produces ...} to @samp{the function call evaluates to ...}, except when trying to draw attention to the evaluation of the arguments.} diff --git a/collects/htdp/hangman.rkt b/collects/htdp/hangman.rkt index 9b58179a08..ed5501c46b 100644 --- a/collects/htdp/hangman.rkt +++ b/collects/htdp/hangman.rkt @@ -114,7 +114,7 @@ (define message-panel #f) ;; setup-gui : str ->* message% panel% -;; to return a status message and a panel where winning/losing can be announced +;; to produce a status message and a panel where winning/losing can be announced ;; effect: set up a new frame, arrange the GUI, and display (blank) status word (define (setup-gui status) (local (#| -------------------------------------------------------------- diff --git a/collects/htdp/htdp-lib.scrbl b/collects/htdp/htdp-lib.scrbl index 90e3eb390c..5e0ba89eb3 100755 --- a/collects/htdp/htdp-lib.scrbl +++ b/collects/htdp/htdp-lib.scrbl @@ -157,7 +157,7 @@ they can be syntactically restricted to application positions. @defform[(first-order->higher-order expression)]{ If @racket[expression] is the name of a first-order function (either a -primitive or a function defined within Beginner Student), returns the +primitive or a function defined within Beginner Student), produces the function as a value; otherwise, the form is equivalent to @racket[expression]. diff --git a/collects/htdp/tests/convert.rkt b/collects/htdp/tests/convert.rkt index 9ff964b336..e13cc06c5a 100644 --- a/collects/htdp/tests/convert.rkt +++ b/collects/htdp/tests/convert.rkt @@ -35,13 +35,13 @@ (convert-file IN f2c OUT) (with-input-from-file OUT check-convert-out) -(check-error (convert-file IN list OUT) "convert: The conversion function must return a number; but it returned (212)") +(check-error (convert-file IN list OUT) "convert: The conversion function must produce a number; but it produced (212)") (check-error (convert-file IN first OUT) "first: expected argument of type ; given 212") -(check-error (convert-file IN fx OUT) "convert: The conversion function must return a number; but it returned xyz") +(check-error (convert-file IN fx OUT) "convert: The conversion function must produce a number; but it produced xyz") -(check-error (convert-file IN f2c 10) "convert-file: expected as third argument, given: 10") +(check-error (convert-file IN f2c 10) "convert-file: expects a string as third argument, given 10") ;; ---------------------------------------------------------------------------- ;; convert by repl: diff --git a/collects/lang/private/advanced-funs.rkt b/collects/lang/private/advanced-funs.rkt index 42c59cf9c7..a64e3157c0 100644 --- a/collects/lang/private/advanced-funs.rkt +++ b/collects/lang/private/advanced-funs.rkt @@ -31,7 +31,7 @@ (with-input-from-string (string (-> any) -> any) "Turns the given string into input for read* operations.") (with-output-to-string (string (-> any) -> any) - "Returns a string from all write/display/print operations.") + "Produces a string from all write/display/print operations.") (print (any -> void) @@ -63,7 +63,7 @@ (assoc (any (listof any) -> (listof any) or false) - "Returns the first element on the list whose first is equal? to v; otherwise it returns false.")) + "Produces the first element on the list whose first is equal? to v; otherwise it produces false.")) ("Misc" (gensym (-> symbol?) @@ -75,7 +75,7 @@ (force (delay -> any) "Finds the delayed value; see also delay.") (promise? (any -> boolean) "Determines if a value is delayed.") - (void (-> void) "Returns a void value.") + (void (-> void) "Produces a void value.") (void? (any -> boolean) "Determines if a value is void.")) ("Posns" diff --git a/collects/lang/private/beginner-funs.rkt b/collects/lang/private/beginner-funs.rkt index 67a0c93351..27dc2860df 100644 --- a/collects/lang/private/beginner-funs.rkt +++ b/collects/lang/private/beginner-funs.rkt @@ -290,13 +290,13 @@ "Evaluates the number of items on a list.") (memq (any (listof any) -> (union false list)) "Determines whether some value is on some list" - " if so, it returns the suffix of the list that starts with x" - " if not, it returns false." + " if so, it produces the suffix of the list that starts with x" + " if not, it produces false." " (It compares values with the eq? predicate.)") (memv (any (listof any) -> (union false list)) "Determines whether some value is on the list" - " if so, it returns the suffix of the list that starts with x" - " if not, it returns false." + " if so, it produces the suffix of the list that starts with x" + " if not, it produces false." " (It compares values with the eqv? predicate.)") ((beginner-member? member?) (any (listof any) -> boolean) "Determines whether some value is on the list" @@ -405,7 +405,7 @@ (string (char ... -> string) "Builds a string of the given characters.") (make-string (nat char -> string) - "Returns a string of given length" + "Produces a string of given length" " from a single given character.") (string-ref (string nat -> char) "Extracts the i-the character from a string.") @@ -455,7 +455,7 @@ "Converts a string into a symbol.") (string->number (string -> (union number false)) "Converts a string into a number," - " return false if impossible.") + " produce false if impossible.") (string->list (string -> (listof char)) "Converts a string into a list of characters.") (list->string ((listof char) -> string) diff --git a/collects/lang/private/intermediate-funs.rkt b/collects/lang/private/intermediate-funs.rkt index 67e73b3d98..30edcf6a06 100644 --- a/collects/lang/private/intermediate-funs.rkt +++ b/collects/lang/private/intermediate-funs.rkt @@ -52,10 +52,10 @@ "Finds the (first) element of the list that maximizes the output of the function.") (memf ((X -> any) (listof X) -> (union false (listof X))) - "Determines whether the function fiven as the first argument returns a non-false value for any item in the second argument.") + "Produces true if the function given as the first argument produces a non-false value for any item in the second argument.") (apply ((X-1 ... X-N -> Y) X-1 ... X-i (list X-i+1 ... X-N) -> Y) "Applies a function using items from a list as the arguments.") (compose ((Y-1 -> Z) ... (Y-N -> Y-N-1) (X-1 ... X-N -> Y-N) -> (X-1 ... X-N -> Z)) "Composes a sequence of procedures into a single procedure.") (procedure? (any -> boolean) - "Determines if a value is a procedure.")))) + "Produces true if the value is a procedure.")))) diff --git a/collects/lang/private/teachprims.rkt b/collects/lang/private/teachprims.rkt index a3145367f1..039251ae92 100644 --- a/collects/lang/private/teachprims.rkt +++ b/collects/lang/private/teachprims.rkt @@ -352,8 +352,8 @@ namespace. (define r (f i)) (unless (char? r) (hocheck 'build-string - "the second argument must be a function that returns a character, ~ - given ~e, which returned ~e when given ~e" f r i)) + "the second argument must be a function that produces a character, ~ + given ~e, which produced ~e when given ~e" f r i)) r)))) diff --git a/collects/scribblings/htdp-langs/advanced.scrbl b/collects/scribblings/htdp-langs/advanced.scrbl index 3ae6901d29..9970fbb662 100644 --- a/collects/scribblings/htdp-langs/advanced.scrbl +++ b/collects/scribblings/htdp-langs/advanced.scrbl @@ -163,10 +163,10 @@ by @racket[define], @racket[letrec], @racket[let*], or @racket[let].} @defform[(delay expression)]{ -Returns a ``promise'' to evaluate @racket[expression]. The @racket[expression] +Produces a ``promise'' to evaluate @racket[expression]. The @racket[expression] is not evaluated until the promise is forced with @racket[force]; when the promise is forced, the result is recorded, so that any further -@racket[force] of the promise immediately returns the remembered value.} +@racket[force] of the promise immediately produces the remembered value.} @@ -263,7 +263,7 @@ error.} @defform[(unless test-expression body-expression)]{ Like @racket[when], but the @racket[body-expression] is evaluated when the -@racket[test-expression] evaluates to @racket[false] instead of @racket[true].} +@racket[test-expression] produces @racket[false] instead of @racket[true].} @section[#:tag "advanced-common-syntax"]{Common Syntaxes} diff --git a/collects/tests/htdp-lang/intm-adv.rktl b/collects/tests/htdp-lang/intm-adv.rktl index 841d5818b7..c032984b98 100644 --- a/collects/tests/htdp-lang/intm-adv.rktl +++ b/collects/tests/htdp-lang/intm-adv.rktl @@ -106,7 +106,7 @@ "foldl : first argument must be a function that expects two arguments, given #") (htdp-err/rt-test (build-string 2 add1) - "build-string : the second argument must be a function that returns a character, given #, which returned 1 when given 0") + "build-string : the second argument must be a function that produces a character, given #, which produced 1 when given 0") (htdp-test 0 '+ (+)) (htdp-test 1 '+ (+ 1)) From 4b13d543968fcf2bdf6f76d7c34bd6aa2dddc739 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 17 Jul 2011 20:07:46 -0600 Subject: [PATCH 281/746] fix "block cache" layer to handle allocation failure (cherry picked from commit 5efe7001d656388a86c498b6a5aa45d0f6de106c) --- src/racket/gc2/block_cache.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/racket/gc2/block_cache.c b/src/racket/gc2/block_cache.c index b36494ce29..de973d7b59 100644 --- a/src/racket/gc2/block_cache.c +++ b/src/racket/gc2/block_cache.c @@ -85,13 +85,22 @@ static ssize_t block_cache_free(BlockCache* bc) { static block_desc *bc_alloc_std_block(block_group *bg) { int this_block_size = bg->block_size; void *r = os_alloc_pages(this_block_size); - void *ps = align_up_ptr(r, APAGE_SIZE); + block_desc *bd; + void *ps; + + if (!r) return NULL; + + ps = align_up_ptr(r, APAGE_SIZE); if (this_block_size < BC_MAX_BLOCK_SIZE) { bg->block_size <<= 1; } - block_desc *bd = (block_desc*) ofm_malloc(sizeof(block_desc)); + bd = (block_desc*) ofm_malloc(sizeof(block_desc)); + if (!bd) { + os_free_pages(r, this_block_size); + return NULL; + } bd->block = r; bd->free = ps; bd->size = this_block_size; @@ -151,8 +160,10 @@ static void *bc_alloc_std_page(BlockCache *bc, int dirty_ok, int expect_mprotect } } else { + block_desc *bd; newbl = 1; - block_desc *bd = bc_alloc_std_block(bg); + bd = bc_alloc_std_block(bg); + if (!bd) return NULL; gclist_add(free_head, &(bd->gclist)); (*size_diff) += bd->size; /* printf("ALLOC BLOCK %i %p %p-%p size %li %p\n", expect_mprotect, bg, bd->block, bd->block + bd->size, bd->size, bd->free); */ From d5045184c91f74067ad370b39250f2785f565da3 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 17 Jul 2011 19:32:43 -0500 Subject: [PATCH 282/746] fix missing argument to format please merge to release branch (cherry picked from commit 2b99c863211b9093ef0307c590268e61ff380826) --- collects/racket/private/class-internal.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/racket/private/class-internal.rkt b/collects/racket/private/class-internal.rkt index 239d11374c..d466b4ce0a 100644 --- a/collects/racket/private/class-internal.rkt +++ b/collects/racket/private/class-internal.rkt @@ -2576,7 +2576,7 @@ (fail "no public method ~a" m))) (for ([m (class/c-absents ctc)]) (when (hash-ref method-ht m #f) - (fail "class already contains public method ~a"))) + (fail "class already contains public method ~a" m))) (for ([m (class/c-inherits ctc)]) (unless (hash-ref method-ht m #f) (fail "no public method ~a" m))) From 71ea3183ba5cb39df3a87f13378cf1400e4bc094 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 15 Jul 2011 18:21:33 -0400 Subject: [PATCH 283/746] Rename `prompt-shown' -> `zero-column!', and use it only in the non-readline reader. Use line reading for ,install!. (Cherry-picked from 3f8bb7a, and edited conflucts because `port-set-next-location!' is not added to the release.) --- collects/xrepl/xrepl.rkt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index 33f631b622..4e619ed757 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -96,7 +96,11 @@ (let-values ([(line col pos) (port-next-location last-output-port)]) (unless (eq? col (if (eq? line last-output-line) last-output-visual-col 0)) (newline)))) -(define (prompt-shown) +(define (zero-column!) + ;; there's a problem whenever there's some printout followed by a read: the + ;; cursor will at column zero, but the port counting will think that it's + ;; still right after the printout; call this function in such cases to adjust + ;; the column to 0. (maybe-new-output-port) ;; if there was a way to change the location of stdout we'd set the column to ;; 0 here... @@ -1021,6 +1025,7 @@ (define expr "(require xrepl)") (define dexpr "(dynamic-require 'xrepl #f)") (define contents (file->string init-file)) + (read-line) ; discard the newline for further input (define (look-for comment-rx expr) (let ([m (regexp-match-positions (format "(?<=\r?\n|^) *;+ *~a *\r?\n *~a *(?=\r?\n|$)" @@ -1030,9 +1035,7 @@ (define existing? (look-for (regexp-quote comment) expr)) (define existing-readline? (look-for "load readline support[^\r\n]*" "(require readline/rep)")) - (define (yes?) - (flush-output) - (begin0 (regexp-match? #rx"^[yY]" (getarg 'string)) (prompt-shown))) + (define (yes?) (flush-output) (regexp-match? #rx"^[yY]" (getarg 'line))) (cond [existing? (printf "; already installed, nothing to do\n") @@ -1187,7 +1190,7 @@ (provide make-command-reader) (define (make-command-reader) (define (plain-reader prefix) ; a plain reader, without readline - (display prefix) (display "> ") (flush-output) + (display prefix) (display "> ") (flush-output) (zero-column!) (let ([in ((current-get-interaction-input-port))]) ((current-read-interaction) (object-name in) in))) (define RL ; no direct dependency on readline @@ -1233,7 +1236,7 @@ (define input (if from-queue? (begin0 (car more-inputs) (set! more-inputs (cdr more-inputs))) - (begin (fresh-line) (begin0 (reader (get-prefix)) (prompt-shown))))) + (begin (fresh-line) (reader (get-prefix))))) (syntax-case input () [(uq cmd) (eq? 'unquote (syntax-e #'uq)) (let ([r (run-command (syntax->datum #'cmd))]) From c1a82bf23e8d6657e962af74ae313fb7a8bb217e Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 16 Jul 2011 01:22:19 -0400 Subject: [PATCH 284/746] Use (banner) instead of a fixed "Welcome to Racket" in the More tutorial and in the guide. Also, add a tag to the readline "License Issues" to be able to link to it from the xrepl docs. (cherry picked from commit 45394bb7b6b35af7151a691631b3984a386a531f) --- collects/readline/readline.scrbl | 2 +- collects/scribblings/guide/running.scrbl | 2 +- collects/scribblings/more/more.scrbl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/readline/readline.scrbl b/collects/readline/readline.scrbl index f61731bc89..ba836d00f6 100644 --- a/collects/readline/readline.scrbl +++ b/collects/readline/readline.scrbl @@ -241,7 +241,7 @@ from @racketmodname[ffi/unsafe], determines the type of value supplied to the @racket[proc].} -@section{License Issues} +@section[#:tag "readline-license"]{License Issues} GNU's @|readline| library is covered by the GPL, and that applies to code that links with it. Racket is licensed with the LGPL, so the diff --git a/collects/scribblings/guide/running.scrbl b/collects/scribblings/guide/running.scrbl index e2b8985c57..081e8b446a 100644 --- a/collects/scribblings/guide/running.scrbl +++ b/collects/scribblings/guide/running.scrbl @@ -34,7 +34,7 @@ confguration options, like @Flag{j}), then it starts a @tech{REPL} with a @litchar{> } prompt: @verbatim[#:indent 2]{ - Welcome to Racket + @(regexp-replace #rx"\n+$" (banner) "") > } diff --git a/collects/scribblings/more/more.scrbl b/collects/scribblings/more/more.scrbl index 52ed6fccec..ce9df39e19 100644 --- a/collects/scribblings/more/more.scrbl +++ b/collects/scribblings/more/more.scrbl @@ -75,7 +75,7 @@ start @exec{racket} with no command-line arguments: @verbatim[#:indent 2]{ $ racket - Welcome to Racket + @(regexp-replace #rx"\n+$" (banner) "") > } From e0a96d3e7e6794efbb469eca11019ff62b467b3e Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 18 Jul 2011 12:30:11 -0400 Subject: [PATCH 285/746] Typo in the `errortrace' language description. (cherry picked from commit 50b74c453ff4b78c8d84d0d6912d6b3ca2ec6848) --- collects/errortrace/scribblings/errortrace.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/errortrace/scribblings/errortrace.scrbl b/collects/errortrace/scribblings/errortrace.scrbl index 3b3d9d590c..a09da34c80 100644 --- a/collects/errortrace/scribblings/errortrace.scrbl +++ b/collects/errortrace/scribblings/errortrace.scrbl @@ -100,7 +100,7 @@ top-level. The functions also can be accessed by importing handlers. As a language name, @racketmodname[errortrace] chains to another -language that is specified immediately after @racketmodname[at-exp], +language that is specified immediately after @racketmodname[errortrace], but instruments the module for debugging in the same way as if @racketmodname[errortrace] is required before loading the module from source. Using the @racketmodname[errortrace] meta-language is one way From 8d0db4cd35a86a0b629a37736a0571704c2752f2 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 18 Jul 2011 13:33:09 -0400 Subject: [PATCH 286/746] Lots of improvements: * Rename `make-command-{reader,evaluator}' -> `make-xrepl-{reader,evaluator}' * Move the commented-out ,meta block to a better place * Protect the prompt computation against errors, to avoid infinite exception output if an exception is raised. * Add ",switch ?" to query namespaces, and ",switch - " to remove one. Forbid resetting the default initial `*' namespace. * Clarify that multiple arguments can be sent to ,stx and fix it to display the current syntax when there are no arguments. * Various minor typos and improvements. * Restore the use-last-arguments-by-default functionality of ,rr * Re-do argument reading to make it easier to have a default argument (as in ,enter and ,edit). (cherry picked from commit c57ab7b4fcb8952114b2991d732a087ca6412a64) --- collects/xrepl/main.rkt | 4 +- collects/xrepl/xrepl.rkt | 288 ++++++++++++++++++++++++--------------- 2 files changed, 177 insertions(+), 115 deletions(-) diff --git a/collects/xrepl/main.rkt b/collects/xrepl/main.rkt index d4a285c32b..3a70c4f70f 100644 --- a/collects/xrepl/main.rkt +++ b/collects/xrepl/main.rkt @@ -9,5 +9,5 @@ ;; (compile-enforce-module-constants #f) ;; create the command repl reader, and value-saving evaluator -(current-prompt-read (make-command-reader)) -(current-eval (make-command-evaluator (current-eval))) +(current-prompt-read (make-xrepl-reader)) +(current-eval (make-xrepl-evaluator (current-eval))) diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index 4e619ed757..935a0eabe7 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -16,6 +16,8 @@ ;; ---------------------------------------------------------------------------- ;; utilities +(define home-dir (find-system-path 'home-dir)) + ;; autoloads: avoid loading a ton of stuff to minimize startup penalty (define autoloaded-specs (make-hasheq)) (define (autoloaded? sym) (hash-ref autoloaded-specs sym #f)) @@ -161,20 +163,35 @@ (let ([ch (peek-char)]) (if (memq ch skip) (begin (read-char) (loop)) ch))))) -(define (getarg kind [flag 'req]) +(define (here-path) + (let ([x (here-source)]) (if (path? x) x eof))) +(define (here-mod-or-eof) + (let ([x (here-source)]) + (if (not x) + eof + (datum->syntax #f + (cond [(symbol? x) (and (module-name? x) `',x)] + [(path? x) (let ([s (path->string x)]) + (if (absolute-path? x) `(file ,s) s))] + [else (error 'here-mod-or-eof "internal error: ~s" x)]))))) + +(define (getarg kind [flag 'req] #:default [dflt #f]) (define (argerror fmt . args) (apply cmderror #:default-who 'getarg fmt args)) (define (missing) (argerror "missing ~a argument" kind)) (define (get read) - (let loop ([flag flag]) - (case flag - [(req) (let ([x (if (eq? #\newline (skip-spaces/peek)) eof (read))]) - (if (eof-object? x) (missing) x))] - [(opt) (and (not (eq? #\newline (skip-spaces/peek))) (loop 'req))] - [(list) (let ([x (loop 'opt)]) - (if x (cons x (loop 'list)) '()))] - [(list+) (cons (loop 'req) (loop 'list))] - [else (error 'getarg "unknown flag: ~e" flag)]))) + (define 1st (if (eq? #\newline (skip-spaces/peek)) eof (read))) + (define 1st? (not (eof-object? 1st))) + (define (dflt*) (let ([r (dflt)]) (if (eof-object? r) (missing) r))) + (case flag + [(req opt) (cond [1st? 1st] [dflt (dflt*)] + [(eq? 'opt flag) #f] [else (missing)])] + [(list list+) + (define (more) + (if (eq? #\newline (skip-spaces/peek)) '() (cons (read) (more)))) + (cond [1st? (cons 1st (more))] [dflt (list (dflt*))] + [(eq? 'list flag) '()] [else (missing)])] + [else (error 'getarg "unknown flag: ~e" flag)])) (define (read-string-arg) (define ch (skip-spaces/peek " \t\r\n")) (let* ([i (current-input-port)] @@ -203,18 +220,12 @@ (and arg (if (memq flag '(list list+)) (map convert arg) (convert arg)))) (let loop ([kind kind]) (case kind - [(line) (get read-line-arg)] - [(string) (get read-string-arg)] - [(path) (translate (loop 'string) expand-user-path)] - [(path*) (if (eq? flag 'list) - (let ([args (getarg 'path 'list)]) - (if (pair? args) - args - (let ([x (here-source)]) (if (path? x) (list x) '())))) - (error 'getarg "'path* must always be used with 'list"))] - [(sexpr) (get read)] - [(syntax) (translate (get read-syntax) namespace-syntax-introduce)] - [(modspec) (translate (loop 'syntax) process-modspec)] + [(line) (get read-line-arg)] + [(string) (get read-string-arg)] + [(path) (translate (loop 'string) expand-user-path)] + [(sexpr) (get read)] + [(syntax) (translate (get read-syntax) namespace-syntax-introduce)] + [(modspec) (translate (loop 'syntax) process-modspec)] [else (error 'getarg "unknown arg kind: ~e" kind)]))) (define (run-command cmd) @@ -276,14 +287,14 @@ ["Sets `current-directory'; expands user paths. With no arguments, goes" "to your home directory. An argument of `-' indicates the previous" "directory."] - (let* ([arg (or (getarg 'path 'opt) (find-system-path 'home-dir))] + (let* ([arg (or (getarg 'path 'opt) home-dir)] [arg (if (equal? arg (string->path "-")) (cdr (last-2dirs)) arg)]) (if (directory-exists? arg) (begin (current-directory arg) (report-directory-change 'cd)) (eprintf "cd: no such directory: ~a\n" arg)))) (defcommand pwd #f - "read the current directory" + "display the current directory" ["Displays the value of `current-directory'."] (report-directory-change 'pwd)) @@ -319,13 +330,14 @@ (string-append "$EDITOR ("env") not found in your path") "no $EDITOR variable")) (run-command 'drracket)] - [(not (apply system* exe (getarg 'path* 'list))) + [(not (apply system* exe (getarg 'path 'list #:default here-path))) (eprintf "(exit with an error status)\n")] [else (void)])) (define ->running-dr #f) (define (->dr . xs) (unless ->running-dr (start-dr)) (->running-dr xs)) (define (start-dr) + (printf "; starting DrRacket...\n") (define c (make-custodian)) (define ns ((dynamic-require 'racket/gui 'make-gui-namespace))) (parameterize ([current-custodian c] @@ -441,7 +453,7 @@ "* -quit: exits the running instance. Quitting the application as usual" " will only close the visible window, but it will still run in a hidden" " window. This command should not be needed under normal circumstances."] - (let ([args (getarg 'path* 'list)]) + (let ([args (getarg 'path 'list #:default here-path)]) (if (null? args) (->dr 'new) (let* ([cmd (let ([s (path->string (car args))]) @@ -455,7 +467,7 @@ (defcommand (apropos ap) " ..." "look for a binding" - ["Additional string arguments restrict matches shown. The search specs can" + ["Additional arguments restrict the shown matches. The search specs can" "have symbols (which specify what to look for in bound names), and regexps" "(for more complicated matches)."] (let* ([look (map (λ (s) (cond [(symbol? s) @@ -619,16 +631,20 @@ (define rr-modules (make-hash)) ; hash to remember reloadable modules -(defcommand (require-reloadable reqr rr) " ...+" +(define last-rr-specs '()) + +(defcommand (require-reloadable reqr rr) " ..." "require a module, make it reloadable" ["Same as ,require but the module is required in a way that makes it" "possible to reload later. If it was already loaded then it is reloaded." "Note that this is done by setting `compile-enforce-module-constants' to" "#f, which prohibits some optimizations."] + (let ([s (getarg 'modspec 'list)]) (when (pair? s) (set! last-rr-specs s))) + (when (null? last-rr-specs) (cmderror "missing modspec arguments")) (parameterize ([compile-enforce-module-constants (compile-enforce-module-constants)]) (compile-enforce-module-constants #f) - (for ([spec (in-list (getarg 'modspec 'list+))]) + (for ([spec (in-list last-rr-specs)]) (define datum (syntax->datum spec)) (define resolved ((current-module-name-resolver) datum #f #f #f)) (define path (resolved-module-path-name resolved)) @@ -645,14 +661,17 @@ (define enter!-id (make-lazy-identifier 'enter! 'racket/enter)) -(defcommand (enter en) "[] [noisy?]" +(defcommand (enter en) "[] [noisy?]" "require a module and go into its namespace" - ["Uses `enter!' to go into the module's namespace; the module name is" - "optional, without it you go back to the toplevel. A module name can" - "specify an existing file as with the ,require command. (Note that this" + ["Uses `enter!' to go into the module's namespace. A module name can" + "specify an existing file as with the ,require command. If no module is" + "given, and the REPL is already in some module's namespace, then `enter!'" + "is used with that module, causing it to reload if needed. (Note that this" "can be used even in languages that don't have the `enter!' binding.)"] - (eval-sexpr-for-user `(,(enter!-id) ,(getarg 'modspec) - #:dont-re-require-enter))) + (eval-sexpr-for-user `(,(enter!-id) + ,(getarg 'modspec #:default here-mod-or-eof) + ,@(getarg 'syntax 'list) + #:dont-re-require-enter))) (defcommand (toplevel top) #f "go back to the toplevel" @@ -661,7 +680,7 @@ (defcommand (load ld) " ..." "load a file" - ["Uses `load' to load the specified file(s)"] + ["Uses `load' to load the specified file(s)."] (more-inputs* (map (λ (name) #`(load #,name)) (getarg 'path 'list)))) ;; ---------------------------------------------------------------------------- @@ -684,9 +703,9 @@ "little easier to read information. You can provide an initial number" "that specifies how many times to run the expression -- in this case," "the expression will be executed that many times, extreme results are" - "be removed (top and bottom 2/7ths), and the remaining results will" - "be averaged. Two garbage collections are triggered before each run;" - "the resulting value(s) are from the last run."] + "removed (top and bottom 2/7ths), and the remaining results will be" + "averaged. Two garbage collections are triggered before each run; the" + "resulting value(s) are from the last run."] (more-inputs #`(#,(time-id) #,@(getarg 'syntax 'list)))) (define trace-id (make-lazy-identifier 'trace 'racket/trace)) @@ -759,7 +778,7 @@ " * : show profiling results by time" " # : show profiling results by counts" " ! : clear profiling results" - " Multiple commands can be combined, for example \",prof *!-\" will show" + " Multiple flags can be combined, for example \",prof *!-\" will show" " profiler results, clear them, and turn it off." "* With no arguments, turns the errortrace profiler on if it's off, and if" " it's on it shows the collected results and clears them." @@ -844,7 +863,7 @@ [t (make-hasheq)]) (hash-set! t (current-namespace-name) (cons (current-namespace) r)) t)) -(defcommand (switch-namespace switch) "[] [! []]" +(defcommand (switch-namespace switch) "[] [? | - | ! []]" "switch to a different repl namespace" ["Switch to the namespace, creating it if needed. The of a" "namespace is a symbol or an integer where a `*' indicates the initial one;" @@ -854,7 +873,9 @@ "that was used for the current namespace. If `! ' is used, it" "indicates that a new namespace will be created even if it exists, using" "`' as the initial module, and if just `!' is used, then this happens" - "with the existing namespace's init or with the current one's." + "with the existing namespace's init or with the current one's. You can" + "also use `-' and a name to drop the corresponding namespace (allowing it" + "to be garbage-collected), and `?' to list all known namespaces." "A few examples:" " ,switch ! reset the current namespace" " ,switch ! racket reset it using the `racket' language" @@ -863,53 +884,85 @@ " ,switch foo ! racket switch to newly made `foo', even if it exists" " ,switch foo ! same, but using the same as it was created" " with, or same as the current if it's new" + " ,switch ? list known namespaces, showing the above two" + " ,switch - r5rs drop the `r5rs' namespace" "(Note that you can use `^' etc to communicate values between namespaces.)"] - (define-values (name force-reset? init) - (match (getarg 'sexpr 'list) - [(list '!) (values #f #t #f )] - [(list '! init) (values #f #t init)] - [(list name) (values name #f #f )] - [(list name '!) (values name #t #f )] - [(list name '! init) (values name #t init)] - [(list) (cmderror "what do you want to do?")] - [_ (cmderror "syntax error, see ,help switch-namespace")])) - (unless (or (not name) (symbol? name) (fixnum? name)) - (cmderror "bad namespace name, must be symbol or fixnum")) - (define old-namespace (current-namespace)) - (define (is-require-able? name) - (with-handlers ([void (λ (_) #f)]) - ;; name is not a string => no need to set the current directory - (file-exists? (modspec->path name)))) - ;; if there's an , then it must be forced - (let* ([name (or name (current-namespace-name))] - [init - (cond [init] - [(or force-reset? (not (hash-ref namespaces name #f))) - (cdr (or (hash-ref namespaces name #f) - (and (is-require-able? name) (cons #f name)) - (hash-ref namespaces (current-namespace-name) #f) - ;; just in case - (hash-ref namespaces default-namespace-name #f)))] - [else #f])]) - (when init - (printf "*** ~a `~s' namespace with ~s ***\n" - (if (hash-ref namespaces name #f) - "Resetting the" "Initializing a new") - name - (->relname init)) - (current-namespace (make-base-empty-namespace)) - (namespace-require init) - (hash-set! namespaces name (cons (current-namespace) init)))) - (when (and name (not (eq? name (current-namespace-name)))) - (printf "*** switching to the `~s' namespace ***\n" name) - (let ([x (hash-ref namespaces (current-namespace-name))]) - (unless (eq? (car x) old-namespace) - (printf "*** (note: saving current namespace for `~s')\n" - (current-namespace-name)) - (hash-set! namespaces (current-namespace-name) - (cons old-namespace (cdr x))))) - (current-namespace-name name) - (current-namespace (car (hash-ref namespaces name))))) + (define (list-namespaces) + (printf "; namespaces and their languages:\n") + (define nss (sort (map (λ (x) (cons (format "~s" (car x)) (cddr x))) + (hash-map namespaces cons)) + string no need to set the current directory + (file-exists? (modspec->path name)))) + ;; if there's an , then it must be forced + (let* ([name (or name (current-namespace-name))] + [init + (cond [init] + [(or force-reset? (not (hash-ref namespaces name #f))) + (when (eq? name default-namespace-name) + ;; no deep reason for this, but might be usful to keep it + ;; possible to ,en xrepl/xrepl to change options etc + (cmderror "cannot reset the default namespace")) + (cdr (or (hash-ref namespaces name #f) + (and (is-require-able? name) (cons #f name)) + (hash-ref namespaces (current-namespace-name) #f) + ;; just in case + (hash-ref namespaces default-namespace-name #f)))] + [else #f])]) + (when init + (printf "; *** ~a `~s' namespace with ~s ***\n" + (if (hash-ref namespaces name #f) + "Resetting the" "Initializing a new") + name + (->relname init)) + (current-namespace (make-base-empty-namespace)) + (namespace-require init) + (hash-set! namespaces name (cons (current-namespace) init)))) + (when (and name (not (eq? name (current-namespace-name)))) + (printf "; *** switching to the `~s' namespace ***\n" name) + (let ([x (hash-ref namespaces (current-namespace-name))]) + (unless (eq? (car x) old-namespace) + (printf "; (note: saving current namespace for `~s')\n" + (current-namespace-name)) + (hash-set! namespaces (current-namespace-name) + (cons old-namespace (cdr x))))) + (current-namespace-name name) + (current-namespace (car (hash-ref namespaces name))))) + (define (syntax-error) + (cmderror "syntax error, see ,help switch-namespace")) + (match (getarg 'sexpr 'list) + [(list) (cmderror "what do you want to do?")] + [(list '?) (list-namespaces)] + [(list '? _ ...) (syntax-error)] + [(list '- name) (delete name)] + [(list '- _ ...) (syntax-error)] + [(list '!) (switch #f #t #f )] + [(list '! init) (switch #f #t init)] + [(list name) (switch name #f #f )] + [(list name '!) (switch name #t #f )] + [(list name '! init) (switch name #t init)] + [_ (syntax-error)])) ;; ---------------------------------------------------------------------------- ;; syntax commands @@ -931,13 +984,17 @@ ["With no arguments, will show the previously set (or expanded) syntax" "additional arguments serve as an operation to perform:" "- `^' sets the syntax from the last entered expression" + "- other sexprs set the current syntax explicitly" "- `+' will `expand-once' the syntax and show the result (can be used again" " for additional `expand-once' steps)" "- `!' will `expand' the syntax and show the result" "- `*' will use the syntax stepper to show expansion steps, leaving macros" " from racket/base intact (does not change the currently set syntax)" - "- `**' similar to `*', but expanding everything"] - (for ([stx (in-list (getarg 'syntax 'list))]) + "- `**' similar to `*', but expanding everything" + "Note that you can specify several syntaxes and operations in a single" + "invocation."] + (define args (getarg 'syntax 'list)) + (for ([stx (in-list (if (null? args) '(#f) args))]) (define (show/set label stx) (printf "~a\n" label) (current-syntax stx) @@ -957,23 +1014,6 @@ (begin (printf "syntax set\n") (current-syntax stx)) (cmderror "internal error: ~s ~s" stx (syntax? stx)))]))) -;; ---------------------------------------------------------------------------- -;; meta evaluation hook - -;; questionable value, (and need to display the resulting values etc) -#; -(defcommand meta "" - "meta evaluation" - ["Evaluate the given expression where bindings are taken from the xrepl" - "module. This is convenient when you're in a namespace that does not have" - "a specific binding -- for example, you might be using a language that" - "doesn't have `current-namespace', so to get it, you can use" - "`,eval (current-namespace)'. The evaluation happens in the repl namespace" - "as usual, only the bindings are taken from the xrepl module -- so you can" - "use `^' to refer to the result of such an evaluation."] - (eval (datum->syntax #'here `(#%top-interaction . ,(getarg 'sexpr)))) - (void)) - ;; ---------------------------------------------------------------------------- ;; dynamic log output control @@ -1011,6 +1051,23 @@ (flush-output)]) (loop)))))))) +;; ---------------------------------------------------------------------------- +;; meta evaluation hook + +;; questionable value, (and need to display the resulting values etc) +#; +(defcommand meta "" + "meta evaluation" + ["Evaluate the given expression where bindings are taken from the xrepl" + "module. This is convenient when you're in a namespace that does not have" + "a specific binding -- for example, you might be using a language that" + "doesn't have `current-namespace', so to get it, you can use" + "`,eval (current-namespace)'. The evaluation happens in the repl namespace" + "as usual, only the bindings are taken from the xrepl module -- so you can" + "use `^' to refer to the result of such an evaluation."] + (eval (datum->syntax #'here `(#%top-interaction . ,(getarg 'sexpr)))) + (void)) + ;; ---------------------------------------------------------------------------- ;; setup xrepl in the user's racketrc file @@ -1129,8 +1186,8 @@ (namespace-set-variable-value! id (void)))) (when res (save-values! res))))) -(provide make-command-evaluator) -(define (make-command-evaluator builtin-evaluator) +(provide make-xrepl-evaluator) +(define (make-xrepl-evaluator builtin-evaluator) (λ (expr) ;; not useful: catches only escape continuations ;; (with-handlers ([exn:break? (λ (e) (last-break-exn e) (raise e))]) ...) @@ -1141,7 +1198,6 @@ ;; ---------------------------------------------------------------------------- ;; capture ",..." and run the commands, use readline/rep when possible -(define home-dir (expand-user-path "~")) (define get-prefix ; to show before the "> " prompt (let () (define (choose-path x) @@ -1175,7 +1231,13 @@ (unless (and (equal? (current-namespace) last-namespace) (equal? curdir last-directory)) (report-directory-change) - (set! prefix (get-prefix)) + (set! prefix + (with-handlers + ([exn? (λ (e) + (eprintf "error during prompt calculation: ~a\n" + (exn-message e)) + "[internal-error]")]) + (get-prefix))) (set! last-namespace (current-namespace)) (set! last-directory curdir)) prefix))) @@ -1187,8 +1249,8 @@ #:constructor-name more-inputs* #:omit-define-syntaxes) (define (more-inputs . inputs) (more-inputs* inputs)) -(provide make-command-reader) -(define (make-command-reader) +(provide make-xrepl-reader) +(define (make-xrepl-reader) (define (plain-reader prefix) ; a plain reader, without readline (display prefix) (display "> ") (flush-output) (zero-column!) (let ([in ((current-get-interaction-input-port))]) From f8974781fef1cecfb3173491c3074ca60b4a1d3b Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 18 Jul 2011 13:43:31 -0400 Subject: [PATCH 287/746] XREPL documentation. (cherry picked from commit d7c14cbd3fd3efa675a29955fdfd912ba16c23ea) --- collects/xrepl/doc-utils.rkt | 80 ++++++ collects/xrepl/info.rkt | 2 + collects/xrepl/xrepl.scrbl | 484 +++++++++++++++++++++++++++++++++++ 3 files changed, 566 insertions(+) create mode 100644 collects/xrepl/doc-utils.rkt create mode 100644 collects/xrepl/xrepl.scrbl diff --git a/collects/xrepl/doc-utils.rkt b/collects/xrepl/doc-utils.rkt new file mode 100644 index 0000000000..fe15ecd335 --- /dev/null +++ b/collects/xrepl/doc-utils.rkt @@ -0,0 +1,80 @@ +#lang racket/base + +(require scribble/manual scribble/core scribble/decode + racket/list racket/sandbox) + +(provide (all-from-out scribble/manual) + RL GUIDE cmd defcmd check-all-documented) + +(define RL '(lib "readline/readline.scrbl")) +(define GUIDE '(lib "scribblings/guide/guide.scrbl")) + +(define commands + (let ([c #f]) + (λ () + (unless c + (define e (call-with-trusted-sandbox-configuration + (λ () (make-evaluator 'racket/base)))) + (e '(require xrepl/xrepl)) + (e '(current-namespace (module->namespace 'xrepl/xrepl))) + (set! c (e '(for/list ([c (in-list commands-list)]) + (list (car (command-names c)) + (cdr (command-names c)) + (command-argline c) + (command-blurb c))))) + (kill-evaluator e)) + c))) +(define documented '()) + +(define (cmd* name0 . more) + (define name (if (symbol? name0) name0 (string->symbol name0))) + (define full-name + (or (and (assq name (commands)) name) + (for/or ([c (in-list (commands))]) (and (memq name (cadr c)) (car c))) + (error 'cmd "unknown command: ~s" name))) + (define content + (litchar (let ([s (format ",~a" name)]) + (if (pair? more) (apply string-append s " " more) s)))) + (link-element "plainlink" content `(xrepl ,(format "~a" full-name)))) + +(define-syntax-rule (cmd name more ...) (cmd* 'name more ...)) + +(define (cmd-index name) + (define namestr (format ",~a" name)) + (define tag `(xrepl ,(format "~a" name))) + (define content (cmd* name)) + (define ielem + (index-element #f content tag (list namestr) (list content) + 'xrepl-command)) + (toc-target-element #f (list ielem) tag)) + +(define (defcmd* name . text) + (set! documented (cons name documented)) + (define-values [other-names argline blurb] + (apply values (cond [(assq name (commands)) => cdr] + [else (error 'defcmd "unknown command: ~s" name)]))) + (define header + (list (cmd-index name) (litchar (string-append " " (or argline ""))))) + (define desc + (list (hspace 2) (make-element 'italic blurb))) + (define synonyms + (and (pair? other-names) + (list (hspace 2) + "[Synonyms: " + (add-between (map (λ (n) (litchar (format ",~a" n))) + other-names) + " ") + "]"))) + (splice + (list* (tabular #:style 'boxed `((,header) (,desc) + ,@(if synonyms `((,synonyms)) `()))) + "\n" "\n" text))) + +(define-syntax-rule (defcmd name text ...) (defcmd* 'name text ...)) + +(define (check-all-documented) + (unless (= (length documented) (length (remove-duplicates documented))) + (error 'xrepl-docs "some commands were documented multiple times")) + (let ([missing (remove* documented (map car (commands)))]) + (when (pair? missing) + (error 'xrepl-docs "missing command documentation: ~s" missing)))) diff --git a/collects/xrepl/info.rkt b/collects/xrepl/info.rkt index dd70b324f1..96e8ea9a85 100644 --- a/collects/xrepl/info.rkt +++ b/collects/xrepl/info.rkt @@ -1,3 +1,5 @@ #lang setup/infotab (define name "eXtended REPL") + +(define scribblings '(("xrepl.scrbl" () (tool-library)))) diff --git a/collects/xrepl/xrepl.scrbl b/collects/xrepl/xrepl.scrbl new file mode 100644 index 0000000000..f934492caf --- /dev/null +++ b/collects/xrepl/xrepl.scrbl @@ -0,0 +1,484 @@ +#lang scribble/doc +@(require scribble/manual "doc-utils.rkt" + scribble/decode (only-in scribble/core) + (for-label racket readline racket/help racket/enter + racket/trace profile)) + +@title{XREPL: eXtended REPL} +@author+email["Eli Barzilay" "eli@barzilay.org"] + +@defmodule[xrepl]{ + The @filepath{xrepl} collection extends the @exec{racket} @tech[#:doc + GUIDE]{REPL} significantly, turning it into a more useful tool for + interactive exploration and development. This includes ``meta + commands'', using readline, keeping past evaluation results, and + more.} + +@; --------------------------------------------------------------------- +@section{Installing XREPL} + +To use XREPL, start @exec{racket} and enter @racket[(require xrepl)]. +You will know that it works when the prompt changes to a @litchar{->}, +and, if you're working on a capable terminal, you will now have readline +editing. You can also start @exec{racket} and ask for XREPL to be +loaded using command-line arguments: +@commandline{racket -il xrepl} + +If you want to enable XREPL automatically, add this expression to your +Racket initialization file. +@margin-note*{To load XREPL conditionally (e.g., not in older Racket + versions), you can use @racket[(dynamic-require 'xrepl #f)]. This + is a plain expression that can be placed inside @racket[when] and + elsewhere.} +An easy way to do the necessary editing is to enter @cmd[install!], +which will inspect and edit your initialization file (it will describe +the change and ask for your permission). Alternatively, you can edit +the file directly: on Unix, it is @filepath{~/.racketrc}, and for +other platforms evaluate @racket[(find-system-path 'init-file)] to see +where it is. + +XREPL will set up a readline-based reader, so you do not need to load +that yourself. If your initialization file was previously set to load +readline via @racket[install-readline!], the @cmd[install!] command +will (notify you and) remove it. If you added it yourself, consider +removing it. (This is not strictly needed, but XREPL is slightly +better at detecting when to use readline.) + +@; --------------------------------------------------------------------- +@section{Meta REPL Commands} + +Most of the XREPL extensions are implemented as meta commands. These +commands are entered at the REPL, prefixed by a @litchar{,} and followed +by the command name. Note that several commands correspond directly to +Racket functions (e.g., @cmd[exit]) --- but since they work outside of +your REPL, they can be used even if the matching bindings are not +available. + +@; --------------------------------- +@subsection{Generic Commands} + +@defcmd[help]{ + Without an argument, displays a list of all known commands. Specify a + command to get help specific to that command. +} + +@defcmd[exit]{ + Exits Racket, optionally with an error code (see @racket[exit]). +} + +@defcmd[cd]{ + Sets the @racket[current-directory] to the given path. If no path is + specified, use your home directory. Path arguments are passed through + @racket[expand-user-path] so you can use @litchar{~}. An argument of + @litchar{-} means ``the previous path''. +} + +@defcmd[pwd]{ + Reports the value of @racket[current-directory]. +} + +@defcmd[shell]{ + Use @cmd[shell] (or @cmd[sh]) to run a generic shell command (via + @racket[system]). For convenience, a few synonyms are provided --- + they run the specified executables (still using @racket[system]). +} + +@defcmd[edit]{ + Runs an editor, as specified by your @envvar{EDITOR} environment + variable, with the given file/s arguments. If no files are specified + and the REPL is currently inside a module's namespace, then the file + for that module is used. If the @envvar{EDITOR} environment variable + is not set, use the @cmd[drracket] command instead. +} + +@defcmd[drracket]{ + Runs DrRacket with the specified file/s. If no files are given, and + the REPL is currently inside a module, the file for that module is + used. + + DrRacket is launched directly, without starting a new subprocess, and + it is then kept running in a hidden window so further invocations are + immediate. (When this command is used for the first time, you will + see DrRacket start as usual, and then its window will disappear --- + that window is keeping DrRacket ready for quick editing.) + + In addition to file arguments, arguments can specify one of a few + flags for additional operations: + @itemize[ + @item{@litchar{-new}: opens a new editing window. This is the default + when no files are given and the REPL is not inside a module,} + @item{@litchar{-open}: opens the specified file/s (or the current + module's file). This is the default when files are given or when + inside a module.} + @item{@litchar{-quit}: exits the running DrRacket instance. Quitting + DrRacket is usually not necessary. Therefore, if you try to quit it + from the DrRacket window, it will instead just close the window but + DrRacket will still be running in the background. Use this command + in case there is some exceptional problem that requires actually + quitting the IDE. (Once you do so, future uses of this command will + start a fresh instance.)}] +} + +@; --------------------------------- +@subsection{Binding Information} + +@defcmd[apropos]{ + Searches for known bindings in the current namespace. The arguments + specify which binding to look for: use a symbol (without a + @litchar{'}) to look for bindings that contain that name, and use a + regexp (e.g., @racket[#rx"..."]) to use a regexp for the search. + Multiple arguments are and-ed together. + + If no arguments are given, @emph{all} bindings are listed. +} + +@defcmd[describe]{ + For each of the specified names, describe where where it is coming + from and how it was defined if it names a known binding. In addition, + desribe the module (list its imports and exports) that is named by + arguments that are known module names. + + By default, bindings are searched for at the runtime level (phase 0). + You can add a different phase level for identifier lookups as a first + argument. In this case, only a binding can be described, even if the + same name is a known module. +} + +@defcmd[doc]{ + Uses Racket's @racket[help] to browse the documentation, look for a + binding, etc. Note that this can be used even in languages that don't + have the @racket[help] binding. +} + +@; --------------------------------- +@subsection{Requiring and Loading Files} + +@defcmd[require]{ + Most arguments are passed to @racket[require] as is. As a + convenience, if an argument specifies an existing file name, then use + its string form to specify the require, or use a @racket[file] in case + of an absolute path. In addition, an argument that names a known + symbolic module name (e.g., one that was defined on the REPL, or a + builtin module like @racket[#%network]), then its quoted form is used. + (Note that these shorthands do not work inside require subforms like + @racket[only-in].) +} + +@defcmd[require-reloadable]{ + Same as @cmd[require], but arranges to load the code in a way that + makes it possible to reload it later, or if a module was already + loaded (using this command) then reload it. Note that the arguments + should be simple specifications, without any require macros. If no + arguments are given, use arguments from the last use of this command + (if any). + + Module reloading is enabled by turnning off the + @racket[compile-enforce-module-constants] parameter --- note that this + prohibits some opimizations, since the compiler assumes that all + bindings may change. +} + +@defcmd[enter]{ + Uses @racket[enter!] to have the REPL go `inside' a given module's + namespace. A module name can specify an existing file as with the + @cmd[require-reloadable] command. If no module is given, and the REPL + is already in some module's namespace, then `enter!' is used with that + module, causing it to reload if needed. Using @racket[#f] makes it go + back to the toplevel namespace. + + Note that this can be used even in languages that don't have the + @racket[enter!] binding. In addition, @racket[enter!] is used in a + way that does not make it require itself into the target namespace. +} + +@defcmd[toplevel]{ + Makes the REPL go back to the toplevel namespace. Same as using the + @cmd[enter] command with a @racket[#f] argument. +} + +@defcmd[load]{ + Uses @racket[load] to load the specified file(s). +} + +@; --------------------------------- +@subsection{Debugging} + +@defcmd[time]{ + Times execution of an expression (or expressions). This is similar to + @racket{time} but the information that is displayed is a bit easier to + read. + + In addition, you can provide an initial number to specify repeating + the evaluation a number of times. In this case, each iteration is + preceded by two garbage collections, and when the iteration is done + its timing information and evaluation result(s) are displayed. When + the requested number of repetitions is done, some extreme results are + removed (top and bottom 2/7ths), and the remaining results are be + averaged. Finally, the resulting value(s) are from the last run are + returned (and can be accessed via the bindings for the last few + results, see @secref["past-vals"]). +} + +@defcmd[trace]{ + Traces the named function (or functions), using @racket[trace]. +} + +@defcmd[untrace]{ + Untraces the named function (or functions), using @racket[untrace]. +} + +@defcmd[errortrace]{ + @racketmodname[errortrace] is a useful Racket library which can + provide a number of useful services like precise profiling, test + coverage, and accurate error information. However, using it can be a + little tricky. @cmd[errortrace] and a few related commands fill this + gap, making @racketmodname[errortrace] easier to use. + + @cmd[errortrace] controls global use of @racketmodname[errortrace]. + With a flag argument of @litchar{+} errortrace instrumentation is + turned on, with @litchar{-} it is turned off, and with no arguments it + is toggled. In addition, a @litchar{?} flag displays instrumentation + state. + + Remember that @racketmodname[errortrace] instrumentation hooks into + the Racket compiler, and applies only to source code that gets loaded + from source and therefore compiled. Therefore, you should use it + @emph{before} loading the code that you want to instrument. +} + +@defcmd[profile]{ + This command can perform profiling of code in one of two very + different ways: either statistical profiling via the + @racketmodname[profile] library, or using the exact profiler feature + of @racketmodname[errortrace]. + + When given a parenthesized expression, @cmd[profile] will run it via + the statistical profiler, as with the @racket[profile] form, reporting + results as usual. This profiler adds almost no overhead, and it + requires no special setup. In particular, it does not require + pre-compiling code in a special way. However, there are some + imprecise elements to this profiling: the profiler samples stack + snapshots periodically which can miss certain calls, and it is also + sensitive to some compiler optimizations like inlining procedures and + thereby not showing them in the displayed analysis. See + @other-doc['(lib "profile/scribblings/profile.scrbl")] for more + information. + + In the second mode of operation, @cmd[profile] uses the precise + @racketmodname[errortrace] profiler. This profiler produces precise + results, but like other uses of the @racketmodname[errortrace], it + must be enabled before loading the code that is to be profiled. It + can add noticeable overhead (potentially affecting the reported + runtimes), but the results are accurate in the sense that no procedure + is skipped. (For additional details, see + @other-doc['(lib "errortrace/scribblings/errortrace.scrbl")].) + + In this mode, the arguments are flags that control the profiler. A + @litchar{+} flag turns the profiler on --- and as usual with + @racketmodname[errortrace] functionality, this applies to code that is + compiled from now on. A @litchar{-} flag turns this instrumentation + off, and without any flags it is toggled. Once the profiler is + enabled, you can run some code and then use this command to report + profiling results: use @litchar{*} to show profiling results by time, + and @litchar{#} for the results by counts. Once you've seen the + results, you can evaluate additional code to collect more profiling + information, or you can reset the results with a @litchar{!} flag. + You can also combine several flags to perform the associated + operations, for example, @cmd[prof]{*!-} will show the accumulated + results, clear them, and turn profiler instrumentation off. + + Note that using @emph{any} of these flags turns errortrace + instrumentation on, even @cmd[prof]{-} (or no flags). Use the + @cmd[errortrace] command to turn off instrumentation completely. +} + +@defcmd[execution-counts]{ + This command makes it easy to use the execution counts functionality + of @racketmodname[errortrace]. Given a file name (or names), + @cmd[execution-counts] will enable errortrace instrumentation for + coverage, require the file(s), display the results, disables coverage, + and disables instrumentation (if it wasn't previously turned on). + This is useful as an indication of how well the test coverage is for + some file. +} + +@defcmd[coverage]{ + Runs a given file and displays coverage information for the run. This + is somewhat similar to the @cmd[execution-counts] command, but instead + of using @racketmodname[errortrace] directly, it runs the file in a + (trusted) sandbox, using the @racketmodname[racket/sandbox] library + and its ability to provide coverage information. +} + +@; --------------------------------- +@subsection{Miscellaneous Commands} + +@defcmd[switch-namespace]{ + This powerful command controls the REPL's namespace. While + @cmd[enter] can be used to make the REPL go into the namespace of a + specific module, the @cmd[switch-namespace] command can switch between + @emph{toplevel namespaces}, allowing you to get multiple separate + ``workspaces''. + + Namespaces are given names that are symbols or integers, where + @litchar{*} is the name for the first initial namespace, serving as + the default one. These names are not bindings --- they are only used + to label the known namespaces. + + The most basic usage for this command is to simply specify a new name. + A namespace that corresponds to that name will be created and the REPL + will switch to that namespace. The prompt will now indicate this + namespace's name. The name is usually insignificant, except when it + is a @racket[require]-able module: in this case, the new namespace is + initialized to use that module's bindings. For example, + @cmd[switch]{racket/base} creates a new namespace that is called + @litchar{racket/base} and initializes it with + @racketmodname[racket/base]. For all other names, the new namespace + is initialized the same as the current one. + + Additional @cmd[switch] uses: + @itemize[ + @item{@cmd[switch]{!} --- reset the current namespace, recreating it + using the same initial library. Note that it is forbidden to reset + the default initial namespace, the one named @litchar{*} --- this + namespace corresponds to the one that Racket was started with, and + where XREPL was initialized. There is no technical reason for + forbidding this, but doing so is not useful as no resources will + actually be freed.} + @item{@cmd[switch]{! } --- resets the current namespace with + the explicitly given simple module spec.} + @item{@cmd[switch]{ !} --- switch to a newly made namespace. If + a namespace by that name already existed, it is rest.} + @item{@cmd[switch]{ ! } --- same, but reset to the given + module instead of what it previously used.} + @item{@cmd[switch]{- } --- drop the specified namespace, making + it possible to garbage-collect away any associated resources. You + cannot drop the current namespace or the default one (@litchar{*}).} + @item{@cmd[switch]{?} --- list all known namespaces.}] + + Do not confuse namespaces with sandboxes or custodians. The + @cmd{switch} command changes @emph{only} the + @racket[current-namespace] --- it does not install a new custodian or + restricts evaluation in any way. Note that it is possible to pass + around values from one namespace to another via past result reference; + see @secref["past-vals"]. +} + +@defcmd[syntax]{ + Manipulate syntaxes and inspect their expansion. + + Useful operations revolve around a ``currently set syntax''. With no + arguments, the currently set syntax is displayed; an argument of + @litchar{^} sets the current syntax from the last input to the REPL; + and an argument that holds any other s-expression will set it as the + current syntax. + + Syntax operations are specified via flags: + @itemize[ + @item{@litchar{+} uses @racket[expand-once] on the current syntax and + prints the resulting syntax. In addition, the result becomes the + new ``current'' syntax, so you can use this as a poor-man's syntax + stepper. (Note that in some rare cases expansion via a sequence of + @racket[expand-once] might differ from the actual expansion.)} + @item{@litchar{!} uses @racket[expand] to completely expand the + current syntax.} + @item{@litchar{*} uses the macro debugger's textual output to show + expansion steps for the current syntax, leaving macros from + @racketmodname[racket/base] intact. Does not change the current + syntax. + See @other-doc['(lib "macro-debugger/macro-debugger.scrbl")] for + details.} + @item{@litchar{**} uses the macro debugger similarly to @litchar{*}, + but expands @racketmodname[racket/base] macros too, showing the + resulting full expansion process.}] + Several input flags and/or syntaxes can be spacified in succession as + arguments to @cmd{syntax}. For example, @cmd[stx]{(when 1 2) ** !}. +} + +@defcmd[log]{ + Starts (or stops) logging events at a specific level. The level can + be: + @itemize[ + @item{a known level name (currently one of @litchar{fatal}, + @litchar{error}, @litchar{warning}, @litchar{info}, + @litchar{debug}),} + @item{@racket[#f] for no logging,} + @item{@racket[#t] for maximum logging,} + @item{an integer level specification, with @racket[0] for no logging + and bigger ones for additional verbosity.}] +} + +@defcmd[install!]{ + Convenient utility command to install XREPL in your Racket + initialization file. This is done carefully, you will be notified of + potential issues, and asked to authorize changes. +} + +@; --------------------------------------------------------------------- +@section[#:tag "past-vals"]{Past Evaluation Results} + +XREPL makes the last few interaction results available for evaluation +via special toplevel variables: @racketidfont{^}, @racketidfont{^^}, +..., @racketidfont{^^^^^}. The first, @racketidfont{^}, refers to the +last result, @racketidfont{^^} to the previous one and so on. + +As with the usual REPL printouts, @void-const results are not kept. In +case of multiple results, they are spliced in reverse, so +@racketidfont{^} refers to the last result of the last evaluation. For +example: +@verbatim[#:indent 4]{ + -> 1 + 1 + -> (values 2 3) + 2 + 3 + -> (values 4) + 4 + -> (list ^ ^^ ^^^ ^^^^) + '(4 3 2 1)} +The rationale for this is that @racketidfont{^} always refers to the +last @emph{printed} result, @racketidfont{^^} to the one before that, +etc. + +These bindings are made available only if they are not already defined, +and if they are not modified. This means that if you have code that +uses these names, it will continue to work as usual. + +@; --------------------------------------------------------------------- +@section{Hacking XREPL} + +XREPL is mainly a convenience tool, and as such you might want to hack +it to better suite your needs. Currently, there is no convenient way to +customize and extend it, but this will be added in the future. + +Meanwhile, if you're interested in tweaking XREPL, the @cmd[enter] +command can be used as usual to go into its implementation. For +example: +@verbatim[#:indent 4]{ + -> ,en xrepl/xrepl + xrepl/xrepl> ,e + xrepl/xrepl> (saved-values-char #\~) + xrepl/xrepl> ,top + -> 123 + 123 + -> ~ + 123} +While this is not intended as @emph{the} way to extend and customize +XREPL, it is a useful debugging tool should you want to do so. + +If you have any useful tweaks and extensions, please mail the author or +the Racket developer's +@hyperlink["http://racket-lang.org/community.html"]{mailing list}. + +@; --------------------------------------------------------------------- +@section{License Issues} + +Under most circumstances XREPL uses the @racketmodname[readline] +library, and therefore a similar license caveat applies: XREPL cannot be +enabled by default because of the @seclink["readline-license" #:doc +RL]{readline licensing}, you have to explicitly do so yourself to use +it. (Note that XREPL is intended to be used only for enhanced +interaction, not as a library; so there are no additional issues.) + +@; --------------------------------------------------------------------- +@(check-all-documented) From 3223a656a6c01d0dab905872611a701798cd3765 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 18 Jul 2011 13:44:01 -0400 Subject: [PATCH 288/746] Hook XREPL into a few places where `readline' and `enter!' are mentioned. (cherry picked from commit 5fb83906097b444cb967485f76d616aba98f2fc4) --- collects/scribblings/guide/running.scrbl | 5 +- collects/scribblings/guide/welcome.scrbl | 4 + collects/scribblings/more/more.scrbl | 96 ++++++++++++++++-------- 3 files changed, 72 insertions(+), 33 deletions(-) diff --git a/collects/scribblings/guide/running.scrbl b/collects/scribblings/guide/running.scrbl index 081e8b446a..fa1622313e 100644 --- a/collects/scribblings/guide/running.scrbl +++ b/collects/scribblings/guide/running.scrbl @@ -38,8 +38,9 @@ with a @litchar{> } prompt: > } -@margin-note{For information on GNU Readline support, see -@racketmodname[readline].} +@margin-note{For enhancing your @tech{REPL} experience, see + @racketmodname[xrepl]; for information on GNU Readline support, see + @racketmodname[readline].} To initialize the @tech{REPL}'s environment, @exec{racket} first requires the @racketmodname[racket/init] module, which provides all of diff --git a/collects/scribblings/guide/welcome.scrbl b/collects/scribblings/guide/welcome.scrbl index f56f8ff12f..badb0548f6 100644 --- a/collects/scribblings/guide/welcome.scrbl +++ b/collects/scribblings/guide/welcome.scrbl @@ -1,5 +1,6 @@ #lang scribble/doc @(require scribble/manual scribble/eval scribble/bnf "guide-utils.rkt" + (only-in scribble/core link-element) (for-label racket/enter)) @(define piece-eval (make-base-eval)) @@ -134,6 +135,9 @@ the above text in a file using your favorite editor. If you save it as @filepath{extract.rkt}, then after starting @exec{racket} in the same directory, you'd evaluate the following sequence: +@margin-note{If you use @racketmodname[xrepl], you can use + @(link-element "plainlink" (litchar ",enter extract.rkt") `(xrepl "enter")).} + @interaction[ #:eval piece-eval (eval:alts (enter! "extract.rkt") (void)) diff --git a/collects/scribblings/more/more.scrbl b/collects/scribblings/more/more.scrbl index ce9df39e19..5b198a456e 100644 --- a/collects/scribblings/more/more.scrbl +++ b/collects/scribblings/more/more.scrbl @@ -2,43 +2,58 @@ @(require scribble/manual scribble/urls scribble/eval + (only-in scribble/core link-element) "../quick/keep.rkt" (for-label scheme racket/enter + xrepl readline net/url xml racket/control)) -@(define quick @other-manual['(lib "quick.scrbl" "scribblings/quick")]) -@(define guide @other-manual['(lib "guide.scrbl" "scribblings/guide")]) +@(begin -@(define more-eval (make-base-eval)) -@(interaction-eval #:eval more-eval - (define (show-load re?) - (fprintf (current-error-port) " [~aloading serve.rkt]\n" (if re? "re-" "")))) -@(interaction-eval #:eval more-eval - (define (serve n) void)) -@(interaction-eval #:eval more-eval - (define (show-break) - (fprintf (current-error-port) "^Cuser break"))) -@(interaction-eval #:eval more-eval - (define (show-fail n) - (error 'tcp-listen - "listen on ~a failed (address already in use)" - n))) -@(interaction-eval #:eval more-eval (require xml net/url)) +(define quick @other-manual['(lib "quick.scrbl" "scribblings/quick")]) +(define guide @other-manual['(lib "guide.scrbl" "scribblings/guide")]) -@(define (whole-prog which [last? #f]) +(define more-eval (make-base-eval)) +(interaction-eval #:eval more-eval + (define (show-load re?) + (fprintf (current-error-port) + " [~aloading serve.rkt]\n" (if re? "re-" "")))) +(interaction-eval #:eval more-eval + (define (serve n) void)) +(interaction-eval #:eval more-eval + (define (show-break) + (fprintf (current-error-port) "^Cuser break"))) +(interaction-eval #:eval more-eval + (define (show-fail n) + (error 'tcp-listen + "listen on ~a failed (address already in use)" + n))) +(interaction-eval #:eval more-eval (require xml net/url)) + +(define (whole-prog which [last? #f]) (let ([file (format "step~a.txt" which)]) (margin-note (keep-file file) "Here's the " - (if last? + (if last? "final program" "whole program so far") " in plain text: " (link file "step " which) "."))) +(define-syntax-rule (REQ m) @racket[(require @#,racketmodname[m])]) + +(define (xreplcmd name . args) + (define namestr (format ",~a" name)) + (define content + (litchar (if (null? args) namestr (apply string-append namestr " " args)))) + (link-element "plainlink" content `(xrepl ,(format "~a" name)))) + +) + @title{More: Systems Programming with Racket} @author["Matthew Flatt"] @@ -79,20 +94,36 @@ start @exec{racket} with no command-line arguments: > } -If you're using a plain terminal, if you have GNU Readline installed -on your system, and if you'd like Readline support in @exec{racket}, -then evaluate @racket[(require readline)]. If you also evaluate -@racket[(install-readline!)], then your @filepath{~/.racketrc} is -updated to load Readline whenever you start @exec{racket} for -interactive evaluation. Readline is not needed if you're running a -shell inside Emacs or if you're on Windows and use a @exec{cmd} -window. - -@margin-note{Unfortunately, for legal reasons related to GPL vs. LGPL, - @exec{racket} cannot provide Readline automatically.} +To get a richer read-eval-print-loop, evaluate @REQ[xrepl]. You will +get Readline-based input if you have GNU Readline installed on your +system, and a useful set of meta-commands to support exploration and +development. @interaction[ -(eval:alts (require readline) (void)) +(eval:alts @#,REQ[xrepl] (void)) +] + +To get this as a default, use the @xreplcmd{install!} command---your +@filepath{~/.racketrc} will be updated to load @racketmodname[xrepl] +whenever you start @exec{racket} for interactive evaluation. + +@margin-note{Unfortunately, for legal reasons related to GPL vs. LGPL, + @exec{racket} cannot provide @racketmodname[xrepl] or Readline + automatically.} + +@; FIXME: probably needs revisions, and questionable whether readline +@; should be mentioned by itself. One thing to consider is that with +@; readline it's possible to pretend that the whole thing is one +@; session, whereas xrepl changes the prompt. + +If you want @emph{just} readline support in @exec{racket}, evaluate +@REQ[readline]. To install this in your @filepath{~/.racketrc}, +evaluate @racket[(install-readline!)]. Readline is not needed if you're +using @racketmodname[xrepl], if you're running a shell inside Emacs, or +if you're on Windows and use a @exec{cmd} window. + +@interaction[ +(eval:alts @#,REQ[readline] (void)) (eval:alts (install-readline!) (void)) ] @@ -116,6 +147,9 @@ racket Back in @exec{racket}, try loading the file and running @racket[go]: +@margin-note{If you use @racketmodname[xrepl], you can use + @xreplcmd["enter"]{serve.rkt}.} + @interaction[ #:eval more-eval (eval:alts (enter! "serve.rkt") (show-load #f)) From e8d3223ce571973186fff563c0b447a241bb0124 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 18 Jul 2011 15:23:09 -0400 Subject: [PATCH 289/746] Add an example for extending xrepl, the very stupid way. For the record, a way to do this permanently is to add something like this to your ~/.racketrc: (eval '(begin (saved-values-char #\~) (defcommand eli "stuff" "eli says" ["Make eli say stuff"] (printf "Eli says: ~a\n" (getarg 'line))) (defcommand er #f "alias for errortrace" ["Runs errortrace"] (run-command 'errortrace))) (module->namespace 'xrepl/xrepl)) But this is too stupid even for a section that has "Hacking" in its title. There should definitely be an organized way to do this. This will require several things: * A decent API for doing these things for user code. (So the above `eval' turns to a `require' for your file which uses this API.) This goes beyond just documenting what's in there -- there are issues to resolve like some argument reading protocol (separating the declaration of argument types from the command implementation code), so a new command can call another with arguments that it reads. * There should also be some ,set command for customization options (reading and changing) and code to use the preference file for doing that. I almost started to do this, but currently there are only three values that this could apply to (`saved-values-char', `-number', and `wrap-column' (which might be better to dump and use `pretty-print-columns' instead)). * Also, it might be nice to have some command to do the same for simple aliases. (But this might get into shady parsing issues if it's more than just "I want `foo' to be an alias for an existing `bar' command".) (cherry picked from commit 3c1e624916440747144ce17474f668f32a8a8a6b) --- collects/xrepl/xrepl.scrbl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/collects/xrepl/xrepl.scrbl b/collects/xrepl/xrepl.scrbl index f934492caf..5aed7f00fb 100644 --- a/collects/xrepl/xrepl.scrbl +++ b/collects/xrepl/xrepl.scrbl @@ -453,7 +453,7 @@ customize and extend it, but this will be added in the future. Meanwhile, if you're interested in tweaking XREPL, the @cmd[enter] command can be used as usual to go into its implementation. For -example: +example --- change an XREPL parameter: @verbatim[#:indent 4]{ -> ,en xrepl/xrepl xrepl/xrepl> ,e @@ -463,6 +463,14 @@ example: 123 -> ~ 123} +or add a command: +@verbatim[#:indent 4]{ + -> ,en xrepl/xrepl + xrepl/xrepl> (defcommand eli "stuff" "eli says" ["Make eli say stuff"] + (printf "Eli says: ~a\n" (getarg 'line))) + xrepl/xrepl> ,top + -> ,eli moo + Eli says: moo} While this is not intended as @emph{the} way to extend and customize XREPL, it is a useful debugging tool should you want to do so. From 4c8a6aefe744da97f3c093c040d62500362e1bde Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 18 Jul 2011 15:34:31 -0400 Subject: [PATCH 290/746] Add $F for ,sh commands. (cherry picked from commit 261288c394bfd1c8d5079f9dc41f1bbc29700bbd) --- collects/xrepl/xrepl.rkt | 15 ++++++++++----- collects/xrepl/xrepl.scrbl | 4 ++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index 935a0eabe7..06ac6c4f66 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -163,8 +163,8 @@ (let ([ch (peek-char)]) (if (memq ch skip) (begin (read-char) (loop)) ch))))) -(define (here-path) - (let ([x (here-source)]) (if (path? x) x eof))) +(define (here-path [no-path eof]) + (let ([x (here-source)]) (if (path? x) x no-path))) (define (here-mod-or-eof) (let ([x (here-source)]) (if (not x) @@ -301,7 +301,9 @@ (defcommand (shell sh ls cp mv rm md rd git svn) "" "run a shell command" ["`sh' runs a shell command (via `system'), the aliases run a few useful" - "unix commands. (Note: `ls' has some default arguments set.)"] + "unix commands. (Note: `ls' has some default arguments set.)" + "If the REPL is inside some module's namespace, the command can use $F" + "which is set to the full path to this module's source file."] (let* ([arg (getarg 'line)] [arg (if (equal? "" arg) #f arg)] [cmd (current-command)]) @@ -310,12 +312,15 @@ [(shell) (set! cmd 'sh)]) (let ([cmd (cond [(eq? 'sh cmd) #f] [(symbol? cmd) (symbol->string cmd)] - [else cmd])]) + [else cmd])] + [here (here-path #f)]) + (putenv "F" (if here (path->string here) "")) (unless (system (cond [(and (not cmd) (not arg)) (getenv "SHELL")] [(not cmd) arg] [(not arg) cmd] [else (string-append cmd " " arg)])) - (eprintf "(exit with an error status)\n"))))) + (eprintf "(exit with an error status)\n")) + (when here (putenv "F" ""))))) (defcommand (edit e) " ..." "edit files in your $EDITOR" diff --git a/collects/xrepl/xrepl.scrbl b/collects/xrepl/xrepl.scrbl index 5aed7f00fb..b6654962a7 100644 --- a/collects/xrepl/xrepl.scrbl +++ b/collects/xrepl/xrepl.scrbl @@ -81,6 +81,10 @@ available. Use @cmd[shell] (or @cmd[sh]) to run a generic shell command (via @racket[system]). For convenience, a few synonyms are provided --- they run the specified executables (still using @racket[system]). + + When the REPL is in the context of a module with a known source file, + the shell command can use the @envvar{F} environment variable as the + path to the file. Otherwise, @envvar{F} is set to an empty string. } @defcmd[edit]{ From 1f7e9658a31587dcc8470a64bd31b99107f02cd6 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 18 Jul 2011 15:39:18 -0400 Subject: [PATCH 291/746] Fix reading a 'line argument: always succeeds and returns the line as-is. (cherry picked from commit 09c8880ea041678fbb50f04dae048d5c87be123b) --- collects/xrepl/xrepl.rkt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index 06ac6c4f66..f0027fb067 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -180,17 +180,21 @@ (apply cmderror #:default-who 'getarg fmt args)) (define (missing) (argerror "missing ~a argument" kind)) (define (get read) - (define 1st (if (eq? #\newline (skip-spaces/peek)) eof (read))) + (define (get-one) + (cond [(eq? read read-line-arg) (read)] + [(eq? #\newline (skip-spaces/peek)) eof] + [else (read)])) + (define (get-list) + (let ([x (get-one)]) (if (eof-object? x) '() (cons x (get-list))))) + (define 1st (get-one)) (define 1st? (not (eof-object? 1st))) (define (dflt*) (let ([r (dflt)]) (if (eof-object? r) (missing) r))) (case flag [(req opt) (cond [1st? 1st] [dflt (dflt*)] [(eq? 'opt flag) #f] [else (missing)])] [(list list+) - (define (more) - (if (eq? #\newline (skip-spaces/peek)) '() (cons (read) (more)))) - (cond [1st? (cons 1st (more))] [dflt (list (dflt*))] - [(eq? 'list flag) '()] [else (missing)])] + (cond [1st? (cons 1st (get-list))] [dflt (list (dflt*))] + [(eq? 'list flag) '()] [else (missing)])] [else (error 'getarg "unknown flag: ~e" flag)])) (define (read-string-arg) (define ch (skip-spaces/peek " \t\r\n")) From a03b11befc60b09206ef89530ec0946f737c68b7 Mon Sep 17 00:00:00 2001 From: Carl Eastlund Date: Fri, 17 Jun 2011 13:09:45 -0400 Subject: [PATCH 292/746] Fixed a macro stepper bug: can't use zero? on syntax span, as it can be #f. Please include in the upcoming release. (cherry picked from commit 302cbb5275f2511cd0b72a2625e69afa8b7c894b) --- collects/macro-debugger/syntax-browser/properties.rkt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/collects/macro-debugger/syntax-browser/properties.rkt b/collects/macro-debugger/syntax-browser/properties.rkt index 65dbcafadd..77695d1f3a 100644 --- a/collects/macro-debugger/syntax-browser/properties.rkt +++ b/collects/macro-debugger/syntax-browser/properties.rkt @@ -212,16 +212,16 @@ (define s-line (syntax-line stx)) (define s-column (syntax-column stx)) (define s-position (syntax-position stx)) - (define s-span0 (syntax-span stx)) - (define s-span (if (zero? s-span0) #f s-span0)) + (define s-span (syntax-span stx)) + (define s-span-known? (not (memv s-span '(0 #f)))) (display "Source location\n" key-sd) - (if (or s-source s-line s-column s-position s-span) + (if (or s-source s-line s-column s-position s-span-known?) (begin (display-subkv "source" (prettify-source s-source)) (display-subkv "line" s-line) (display-subkv "column" s-column) (display-subkv "position" s-position) - (display-subkv "span" s-span0)) + (display-subkv "span" s-span)) (display "No source location available\n" n/a-sd)) (display "\n" #f)) From 0083418b53fe936d94282f53a50cfcf1924a1c2f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 19 Jul 2011 08:11:51 -0600 Subject: [PATCH 293/746] cocoa: fix image paste Closes PR 12028 Merge to 5.1.2 (cherry picked from commit c8b37633599a3db93099daec94ce28d399c1b696) --- collects/mred/private/wx/cocoa/image.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/mred/private/wx/cocoa/image.rkt b/collects/mred/private/wx/cocoa/image.rkt index ac05763af8..e6b86f4bb0 100644 --- a/collects/mred/private/wx/cocoa/image.rkt +++ b/collects/mred/private/wx/cocoa/image.rkt @@ -134,4 +134,5 @@ operation: #:type _int NSCompositeCopy fraction: #:type _CGFloat 1.0)) (tellv NSGraphicsContext restoreGraphicsState) (CGContextRestoreGState cg) + (cairo_surface_mark_dirty surface) bm)) From 18b8751ee2aa41e6ae60fcf66fc02db70adccbe4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 19 Jul 2011 08:54:38 -0600 Subject: [PATCH 294/746] win32: fix `is-maximized' in `frame%' Merge to 5.1.2 (cherry picked from commit 255549c8c8fb751a2128478179cb078a70218f3b) --- collects/mred/private/wx/win32/frame.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/mred/private/wx/win32/frame.rkt b/collects/mred/private/wx/win32/frame.rkt index 356983603d..9edcdd5e49 100644 --- a/collects/mred/private/wx/win32/frame.rkt +++ b/collects/mred/private/wx/win32/frame.rkt @@ -442,8 +442,8 @@ (define/public (is-maximized?) (if (is-shown?) - hidden-zoomed? - (IsZoomed hwnd))) + (IsZoomed hwnd) + hidden-zoomed?)) (define/public (maximize on?) (if (is-shown?) From d1b79946f97826442d182a6572062543c53f9d2e Mon Sep 17 00:00:00 2001 From: Guillaume Marceau Date: Tue, 19 Jul 2011 12:59:46 -0400 Subject: [PATCH 295/746] Fixes the (cons an image empty) error message (cherry picked from commit 2ae0376476855082121008b59633a25d7d5851ee) --- collects/lang/private/rewrite-error-message.rkt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/collects/lang/private/rewrite-error-message.rkt b/collects/lang/private/rewrite-error-message.rkt index 8ac58a7340..1083fdcd7f 100755 --- a/collects/lang/private/rewrite-error-message.rkt +++ b/collects/lang/private/rewrite-error-message.rkt @@ -78,12 +78,18 @@ (lambda (all one) "expects a ")) (list #rx"list or cyclic list" (lambda (all) "list")) + (list (regexp-quote "given #(struct:object:image% ...)") + (lambda (all) "given an image")) + (list (regexp-quote "given #(struct:object:image-snip% ...)") + (lambda (all) "given an image")) + (list (regexp-quote "given #(struct:object:cache-image-snip% ...)") + (lambda (all) "given an image")) (list (regexp-quote "#(struct:object:image% ...)") - (lambda (all) "an image")) + (lambda (all) "(image)")) (list (regexp-quote "#(struct:object:image-snip% ...)") - (lambda (all) "an image")) + (lambda (all) "(image)")) (list (regexp-quote "#(struct:object:cache-image-snip% ...)") - (lambda (all) "an image")))) + (lambda (all) "(image)")))) (for/fold ([msg msg]) ([repl. replacements]) (regexp-replace* (first repl.) msg (second repl.)))) From 36a0fea0cc61c9d5368f27de85fd8abccc6374b5 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 19 Jul 2011 00:19:27 -0400 Subject: [PATCH 296/746] XREPL tests. Not too much, but already tests large parts of sensitive code. Caught a bug where ,top would use (enter! #f) but enter grabbed the wrong namespace since it was instantiated in the wrong namespace. (cherry picked from commit f5e53de4d994097f0c7c0495cf2f70efcaf76eeb) --- collects/meta/props | 1 + collects/tests/xrepl/main.rkt | 94 +++++++++++++++++++++++++++++++++++ collects/xrepl/xrepl.rkt | 34 +++++++++---- 3 files changed, 118 insertions(+), 11 deletions(-) create mode 100644 collects/tests/xrepl/main.rkt diff --git a/collects/meta/props b/collects/meta/props index 914c0e3d85..4f3df0511a 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -1979,6 +1979,7 @@ path/s is either such a string or a list of them. "collects/tests/xml" responsible (jay) "collects/tests/xml/test-clark.rkt" drdr:command-line #f drdr:timeout 300 "collects/tests/xml/xml-snip-bug.rkt" drdr:command-line (gracket "-t" *) +"collects/tests/xrepl" responsible (eli) "collects/tests/zo-size.rkt" responsible (jay) "collects/tex2page" responsible (jay) "collects/texpict" responsible (mflatt robby) diff --git a/collects/tests/xrepl/main.rkt b/collects/tests/xrepl/main.rkt new file mode 100644 index 0000000000..e73c7b3408 --- /dev/null +++ b/collects/tests/xrepl/main.rkt @@ -0,0 +1,94 @@ +#lang at-exp racket/base + +(define verbose? (make-parameter #t)) + +(define global-ns (current-namespace)) + +(define stderr (current-error-port)) + +(define (test-xrepl . args) + (define show-all? (verbose?)) + (define-values [Ii Io] (make-pipe)) + (define-values [Oi Oo] (make-pipe)) + (define repl-thread + (parameterize ([current-input-port Ii] + [current-output-port Oo] + [current-error-port Oo] + [current-namespace (make-empty-namespace)] + [error-print-context-length 0] ; easier output + [exit-handler (λ (_) (kill-thread repl-thread))]) + (thread (λ () + (namespace-attach-module global-ns 'racket/base) + (namespace-require 'racket) + (dynamic-require 'xrepl #f) + (read-eval-print-loop))))) + (define (repl-> expected) + (define output (read-string (string-length expected) Oi)) + (if (equal? output expected) + (when show-all? (display output)) + (error 'xrepl "test failure, expected ~s, got ~s" expected output))) + (let loop ([strs args] [input? #f]) + (cond + [(and (pair? strs) (equal? "" (car strs))) + (loop (cdr strs) input?)] + [(and (thread-dead? repl-thread) (null? strs)) + (printf "All tests passed.\n")] + [(thread-dead? repl-thread) + (error 'xrepl "test failure, repl thread died unexpectedly")] + [(null? strs) + (if (sync/timeout 1 repl-thread) + (loop strs input?) + (error 'xrepl "test failure, repl thread is alive at end of tests"))] + [(eq? '« (car strs)) + (when input? (error 'xrepl "bad test: unterminated `«'")) + (loop (cdr strs) #t)] + [(eq? '» (car strs)) + (unless input? (error 'xrepl "bad test: redundant `»'")) + (loop (cdr strs) 'newline)] + [(regexp-match #rx"^(.*?)(?: *⇒[^\n]*)(.*)" (car strs)) + => (λ (m) (loop (list* (cadr m) (caddr m) (cdr strs)) input?))] + [(regexp-match #rx"^(.*?)([«»])(.*)" (car strs)) + => (λ (m) (loop (list* (cadr m) (string->symbol (caddr m)) (cadddr m) + (cdr strs)) + input?))] + [(eq? 'newline input?) + (unless (regexp-match? #rx"^\n" (car strs)) + (error 'xrepl "bad test: `»' followed by a non-newline")) + (newline Io) (flush-output Io) + (when show-all? (newline) (flush-output)) + (loop (cons (substring (car strs) 1) (cdr strs)) #f)] + [input? + (display (car strs) Io) + (when show-all? (display (car strs)) (flush-output)) + (loop (cdr strs) #t)] + [else + (repl-> (car strs)) + (loop (cdr strs) #f)]))) + +@test-xrepl|={ + -> «(- 2 1)» + 1 + -> «(values 2 3)» + 2 + 3 + -> «(values 4)» + 4 + -> «(list ^ ^^ ^^^ ^^^^)» + '(4 3 2 1) + -> «(module foo racket (define x 123))» + -> «,en foo» + 'foo> «x» + 123 + 'foo> «,top» + -> «(define enter! 123)» + -> «(enter! 'foo)» + procedure application: expected procedure, given: 123; arguments were: 'foo + -> «,en foo» ⇒ but this still works + 'foo> «,top» + -> «,switch foo» + ; *** Initializing a new `foo' namespace with "racket/main.rkt" *** + ; *** Switching to the `foo' namespace *** + foo::-> «,switch *» + ; *** Switching to the `*' namespace *** + -> «,ex» + |=@||}=| diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index f0027fb067..3352cca767 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -23,7 +23,8 @@ (define (autoloaded? sym) (hash-ref autoloaded-specs sym #f)) (define-syntax-rule (defautoload libspec id ...) (begin (define (id . args) - (set! id (dynamic-require 'libspec 'id)) + (set! id (parameterize ([current-namespace hidden-namespace]) + (dynamic-require 'libspec 'id))) (hash-set! autoloaded-specs 'libspec #t) (hash-set! autoloaded-specs 'id #t) (apply id args)) @@ -38,13 +39,25 @@ ;; similar, but just for identifiers (define-namespace-anchor anchor) (define (here-namespace) (namespace-anchor->namespace anchor)) +(define hidden-namespace (make-base-namespace)) +(define initial-namespace (current-namespace)) +;; when `racket/enter' initializes, it grabs the `current-namespace' to get +;; back to -- which means it should be instantiated in a top level namespace +;; rather than in (here-namespace); but if we use `initial-namespace' we +;; essentially rely on the user to not kill `enter!' (eg, (define enter! 4)). +;; the solution is to make a `hidden-namespace' where we store these bindings, +;; then instantiate needed modules in the initial namespace and immediately +;; attach the modules to the hidden one then use it, so changes to the binding +;; in `initial-namespace' doesn't affect us. (define (make-lazy-identifier sym from) (define id #f) - (λ () (or id (parameterize ([current-namespace (here-namespace)]) - (eval (namespace-syntax-introduce - (datum->syntax #f #`(require #,from)))) - (set! id (namespace-symbol->identifier sym)) - id)))) + (λ () (or id (begin (parameterize ([current-namespace initial-namespace]) + (namespace-require from)) + (parameterize ([current-namespace hidden-namespace]) + (namespace-attach-module initial-namespace from) + (namespace-require from) + (set! id (namespace-symbol->identifier sym)) + id))))) ;; makes it easy to use meta-tools without user-namespace contamination (define (eval-sexpr-for-user form) @@ -58,10 +71,9 @@ (if (path-string? x) (path->relative-string/setup x) x)) (define (here-source) ; returns a path, a symbol, or #f (= not in a module) - (let* ([x (datum->syntax #'here '(#%variable-reference))] - [x (eval (namespace-syntax-introduce x))] - [x (variable-reference->module-source x)]) - x)) + (variable-reference->module-source + (eval (namespace-syntax-introduce + (datum->syntax #f `(,#'#%variable-reference)))))) (define (phase->name phase [fmt #f]) (define s @@ -983,7 +995,7 @@ (λ () (let ([base-stxs #f]) (unless base-stxs (set! base-stxs ; all ids that are bound to a syntax in racket/base - (parameterize ([current-namespace (here-namespace)]) + (parameterize ([current-namespace hidden-namespace]) (let-values ([(vals stxs) (module->exports 'racket/base)]) (map (λ (s) (namespace-symbol->identifier (car s))) (cdr (assq 0 stxs))))))) From c7bf34d38773d5e4c29a45072d57bcc33c98be03 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 19 Jul 2011 00:36:08 -0400 Subject: [PATCH 297/746] Improve macro stepper output, and some more ,stx outputs. (cherry picked from commit 8109299ec86be6f2ddc89c2862e5a62b5280dcae) --- collects/xrepl/xrepl.rkt | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index 3352cca767..d4b1a4cd33 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -961,7 +961,7 @@ (namespace-require init) (hash-set! namespaces name (cons (current-namespace) init)))) (when (and name (not (eq? name (current-namespace-name)))) - (printf "; *** switching to the `~s' namespace ***\n" name) + (printf "; *** Switching to the `~s' namespace ***\n" name) (let ([x (hash-ref namespaces (current-namespace-name))]) (unless (eq? (car x) old-namespace) (printf "; (note: saving current namespace for `~s')\n" @@ -1000,6 +1000,19 @@ (map (λ (s) (namespace-symbol->identifier (car s))) (cdr (assq 0 stxs))))))) (λ (id) (not (ormap (λ (s) (free-identifier=? id s)) base-stxs)))))) +(define (macro-stepper . args) + (define-values [i o] (make-pipe)) + (parameterize ([current-output-port o]) + (thread (λ () (apply expand/step-text args) (close-output-port o)))) + (let loop () + (define l (read-line i)) + (unless (eof-object? l) + ;; hack: beautify the stepper's output -- remove empty line, indent code + (unless (equal? "" l) + (printf (if (regexp-match? #px"^[A-Z][a-z]+\\b" l) + "; ---- ~a ----\n" "; ~a\n") + l)) + (loop)))) (defcommand (syntax stx st) "[] [ ...]" "set syntax object to inspect, and control it" ["With no arguments, will show the previously set (or expanded) syntax" @@ -1017,22 +1030,22 @@ (define args (getarg 'syntax 'list)) (for ([stx (in-list (if (null? args) '(#f) args))]) (define (show/set label stx) - (printf "~a\n" label) + (printf "; ~a\n" label) (current-syntax stx) - (pretty-write (syntax->datum stx))) + (display "; ") (pretty-write (syntax->datum stx))) (define (cur) (or (current-syntax) (cmderror "no syntax set yet"))) (case (and stx (if (identifier? stx) (syntax-e stx) '--none--)) - [(#f) (show/set "current syntax:" (cur))] + [(#f) (show/set "Current syntax:" (cur))] [(^) (if (last-input-syntax) - (show/set "using last expression:" (last-input-syntax)) + (show/set "Using last expression:" (last-input-syntax)) (cmderror "no expression entered yet"))] [(+) (show/set "expand-once ->" (expand-once (cur)))] [(!) (show/set "expand ->" (expand (cur)))] - [(*) (printf "stepper:\n") (expand/step-text (cur) (not-in-base))] - [(**) (printf "stepper:\n") (expand/step-text (cur))] + [(*) (printf "; Stepper:\n") (macro-stepper (cur) (not-in-base))] + [(**) (printf "; Stepper:\n") (macro-stepper (cur))] [else (if (syntax? stx) - (begin (printf "syntax set\n") (current-syntax stx)) + (begin (printf "; Syntax set\n") (current-syntax stx)) (cmderror "internal error: ~s ~s" stx (syntax? stx)))]))) ;; ---------------------------------------------------------------------------- From ccd9ab07a73e0f0ba6a4fb6d1db513fa3881a23a Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 19 Jul 2011 17:01:27 -0400 Subject: [PATCH 298/746] Revert "Hook XREPL into a few places where `readline' and `enter!' are mentioned." This reverts commit 3223a656a6c01d0dab905872611a701798cd3765. --- collects/scribblings/guide/running.scrbl | 5 +- collects/scribblings/guide/welcome.scrbl | 4 -- collects/scribblings/more/more.scrbl | 92 ++++++++---------------- 3 files changed, 31 insertions(+), 70 deletions(-) diff --git a/collects/scribblings/guide/running.scrbl b/collects/scribblings/guide/running.scrbl index fa1622313e..081e8b446a 100644 --- a/collects/scribblings/guide/running.scrbl +++ b/collects/scribblings/guide/running.scrbl @@ -38,9 +38,8 @@ with a @litchar{> } prompt: > } -@margin-note{For enhancing your @tech{REPL} experience, see - @racketmodname[xrepl]; for information on GNU Readline support, see - @racketmodname[readline].} +@margin-note{For information on GNU Readline support, see +@racketmodname[readline].} To initialize the @tech{REPL}'s environment, @exec{racket} first requires the @racketmodname[racket/init] module, which provides all of diff --git a/collects/scribblings/guide/welcome.scrbl b/collects/scribblings/guide/welcome.scrbl index badb0548f6..f56f8ff12f 100644 --- a/collects/scribblings/guide/welcome.scrbl +++ b/collects/scribblings/guide/welcome.scrbl @@ -1,6 +1,5 @@ #lang scribble/doc @(require scribble/manual scribble/eval scribble/bnf "guide-utils.rkt" - (only-in scribble/core link-element) (for-label racket/enter)) @(define piece-eval (make-base-eval)) @@ -135,9 +134,6 @@ the above text in a file using your favorite editor. If you save it as @filepath{extract.rkt}, then after starting @exec{racket} in the same directory, you'd evaluate the following sequence: -@margin-note{If you use @racketmodname[xrepl], you can use - @(link-element "plainlink" (litchar ",enter extract.rkt") `(xrepl "enter")).} - @interaction[ #:eval piece-eval (eval:alts (enter! "extract.rkt") (void)) diff --git a/collects/scribblings/more/more.scrbl b/collects/scribblings/more/more.scrbl index 5b198a456e..ce9df39e19 100644 --- a/collects/scribblings/more/more.scrbl +++ b/collects/scribblings/more/more.scrbl @@ -2,58 +2,43 @@ @(require scribble/manual scribble/urls scribble/eval - (only-in scribble/core link-element) "../quick/keep.rkt" (for-label scheme racket/enter - xrepl readline net/url xml racket/control)) -@(begin +@(define quick @other-manual['(lib "quick.scrbl" "scribblings/quick")]) +@(define guide @other-manual['(lib "guide.scrbl" "scribblings/guide")]) -(define quick @other-manual['(lib "quick.scrbl" "scribblings/quick")]) -(define guide @other-manual['(lib "guide.scrbl" "scribblings/guide")]) +@(define more-eval (make-base-eval)) +@(interaction-eval #:eval more-eval + (define (show-load re?) + (fprintf (current-error-port) " [~aloading serve.rkt]\n" (if re? "re-" "")))) +@(interaction-eval #:eval more-eval + (define (serve n) void)) +@(interaction-eval #:eval more-eval + (define (show-break) + (fprintf (current-error-port) "^Cuser break"))) +@(interaction-eval #:eval more-eval + (define (show-fail n) + (error 'tcp-listen + "listen on ~a failed (address already in use)" + n))) +@(interaction-eval #:eval more-eval (require xml net/url)) -(define more-eval (make-base-eval)) -(interaction-eval #:eval more-eval - (define (show-load re?) - (fprintf (current-error-port) - " [~aloading serve.rkt]\n" (if re? "re-" "")))) -(interaction-eval #:eval more-eval - (define (serve n) void)) -(interaction-eval #:eval more-eval - (define (show-break) - (fprintf (current-error-port) "^Cuser break"))) -(interaction-eval #:eval more-eval - (define (show-fail n) - (error 'tcp-listen - "listen on ~a failed (address already in use)" - n))) -(interaction-eval #:eval more-eval (require xml net/url)) - -(define (whole-prog which [last? #f]) +@(define (whole-prog which [last? #f]) (let ([file (format "step~a.txt" which)]) (margin-note (keep-file file) "Here's the " - (if last? + (if last? "final program" "whole program so far") " in plain text: " (link file "step " which) "."))) -(define-syntax-rule (REQ m) @racket[(require @#,racketmodname[m])]) - -(define (xreplcmd name . args) - (define namestr (format ",~a" name)) - (define content - (litchar (if (null? args) namestr (apply string-append namestr " " args)))) - (link-element "plainlink" content `(xrepl ,(format "~a" name)))) - -) - @title{More: Systems Programming with Racket} @author["Matthew Flatt"] @@ -94,36 +79,20 @@ start @exec{racket} with no command-line arguments: > } -To get a richer read-eval-print-loop, evaluate @REQ[xrepl]. You will -get Readline-based input if you have GNU Readline installed on your -system, and a useful set of meta-commands to support exploration and -development. - -@interaction[ -(eval:alts @#,REQ[xrepl] (void)) -] - -To get this as a default, use the @xreplcmd{install!} command---your -@filepath{~/.racketrc} will be updated to load @racketmodname[xrepl] -whenever you start @exec{racket} for interactive evaluation. +If you're using a plain terminal, if you have GNU Readline installed +on your system, and if you'd like Readline support in @exec{racket}, +then evaluate @racket[(require readline)]. If you also evaluate +@racket[(install-readline!)], then your @filepath{~/.racketrc} is +updated to load Readline whenever you start @exec{racket} for +interactive evaluation. Readline is not needed if you're running a +shell inside Emacs or if you're on Windows and use a @exec{cmd} +window. @margin-note{Unfortunately, for legal reasons related to GPL vs. LGPL, - @exec{racket} cannot provide @racketmodname[xrepl] or Readline - automatically.} - -@; FIXME: probably needs revisions, and questionable whether readline -@; should be mentioned by itself. One thing to consider is that with -@; readline it's possible to pretend that the whole thing is one -@; session, whereas xrepl changes the prompt. - -If you want @emph{just} readline support in @exec{racket}, evaluate -@REQ[readline]. To install this in your @filepath{~/.racketrc}, -evaluate @racket[(install-readline!)]. Readline is not needed if you're -using @racketmodname[xrepl], if you're running a shell inside Emacs, or -if you're on Windows and use a @exec{cmd} window. + @exec{racket} cannot provide Readline automatically.} @interaction[ -(eval:alts @#,REQ[readline] (void)) +(eval:alts (require readline) (void)) (eval:alts (install-readline!) (void)) ] @@ -147,9 +116,6 @@ racket Back in @exec{racket}, try loading the file and running @racket[go]: -@margin-note{If you use @racketmodname[xrepl], you can use - @xreplcmd["enter"]{serve.rkt}.} - @interaction[ #:eval more-eval (eval:alts (enter! "serve.rkt") (show-load #f)) From 32b53e65496675b4dfa64abef1962b2a47e41781 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 19 Jul 2011 17:03:17 -0400 Subject: [PATCH 299/746] Remove xrepl from the release branch. --- collects/meta/dist-specs.rkt | 3 - collects/meta/props | 2 - collects/tests/xrepl/main.rkt | 94 --- collects/xrepl/doc-utils.rkt | 80 -- collects/xrepl/info.rkt | 5 - collects/xrepl/main.rkt | 13 - collects/xrepl/xrepl.rkt | 1345 --------------------------------- collects/xrepl/xrepl.scrbl | 496 ------------ 8 files changed, 2038 deletions(-) delete mode 100644 collects/tests/xrepl/main.rkt delete mode 100644 collects/xrepl/doc-utils.rkt delete mode 100644 collects/xrepl/info.rkt delete mode 100644 collects/xrepl/main.rkt delete mode 100644 collects/xrepl/xrepl.rkt delete mode 100644 collects/xrepl/xrepl.scrbl diff --git a/collects/meta/dist-specs.rkt b/collects/meta/dist-specs.rkt index 99187995f3..13fa0f72f9 100644 --- a/collects/meta/dist-specs.rkt +++ b/collects/meta/dist-specs.rkt @@ -511,9 +511,6 @@ mz-extras :+= (collects: "rnrs/") ;; -------------------- readline mz-extras :+= (package: "readline/") -;; -------------------- readline -mz-extras :+= (package: "xrepl/") - ;; -------------------- wxme mz-extras :+= (collects: "wxme/") diff --git a/collects/meta/props b/collects/meta/props index 4f3df0511a..e428687d58 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -1979,7 +1979,6 @@ path/s is either such a string or a list of them. "collects/tests/xml" responsible (jay) "collects/tests/xml/test-clark.rkt" drdr:command-line #f drdr:timeout 300 "collects/tests/xml/xml-snip-bug.rkt" drdr:command-line (gracket "-t" *) -"collects/tests/xrepl" responsible (eli) "collects/tests/zo-size.rkt" responsible (jay) "collects/tex2page" responsible (jay) "collects/texpict" responsible (mflatt robby) @@ -2070,7 +2069,6 @@ path/s is either such a string or a list of them. "collects/xml/text-box-tool.rkt" drdr:command-line (gracket-text "-t" *) "collects/xml/text-snipclass.rkt" drdr:command-line (gracket-text "-t" *) "collects/xml/xml-snipclass.rkt" drdr:command-line (gracket-text "-t" *) -"collects/xrepl" responsible (eli) "doc/release-notes/COPYING-libscheme.txt" responsible (mflatt) "doc/release-notes/COPYING.txt" responsible (mflatt) "doc/release-notes/drracket" responsible (robby) diff --git a/collects/tests/xrepl/main.rkt b/collects/tests/xrepl/main.rkt deleted file mode 100644 index e73c7b3408..0000000000 --- a/collects/tests/xrepl/main.rkt +++ /dev/null @@ -1,94 +0,0 @@ -#lang at-exp racket/base - -(define verbose? (make-parameter #t)) - -(define global-ns (current-namespace)) - -(define stderr (current-error-port)) - -(define (test-xrepl . args) - (define show-all? (verbose?)) - (define-values [Ii Io] (make-pipe)) - (define-values [Oi Oo] (make-pipe)) - (define repl-thread - (parameterize ([current-input-port Ii] - [current-output-port Oo] - [current-error-port Oo] - [current-namespace (make-empty-namespace)] - [error-print-context-length 0] ; easier output - [exit-handler (λ (_) (kill-thread repl-thread))]) - (thread (λ () - (namespace-attach-module global-ns 'racket/base) - (namespace-require 'racket) - (dynamic-require 'xrepl #f) - (read-eval-print-loop))))) - (define (repl-> expected) - (define output (read-string (string-length expected) Oi)) - (if (equal? output expected) - (when show-all? (display output)) - (error 'xrepl "test failure, expected ~s, got ~s" expected output))) - (let loop ([strs args] [input? #f]) - (cond - [(and (pair? strs) (equal? "" (car strs))) - (loop (cdr strs) input?)] - [(and (thread-dead? repl-thread) (null? strs)) - (printf "All tests passed.\n")] - [(thread-dead? repl-thread) - (error 'xrepl "test failure, repl thread died unexpectedly")] - [(null? strs) - (if (sync/timeout 1 repl-thread) - (loop strs input?) - (error 'xrepl "test failure, repl thread is alive at end of tests"))] - [(eq? '« (car strs)) - (when input? (error 'xrepl "bad test: unterminated `«'")) - (loop (cdr strs) #t)] - [(eq? '» (car strs)) - (unless input? (error 'xrepl "bad test: redundant `»'")) - (loop (cdr strs) 'newline)] - [(regexp-match #rx"^(.*?)(?: *⇒[^\n]*)(.*)" (car strs)) - => (λ (m) (loop (list* (cadr m) (caddr m) (cdr strs)) input?))] - [(regexp-match #rx"^(.*?)([«»])(.*)" (car strs)) - => (λ (m) (loop (list* (cadr m) (string->symbol (caddr m)) (cadddr m) - (cdr strs)) - input?))] - [(eq? 'newline input?) - (unless (regexp-match? #rx"^\n" (car strs)) - (error 'xrepl "bad test: `»' followed by a non-newline")) - (newline Io) (flush-output Io) - (when show-all? (newline) (flush-output)) - (loop (cons (substring (car strs) 1) (cdr strs)) #f)] - [input? - (display (car strs) Io) - (when show-all? (display (car strs)) (flush-output)) - (loop (cdr strs) #t)] - [else - (repl-> (car strs)) - (loop (cdr strs) #f)]))) - -@test-xrepl|={ - -> «(- 2 1)» - 1 - -> «(values 2 3)» - 2 - 3 - -> «(values 4)» - 4 - -> «(list ^ ^^ ^^^ ^^^^)» - '(4 3 2 1) - -> «(module foo racket (define x 123))» - -> «,en foo» - 'foo> «x» - 123 - 'foo> «,top» - -> «(define enter! 123)» - -> «(enter! 'foo)» - procedure application: expected procedure, given: 123; arguments were: 'foo - -> «,en foo» ⇒ but this still works - 'foo> «,top» - -> «,switch foo» - ; *** Initializing a new `foo' namespace with "racket/main.rkt" *** - ; *** Switching to the `foo' namespace *** - foo::-> «,switch *» - ; *** Switching to the `*' namespace *** - -> «,ex» - |=@||}=| diff --git a/collects/xrepl/doc-utils.rkt b/collects/xrepl/doc-utils.rkt deleted file mode 100644 index fe15ecd335..0000000000 --- a/collects/xrepl/doc-utils.rkt +++ /dev/null @@ -1,80 +0,0 @@ -#lang racket/base - -(require scribble/manual scribble/core scribble/decode - racket/list racket/sandbox) - -(provide (all-from-out scribble/manual) - RL GUIDE cmd defcmd check-all-documented) - -(define RL '(lib "readline/readline.scrbl")) -(define GUIDE '(lib "scribblings/guide/guide.scrbl")) - -(define commands - (let ([c #f]) - (λ () - (unless c - (define e (call-with-trusted-sandbox-configuration - (λ () (make-evaluator 'racket/base)))) - (e '(require xrepl/xrepl)) - (e '(current-namespace (module->namespace 'xrepl/xrepl))) - (set! c (e '(for/list ([c (in-list commands-list)]) - (list (car (command-names c)) - (cdr (command-names c)) - (command-argline c) - (command-blurb c))))) - (kill-evaluator e)) - c))) -(define documented '()) - -(define (cmd* name0 . more) - (define name (if (symbol? name0) name0 (string->symbol name0))) - (define full-name - (or (and (assq name (commands)) name) - (for/or ([c (in-list (commands))]) (and (memq name (cadr c)) (car c))) - (error 'cmd "unknown command: ~s" name))) - (define content - (litchar (let ([s (format ",~a" name)]) - (if (pair? more) (apply string-append s " " more) s)))) - (link-element "plainlink" content `(xrepl ,(format "~a" full-name)))) - -(define-syntax-rule (cmd name more ...) (cmd* 'name more ...)) - -(define (cmd-index name) - (define namestr (format ",~a" name)) - (define tag `(xrepl ,(format "~a" name))) - (define content (cmd* name)) - (define ielem - (index-element #f content tag (list namestr) (list content) - 'xrepl-command)) - (toc-target-element #f (list ielem) tag)) - -(define (defcmd* name . text) - (set! documented (cons name documented)) - (define-values [other-names argline blurb] - (apply values (cond [(assq name (commands)) => cdr] - [else (error 'defcmd "unknown command: ~s" name)]))) - (define header - (list (cmd-index name) (litchar (string-append " " (or argline ""))))) - (define desc - (list (hspace 2) (make-element 'italic blurb))) - (define synonyms - (and (pair? other-names) - (list (hspace 2) - "[Synonyms: " - (add-between (map (λ (n) (litchar (format ",~a" n))) - other-names) - " ") - "]"))) - (splice - (list* (tabular #:style 'boxed `((,header) (,desc) - ,@(if synonyms `((,synonyms)) `()))) - "\n" "\n" text))) - -(define-syntax-rule (defcmd name text ...) (defcmd* 'name text ...)) - -(define (check-all-documented) - (unless (= (length documented) (length (remove-duplicates documented))) - (error 'xrepl-docs "some commands were documented multiple times")) - (let ([missing (remove* documented (map car (commands)))]) - (when (pair? missing) - (error 'xrepl-docs "missing command documentation: ~s" missing)))) diff --git a/collects/xrepl/info.rkt b/collects/xrepl/info.rkt deleted file mode 100644 index 96e8ea9a85..0000000000 --- a/collects/xrepl/info.rkt +++ /dev/null @@ -1,5 +0,0 @@ -#lang setup/infotab - -(define name "eXtended REPL") - -(define scribblings '(("xrepl.scrbl" () (tool-library)))) diff --git a/collects/xrepl/main.rkt b/collects/xrepl/main.rkt deleted file mode 100644 index 3a70c4f70f..0000000000 --- a/collects/xrepl/main.rkt +++ /dev/null @@ -1,13 +0,0 @@ -#lang racket/base - -;; This file is intended to be loaded from your init file (evaluatue -;; (find-system-path 'init-file) to see where that is on your OS.) - -(require "xrepl.rkt") - -;; may want to disable inlining to allow redefinitions -;; (compile-enforce-module-constants #f) - -;; create the command repl reader, and value-saving evaluator -(current-prompt-read (make-xrepl-reader)) -(current-eval (make-xrepl-evaluator (current-eval))) diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt deleted file mode 100644 index d4b1a4cd33..0000000000 --- a/collects/xrepl/xrepl.rkt +++ /dev/null @@ -1,1345 +0,0 @@ -#lang racket/base - -;; ---------------------------------------------------------------------------- -;; customization - -(define toplevel-prefix (make-parameter "-")) ; when not in a module -(define saved-values-number (make-parameter 5)) -(define saved-values-char (make-parameter #\^)) -(define wrap-column (make-parameter 79)) -;; TODO: when there's a few more of these, make them come from the prefs - -;; ---------------------------------------------------------------------------- - -(require racket/list racket/match) - -;; ---------------------------------------------------------------------------- -;; utilities - -(define home-dir (find-system-path 'home-dir)) - -;; autoloads: avoid loading a ton of stuff to minimize startup penalty -(define autoloaded-specs (make-hasheq)) -(define (autoloaded? sym) (hash-ref autoloaded-specs sym #f)) -(define-syntax-rule (defautoload libspec id ...) - (begin (define (id . args) - (set! id (parameterize ([current-namespace hidden-namespace]) - (dynamic-require 'libspec 'id))) - (hash-set! autoloaded-specs 'libspec #t) - (hash-set! autoloaded-specs 'id #t) - (apply id args)) - ...)) - -(defautoload racket/system system system*) -(defautoload racket/file file->string) -(defautoload setup/path-to-relative path->relative-string/setup) -(defautoload syntax/modcode get-module-code) -(defautoload racket/path find-relative-path) - -;; similar, but just for identifiers -(define-namespace-anchor anchor) -(define (here-namespace) (namespace-anchor->namespace anchor)) -(define hidden-namespace (make-base-namespace)) -(define initial-namespace (current-namespace)) -;; when `racket/enter' initializes, it grabs the `current-namespace' to get -;; back to -- which means it should be instantiated in a top level namespace -;; rather than in (here-namespace); but if we use `initial-namespace' we -;; essentially rely on the user to not kill `enter!' (eg, (define enter! 4)). -;; the solution is to make a `hidden-namespace' where we store these bindings, -;; then instantiate needed modules in the initial namespace and immediately -;; attach the modules to the hidden one then use it, so changes to the binding -;; in `initial-namespace' doesn't affect us. -(define (make-lazy-identifier sym from) - (define id #f) - (λ () (or id (begin (parameterize ([current-namespace initial-namespace]) - (namespace-require from)) - (parameterize ([current-namespace hidden-namespace]) - (namespace-attach-module initial-namespace from) - (namespace-require from) - (set! id (namespace-symbol->identifier sym)) - id))))) - -;; makes it easy to use meta-tools without user-namespace contamination -(define (eval-sexpr-for-user form) - (eval (namespace-syntax-introduce (datum->syntax #f form)))) - -(define (modspec->path modspec) ; returns a symbol for 'foo specs - (resolved-module-path-name ((current-module-name-resolver) modspec #f #f))) -(define (mpi->name mpi) - (resolved-module-path-name (module-path-index-resolve mpi))) -(define (->relname x) - (if (path-string? x) (path->relative-string/setup x) x)) - -(define (here-source) ; returns a path, a symbol, or #f (= not in a module) - (variable-reference->module-source - (eval (namespace-syntax-introduce - (datum->syntax #f `(,#'#%variable-reference)))))) - -(define (phase->name phase [fmt #f]) - (define s - (case phase - [(0) #f] [(#f) "for-label"] [(1) "for-syntax"] [(-1) "for-template"] - [else (format "for-meta:~a" phase)])) - (cond [(not fmt) s] [s (format fmt s)] [else ""])) - -;; true if (quote sym) is a known module name -(define (module-name? sym) - (and (symbol? sym) - (with-handlers ([exn? (λ (_) #f)]) (module->imports `',sym) #t))) - -;; support visual column-aware output -;; right after an input expression is entered the terminal won't show the -;; newline, so as far as column counting goes it's still after the prompt which -;; leads to bad output in practice. (at least in the common case where IO -;; share the same terminal.) This will be redundant with the already-added -;; `port-set-next-location!'. -(define last-output-port #f) -(define last-output-line #f) -(define last-output-visual-col #f) -(define (maybe-new-output-port) - (unless (eq? last-output-port (current-output-port)) - (set! last-output-port (current-output-port)) - (flush-output last-output-port) - (port-count-lines! last-output-port) - (let-values ([(line col pos) (port-next-location last-output-port)]) - (set! last-output-line line) - (set! last-output-visual-col col)))) -(define (fresh-line) - (maybe-new-output-port) - (flush-output last-output-port) - (let-values ([(line col pos) (port-next-location last-output-port)]) - (unless (eq? col (if (eq? line last-output-line) last-output-visual-col 0)) - (newline)))) -(define (zero-column!) - ;; there's a problem whenever there's some printout followed by a read: the - ;; cursor will at column zero, but the port counting will think that it's - ;; still right after the printout; call this function in such cases to adjust - ;; the column to 0. - (maybe-new-output-port) - ;; if there was a way to change the location of stdout we'd set the column to - ;; 0 here... - (let-values ([(line col pos) (port-next-location last-output-port)]) - (set! last-output-line line) - (set! last-output-visual-col col))) - -;; wrapped `printf' (cheap but effective), aware of the visual col -(define wrap-prefix (make-parameter "")) -(define (wprintf fmt . args) - (let ([o (current-output-port)] - [wcol (wrap-column)] - [pfx (wrap-prefix)] - [strs (regexp-split #rx" +" (apply format fmt args))]) - (write-string (car strs) o) - (for ([str (in-list (cdr strs))]) - (define-values [line col pos] (port-next-location o)) - (define vcol - (if (eq? line last-output-line) (- col last-output-visual-col) col)) - (if ((+ vcol (string-length str)) . >= . wcol) - (begin (newline o) (write-string pfx o)) - (write-string " " o)) - (write-string str o)))) - -;; ---------------------------------------------------------------------------- -;; toplevel "," commands management - -(struct command (names argline blurb desc handler)) -(define commands (make-hasheq)) -(define commands-list '()) ; for help displays, in definition order -(define current-command (make-parameter #f)) -(define (register-command! names blurb argline desc handler) - (let* ([names (if (list? names) names (list names))] - [cmd (command names blurb argline desc handler)]) - (for ([n (in-list names)]) - (if (hash-ref commands n #f) - (error 'defcommand "duplicate command name: ~s" n) - (hash-set! commands n cmd))) - (set! commands-list (cons cmd commands-list)))) -(define-syntax-rule (defcommand cmd+aliases argline blurb [desc ...] - body0 body ...) - (register-command! `cmd+aliases `argline `blurb `(desc ...) - (λ () body0 body ...))) - -(define (cmderror fmt #:default-who [dwho #f] . args) - (let ([cmd (current-command)]) - (raise-user-error (or (and cmd (string->symbol (format ",~a" cmd))) - dwho '???) - (apply format fmt args)))) - -;; returns first peeked non-space/tab char (#\return is considered space too) -(define string->list* - (let ([t (make-weak-hasheq)]) ; good for string literals - (λ (s) (hash-ref! t s (λ () (string->list s)))))) -(define (skip-spaces/peek [skip " \t\r"]) - (let ([skip (string->list* skip)]) - (let loop () - (let ([ch (peek-char)]) - (if (memq ch skip) (begin (read-char) (loop)) ch))))) - -(define (here-path [no-path eof]) - (let ([x (here-source)]) (if (path? x) x no-path))) -(define (here-mod-or-eof) - (let ([x (here-source)]) - (if (not x) - eof - (datum->syntax #f - (cond [(symbol? x) (and (module-name? x) `',x)] - [(path? x) (let ([s (path->string x)]) - (if (absolute-path? x) `(file ,s) s))] - [else (error 'here-mod-or-eof "internal error: ~s" x)]))))) - -(define (getarg kind [flag 'req] #:default [dflt #f]) - (define (argerror fmt . args) - (apply cmderror #:default-who 'getarg fmt args)) - (define (missing) (argerror "missing ~a argument" kind)) - (define (get read) - (define (get-one) - (cond [(eq? read read-line-arg) (read)] - [(eq? #\newline (skip-spaces/peek)) eof] - [else (read)])) - (define (get-list) - (let ([x (get-one)]) (if (eof-object? x) '() (cons x (get-list))))) - (define 1st (get-one)) - (define 1st? (not (eof-object? 1st))) - (define (dflt*) (let ([r (dflt)]) (if (eof-object? r) (missing) r))) - (case flag - [(req opt) (cond [1st? 1st] [dflt (dflt*)] - [(eq? 'opt flag) #f] [else (missing)])] - [(list list+) - (cond [1st? (cons 1st (get-list))] [dflt (list (dflt*))] - [(eq? 'list flag) '()] [else (missing)])] - [else (error 'getarg "unknown flag: ~e" flag)])) - (define (read-string-arg) - (define ch (skip-spaces/peek " \t\r\n")) - (let* ([i (current-input-port)] - [m (if (eq? ch #\") - (let ([m (regexp-match #px#"((?:\\\\.|[^\"\\\\]+)+)\"" i)]) - (and m (regexp-replace* #rx#"\\\\(.)" (cadr m) #"\\1"))) - (cond [(regexp-match #px#"\\S+" i) => car] [else #f]))]) - (if m (bytes->string/locale m) eof))) - (define (read-line-arg) - (regexp-replace* #px"^\\s+|\\s+$" (read-line) "")) - (define (process-modspec spec) - ;; convenience: symbolic modspecs that name a file turn to a `file' spec, - ;; and those that name a known module turn to a (quote sym) spec - (define dtm (if (syntax? spec) (syntax->datum spec) spec)) - (if (not (symbol? dtm)) - spec - (let* (;; try a file - [f (expand-user-path (symbol->string dtm))] - [f (and (file-exists? f) (path->string f))] - [f (and f (if (absolute-path? f) `(file ,f) f))] - ;; try a quoted one if the above failed - [m (or f (and (module-name? dtm) `',dtm))] - [m (and m (if (syntax? spec) (datum->syntax spec m spec) m))]) - (or m spec)))) - (define (translate arg convert) - (and arg (if (memq flag '(list list+)) (map convert arg) (convert arg)))) - (let loop ([kind kind]) - (case kind - [(line) (get read-line-arg)] - [(string) (get read-string-arg)] - [(path) (translate (loop 'string) expand-user-path)] - [(sexpr) (get read)] - [(syntax) (translate (get read-syntax) namespace-syntax-introduce)] - [(modspec) (translate (loop 'syntax) process-modspec)] - [else (error 'getarg "unknown arg kind: ~e" kind)]))) - -(define (run-command cmd) - (parameterize ([current-command cmd]) - (with-handlers ([void (λ (e) - (if (exn? e) - (eprintf "~a\n" (exn-message e)) - (eprintf "~s\n" e)))]) - ((command-handler (or (hash-ref commands cmd #f) - (error "Unknown command:" cmd))))))) - -(defcommand (help h ?) "[]" - "display available commands" - ["Lists known commands and their help; use with a command name to get" - "additional information for that command."] - (define arg (match (getarg 'sexpr 'opt) [(list 'unquote x) x] [x x])) - (define cmd - (and arg (hash-ref commands arg - (λ () (printf "*** Unknown command: `~s'\n" arg) #f)))) - (define (show-cmd cmd indent) - (define names (command-names cmd)) - (printf "~a~s" indent (car names)) - (when (pair? (cdr names)) (printf " ~s" (cdr names))) - (printf ": ~a\n" (command-blurb cmd))) - (if cmd - (begin (show-cmd cmd "; ") - (printf "; usage: ,~a" arg) - (let ([a (command-argline cmd)]) (when a (printf " ~a" a))) - (printf "\n") - (for ([d (in-list (command-desc cmd))]) - (printf "; ~a\n" d))) - (begin (printf "; Available commands:\n") - (for-each (λ (c) (show-cmd c "; ")) (reverse commands-list))))) - -;; ---------------------------------------------------------------------------- -;; generic commands - -(defcommand (exit quit ex) "[]" - "exit racket" - ["Optional argument specifies exit code."] - (cond [(getarg 'sexpr 'opt) => exit] [else (exit)])) - -(define last-2dirs - (make-parameter (let ([d (current-directory)]) (cons d d)))) -(define (report-directory-change [mode #f]) - (define curdir (current-directory)) - (define (report) ; remove last "/" and say where we are - (define-values [base name dir?] (split-path curdir)) - (printf "; now in ~a\n" (if base (build-path base name) curdir))) - (cond [(not (equal? (car (last-2dirs)) curdir)) - (last-2dirs (cons curdir (car (last-2dirs)))) - (report)] - [else (case mode - [(pwd) (report)] - [(cd) (printf "; still in the same directory\n")])])) - -(defcommand cd "[]" - "change the current directory" - ["Sets `current-directory'; expands user paths. With no arguments, goes" - "to your home directory. An argument of `-' indicates the previous" - "directory."] - (let* ([arg (or (getarg 'path 'opt) home-dir)] - [arg (if (equal? arg (string->path "-")) (cdr (last-2dirs)) arg)]) - (if (directory-exists? arg) - (begin (current-directory arg) (report-directory-change 'cd)) - (eprintf "cd: no such directory: ~a\n" arg)))) - -(defcommand pwd #f - "display the current directory" - ["Displays the value of `current-directory'."] - (report-directory-change 'pwd)) - -(defcommand (shell sh ls cp mv rm md rd git svn) "" - "run a shell command" - ["`sh' runs a shell command (via `system'), the aliases run a few useful" - "unix commands. (Note: `ls' has some default arguments set.)" - "If the REPL is inside some module's namespace, the command can use $F" - "which is set to the full path to this module's source file."] - (let* ([arg (getarg 'line)] - [arg (if (equal? "" arg) #f arg)] - [cmd (current-command)]) - (case cmd - [(ls) (set! cmd "ls -F")] - [(shell) (set! cmd 'sh)]) - (let ([cmd (cond [(eq? 'sh cmd) #f] - [(symbol? cmd) (symbol->string cmd)] - [else cmd])] - [here (here-path #f)]) - (putenv "F" (if here (path->string here) "")) - (unless (system (cond [(and (not cmd) (not arg)) (getenv "SHELL")] - [(not cmd) arg] - [(not arg) cmd] - [else (string-append cmd " " arg)])) - (eprintf "(exit with an error status)\n")) - (when here (putenv "F" ""))))) - -(defcommand (edit e) " ..." - "edit files in your $EDITOR" - ["Runs your $EDITOR with the specified file/s. If no files are given, and" - "the REPL is currently inside a module, the file for that module is used." - "If $EDITOR is not set, the ,drracket will be used instead."] - (define env (let ([e (getenv "EDITOR")]) (and (not (equal? "" e)) e))) - (define exe (and env (find-executable-path env))) - (cond [(not env) - (printf "~a, using the ,drracket command.\n" - (if env - (string-append "$EDITOR ("env") not found in your path") - "no $EDITOR variable")) - (run-command 'drracket)] - [(not (apply system* exe (getarg 'path 'list #:default here-path))) - (eprintf "(exit with an error status)\n")] - [else (void)])) - -(define ->running-dr #f) -(define (->dr . xs) (unless ->running-dr (start-dr)) (->running-dr xs)) -(define (start-dr) - (printf "; starting DrRacket...\n") - (define c (make-custodian)) - (define ns ((dynamic-require 'racket/gui 'make-gui-namespace))) - (parameterize ([current-custodian c] - [current-namespace ns] - [exit-handler (λ (x) - (eprintf "DrRacket shutdown.\n") - (set! ->running-dr #f) - (custodian-shutdown-all c))]) - ;; construct a kind of a fake sandbox to run drracket in - (define es - (eval '(begin (require racket/class racket/gui framework racket/file) - (define es (make-eventspace)) - es))) - (define (E expr) - (parameterize ([current-custodian c] - [current-namespace ns] - [(eval 'current-eventspace ns) es]) - (eval expr ns))) - (E '(begin - (define c (current-custodian)) - (define-syntax-rule (Q expr ...) - (parameterize ([current-eventspace es]) - (queue-callback - (λ () (parameterize ([current-custodian c]) expr ...))))) - ;; problem: right after we read commands, readline will save a new - ;; history in the prefs file which frequently collides with drr; so - ;; make it use a writeback thing, with silent failures. (actually, - ;; this is more likely a result of previously starting drr wrongly, - ;; but keep this anyway.) - (let ([t (make-hasheq)] [dirty '()]) - (preferences:low-level-get-preference - (λ (sym [dflt (λ () #f)]) - (hash-ref t sym - (λ () (let ([r (get-preference sym dflt)]) - (hash-set! t sym r) - r))))) - (preferences:low-level-put-preferences - (λ (prefs vals) - (Q (set! dirty (append prefs dirty)) - (for ([pref (in-list prefs)] [val (in-list vals)]) - (hash-set! t pref val))))) - (define (flush-prefs) - (set! dirty (remove-duplicates dirty)) - (with-handlers ([void void]) - (put-preferences dirty (map (λ (p) (hash-ref t p)) dirty)) - (set! dirty '()))) - (exit:insert-on-callback flush-prefs) - (define (write-loop) - (sleep (random 4)) - (when (pair? dirty) (Q (flush-prefs))) - (write-loop)) - (define th (thread write-loop)) - (exit:insert-on-callback (λ () (Q (kill-thread th))))) - ;; start it - (Q (dynamic-require 'drracket #f)) - ;; hide the first untitled window, so drr runs in "server mode" - (Q (dynamic-require 'drracket/tool-lib #f)) - (define top-window - (let ([ch (make-channel)]) - (Q (let ([r (get-top-level-windows)]) - (channel-put ch (and (pair? r) (car r))))) - (channel-get ch))) - (Q (when top-window (send top-window show #f)) - ;; and avoid trying to open new windows in there - (send (group:get-the-frame-group) clear)) - ;; avoid being able to quit so the server stays running, - ;; also hack: divert quitting into closing all group frames - (define should-exit? #f) - (exit:insert-can?-callback - (λ () (or should-exit? - (let ([g (group:get-the-frame-group)]) - (when (send g can-close-all?) (send g on-close-all)) - #f)))) - (require drracket/tool-lib))) ; used as usual below - (define (new) - (E '(Q (drracket:unit:open-drscheme-window #f)))) - (define open - (case-lambda - [() (E '(Q (handler:open-file)))] - [paths - (let ([paths (map path->string paths)]) - (E `(Q (let ([f (drracket:unit:open-drscheme-window ,(car paths))]) - (send f show #t) - ,@(for/list ([p (in-list (cdr paths))]) - `(begin (send f open-in-new-tab ,p) - (send f show #t)))))))])) - (define (quit) - (E `(Q (set! should-exit? #t) (exit:exit)))) - (define (loop) - (define m (thread-receive)) - (if (pair? m) - (let ([proc (case (car m) [(new) new] [(open) open] [(quit) quit] - [else (cmderror "unknown flag: -~a" (car m))])]) - (if (procedure-arity-includes? proc (length (cdr m))) - (apply proc (cdr m)) - (cmderror "bad number of arguments for the -~a flag" (car m)))) - (error '->dr "internal error")) - (loop)) - (define th (thread loop)) - (set! ->running-dr (λ (xs) (thread-send th xs))))) -(defcommand (drracket dr drr) "[-flag] ..." - "edit files in DrRacket" - ["Runs DrRacket with the specified file/s. If no files are given, and" - "the REPL is currently inside a module, the file for that module is used." - "DrRacket is launched directly, without starting a new subprocess, and it" - "is kept running in a hidden window so further invocations are immediate." - "In addition to file arguments, the arguments can have a flag that" - "specifies one of a few operations for the running DrRacket:" - "* -new: opens a new editing window. This is the default when no files are" - " given and the REPL is not inside a module," - "* -open: opens the specified file/s (or the current module's file). This" - " is the default when files are given or when inside a module." - "* -quit: exits the running instance. Quitting the application as usual" - " will only close the visible window, but it will still run in a hidden" - " window. This command should not be needed under normal circumstances."] - (let ([args (getarg 'path 'list #:default here-path)]) - (if (null? args) - (->dr 'new) - (let* ([cmd (let ([s (path->string (car args))]) - (and (regexp-match? #rx"^-" s) - (string->symbol (substring s 1))))] - [args (if cmd (cdr args) args)]) - (apply ->dr (or cmd 'open) args))))) - -;; ---------------------------------------------------------------------------- -;; binding related commands - -(defcommand (apropos ap) " ..." - "look for a binding" - ["Additional arguments restrict the shown matches. The search specs can" - "have symbols (which specify what to look for in bound names), and regexps" - "(for more complicated matches)."] - (let* ([look (map (λ (s) (cond [(symbol? s) - (regexp (regexp-quote (symbol->string s)))] - [(regexp? s) s] - [else (cmderror "bad search spec: ~e" s)])) - (getarg 'sexpr 'list))] - [look (and (pair? look) - (λ (str) (andmap (λ (rx) (regexp-match? rx str)) look)))] - [syms (map (λ (sym) (cons sym (symbol->string sym))) - (namespace-mapped-symbols))] - [syms (if look (filter (λ (s) (look (cdr s))) syms) syms)] - [syms (sort syms string] ..." - "describe a (bound) identifier" - ["For a bound identifier, describe where is it coming from; for a known" - "module, describe its imports and exports. You can use this command with" - "several identifiers. An optional numeric argument specifies phase for" - "identifier lookup."] - (define-values [try-mods? level ids/mods] - (let ([xs (getarg 'syntax 'list)]) - (if (and (pair? xs) (number? (syntax-e (car xs)))) - (values #f (syntax-e (car xs)) (cdr xs)) - (values #t 0 xs)))) - (for ([id/mod (in-list ids/mods)]) - (define dtm (syntax->datum id/mod)) - (define mod - (and try-mods? - (match dtm - [(list 'quote (and sym (? module-name?))) sym] - [(? module-name?) dtm] - [_ (let ([x (with-handlers ([exn:fail? (λ (_) #f)]) - (modspec->path dtm))]) - (cond [(or (not x) (path? x)) x] - [(symbol? x) (and (module-name? x) `',x)] - [else (error 'describe "internal error: ~s" x)]))]))) - (define bind - (cond [(identifier? id/mod) (identifier-binding id/mod level)] - [mod #f] - [else (cmderror "not an identifier or a known module: ~s" dtm)])) - (define bind? (or bind (not mod))) - (when bind? (describe-binding dtm bind level)) - (when mod (describe-module dtm mod bind?)))) -(define (describe-binding sym b level) - (define at-phase (phase->name level " (~a)")) - (cond - [(not b) - (printf "; `~s' is a toplevel (or unbound) identifier~a\n" sym at-phase)] - [(eq? b 'lexical) - (printf "; `~s' is a lexical identifier~a\n" sym at-phase)] - [(or (not (list? b)) (not (= 7 (length b)))) - (cmderror "*** internal error, racket changed ***")] - [else - (define-values [src-mod src-id nominal-src-mod nominal-src-id - src-phase import-phase nominal-export-phase] - (apply values b)) - (set! src-mod (->relname (mpi->name src-mod))) - (set! nominal-src-mod (->relname (mpi->name nominal-src-mod))) - (printf "; `~s' is a bound identifier~a,\n" sym at-phase) - (printf "; defined~a in ~a~a\n" (phase->name src-phase "-~a") src-mod - (if (not (eq? sym src-id)) (format " as `~s'" src-id) "")) - (printf "; required~a ~a\n" (phase->name import-phase "-~a") - (if (equal? src-mod nominal-src-mod) - "directly" - (format "through \"~a\"~a" - nominal-src-mod - (if (not (eq? sym nominal-src-id)) - (format " where it is defined as `~s'" nominal-src-id) - "")))) - (printf "~a" (phase->name nominal-export-phase "; (exported-~a)\n"))])) -(define (describe-module sexpr mod-path/sym also?) - (define get - (if (symbol? mod-path/sym) - (let ([spec `',mod-path/sym]) - (λ (imp?) ((if imp? module->imports module->exports) spec))) - (let ([code (get-module-code mod-path/sym)]) - (λ (imp?) - ((if imp? module-compiled-imports module-compiled-exports) code))))) - (define (phase p1 0) (> p2 0)) (< p1 p2)] - [(and (< p1 0) (< p2 0)) (> p1 p2)] - [else (> p1 0)])) - (define (modnamestring x) (symbol->string y))] - [(and (symbol? x) (string? y)) #t] - [(and (string? x) (symbol? y)) #f] - [else (error 'describe-module "internal error: ~s, ~s" x y)])) - (define imports - (filter-map - (λ (x) - (and (pair? (cdr x)) - (cons (car x) (sort (map (λ (m) (->relname (mpi->name m))) (cdr x)) - modnamerelname mod-path/sym)]) - (printf "; ~a~a\n" - (if (symbol? relname) "defined directly as '" "located at ") - relname)) - (if (null? imports) - (printf "; no imports.\n") - (parameterize ([wrap-prefix "; "]) - (for ([imps (in-list imports)]) - (let ([phase (car imps)] [imps (cdr imps)]) - (wprintf "; imports~a: ~a" (phase->name phase "-~a") (car imps)) - (for ([imp (in-list (cdr imps))]) (wprintf ", ~a" imp)) - (wprintf ".\n"))))) - (define (show-exports exports kind) - (parameterize ([wrap-prefix "; "]) - (for ([exps (in-list exports)]) - (let ([phase (car exps)] [exps (cdr exps)]) - (wprintf "; direct ~a exports~a: ~a" - kind (phase->name phase "-~a") (car exps)) - (for ([exp (in-list (cdr exps))]) (wprintf ", ~a" exp)) - (wprintf ".\n"))))) - (if (and (null? val-exports) (null? stx-exports)) - (printf "; no direct exports.\n") - (begin (show-exports val-exports "value") - (show-exports stx-exports "syntax")))) - -(define help-id (make-lazy-identifier 'help 'racket/help)) -(defcommand doc " ..." - "browse the racket documentation" - ["Uses Racket's `help' to browse the documentation. (Note that this can be" - "used even in languages that don't have the `help' binding.)"] - (eval-sexpr-for-user `(,(help-id) ,@(getarg 'syntax 'list)))) - -;; ---------------------------------------------------------------------------- -;; require/load commands - -(defcommand (require req r) " ...+" - "require a module" - ["The arguments are usually passed to `require', unless an argument" - "specifies an existing filename -- in that case, it's like using a" - "\"string\" or a (file \"...\") in `require'. (Note: this does not" - "work in subforms.)"] - (more-inputs #`(require #,@(getarg 'modspec 'list+)))) ; use *our* `require' - -(define rr-modules (make-hash)) ; hash to remember reloadable modules - -(define last-rr-specs '()) - -(defcommand (require-reloadable reqr rr) " ..." - "require a module, make it reloadable" - ["Same as ,require but the module is required in a way that makes it" - "possible to reload later. If it was already loaded then it is reloaded." - "Note that this is done by setting `compile-enforce-module-constants' to" - "#f, which prohibits some optimizations."] - (let ([s (getarg 'modspec 'list)]) (when (pair? s) (set! last-rr-specs s))) - (when (null? last-rr-specs) (cmderror "missing modspec arguments")) - (parameterize ([compile-enforce-module-constants - (compile-enforce-module-constants)]) - (compile-enforce-module-constants #f) - (for ([spec (in-list last-rr-specs)]) - (define datum (syntax->datum spec)) - (define resolved ((current-module-name-resolver) datum #f #f #f)) - (define path (resolved-module-path-name resolved)) - (if (hash-ref rr-modules resolved #f) - ;; reload - (begin (printf "; reloading ~a\n" path) - (parameterize ([current-module-declare-name resolved]) - (load/use-compiled path))) - ;; require - (begin (hash-set! rr-modules resolved #t) - (printf "; requiring ~a\n" path) - ;; (namespace-require spec) - (eval #`(require #,spec))))))) - -(define enter!-id (make-lazy-identifier 'enter! 'racket/enter)) - -(defcommand (enter en) "[] [noisy?]" - "require a module and go into its namespace" - ["Uses `enter!' to go into the module's namespace. A module name can" - "specify an existing file as with the ,require command. If no module is" - "given, and the REPL is already in some module's namespace, then `enter!'" - "is used with that module, causing it to reload if needed. (Note that this" - "can be used even in languages that don't have the `enter!' binding.)"] - (eval-sexpr-for-user `(,(enter!-id) - ,(getarg 'modspec #:default here-mod-or-eof) - ,@(getarg 'syntax 'list) - #:dont-re-require-enter))) - -(defcommand (toplevel top) #f - "go back to the toplevel" - ["Go back to the toplevel, same as ,enter with no arguments."] - (eval-sexpr-for-user `(,(enter!-id) #f))) - -(defcommand (load ld) " ..." - "load a file" - ["Uses `load' to load the specified file(s)."] - (more-inputs* (map (λ (name) #`(load #,name)) (getarg 'path 'list)))) - -;; ---------------------------------------------------------------------------- -;; debugging commands - -;; not useful: catches only escape continuations -;; (define last-break-exn (make-parameter #f)) -;; (defcommand (continue cont) #f -;; "continue from a break" -;; ["Continue running from the last break."] -;; (if (last-break-exn) -;; ((exn:break-continuation (last-break-exn))) -;; (cmderror 'continue "no break exception to continue from"))) - -(define time-id - (make-lazy-identifier 'time* '(only-in unstable/time [time time*]))) -(defcommand time "[] ..." - "time an expression" - ["Times execution of an expression, similar to `time' but prints a" - "little easier to read information. You can provide an initial number" - "that specifies how many times to run the expression -- in this case," - "the expression will be executed that many times, extreme results are" - "removed (top and bottom 2/7ths), and the remaining results will be" - "averaged. Two garbage collections are triggered before each run; the" - "resulting value(s) are from the last run."] - (more-inputs #`(#,(time-id) #,@(getarg 'syntax 'list)))) - -(define trace-id (make-lazy-identifier 'trace 'racket/trace)) -(defcommand (trace tr) " ..." - "trace a function" - ["Traces a function (or functions), using the `racket/trace' library."] - (eval-sexpr-for-user `(,(trace-id) ,@(getarg 'syntax 'list)))) - -(define untrace-id (make-lazy-identifier 'untrace 'racket/trace)) -(defcommand (untrace untr) " ..." - "untrace a function" - ["Untraces functions that were traced with ,trace."] - (eval-sexpr-for-user `(,(untrace-id) ,@(getarg 'syntax 'list)))) - -(defautoload errortrace - profiling-enabled instrumenting-enabled clear-profile-results - output-profile-results execute-counts-enabled annotate-executed-file) - -(defcommand (errortrace errt inst) "[]" - "errortrace instrumentation control" - ["An argument is used to perform a specific operation:" - " + : turn errortrace instrumentation on (effective only for code that is" - " evaluated from now on)" - " - : turn it off (also only for future evaluations)" - " ? : show status without changing it" - "With no arguments, toggles instrumentation."] - (case (getarg 'sexpr 'opt) - [(#f) (if (autoloaded? 'errortrace) - (instrumenting-enabled (not (instrumenting-enabled))) - (instrumenting-enabled #t))] - [(-) (when (autoloaded? 'errortrace) (instrumenting-enabled #f))] - [(+) (instrumenting-enabled #t)] - [(?) (void)] - [else (cmderror "unknown subcommand")]) - (if (autoloaded? 'errortrace) - (printf "; errortrace instrumentation is ~a\n" - (if (instrumenting-enabled) "on" "off")) - (printf "; errortrace not loaded\n"))) - -(define profile-id - (make-lazy-identifier 'profile 'profile)) -(define (statistical-profiler) - (more-inputs #`(#,(profile-id) #,(getarg 'syntax)))) -(define (errortrace-profiler) - (instrumenting-enabled #t) - (define flags (regexp-replace* #rx"[ \t]+" (getarg 'line) "")) - (for ([cmd (in-string (if (equal? "" flags) - (if (profiling-enabled) "*!" "+") - flags))]) - (case cmd - [(#\+) (profiling-enabled #t) (printf "; profiling is on\n")] - [(#\-) (profiling-enabled #f) (printf "; profiling is off\n")] - [(#\*) (output-profile-results #f #t)] - [(#\#) (output-profile-results #f #f)] - [(#\!) (clear-profile-results) (printf "; profiling data cleared\n")] - [else (cmderror "unknown subcommand")]))) -(defcommand (profile prof) "[ | ...]" - "profiler control" - ["Runs either the exact errortrace-based profiler, or the statistical one." - "* If a parenthesized expression is given, run the statistical profiler" - " while running it. This profiler requires no special setup and adds" - " almost no overhead, it samples stack traces as execution goes on." - "* Otherwise the errortrace profiler is used. This profiler produces" - " precise results, but like other errortrace uses, it must be enabled" - " before loading the code and it adds noticeable overhead. In this case," - " an argument is used to determine a specific operation:" - " + : turn the profiler on (effective only for code that is evaluated" - " from now on)" - " - : turn the profiler off (also only for future evaluations)" - " * : show profiling results by time" - " # : show profiling results by counts" - " ! : clear profiling results" - " Multiple flags can be combined, for example \",prof *!-\" will show" - " profiler results, clear them, and turn it off." - "* With no arguments, turns the errortrace profiler on if it's off, and if" - " it's on it shows the collected results and clears them." - "Note: using no arguments or *any* of the flags turns errortrace" - " instrumentation on, even a \",prof -\". Use the ,errortrace command if" - " you want to turn instrumentation off."] - (if (memq (skip-spaces/peek) '(#\( #\[ #\{)) - (statistical-profiler) - (errortrace-profiler))) - -(defcommand execution-counts " ..." - "execution counts" - ["Enable errortrace instrumentation for coverage, require the file(s)," - "display the results, disables coverage, and disables instrumentation if" - "it wasn't previously turned on."] - (let ([files (getarg 'path 'list)] - [inst? (and (autoloaded? 'errortrace) (instrumenting-enabled))]) - (more-inputs - (λ () - (instrumenting-enabled #t) - (execute-counts-enabled #t)) - #`(require #,@(map (λ (file) `(file ,(path->string file))) files)) - (λ () - (for ([file (in-list files)]) - (annotate-executed-file file " 123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) - (λ () - (execute-counts-enabled #f) - (unless inst? (instrumenting-enabled #f)))))) - -(defautoload racket/sandbox - make-module-evaluator kill-evaluator call-with-trusted-sandbox-configuration - sandbox-coverage-enabled get-uncovered-expressions) - -(defcommand (coverage cover) "" - "coverage information via a sandbox" - ["Runs the given file in a (trusted) sandbox, and annotates it with" - "uncovered expression information."] - (let ([file (getarg 'path)]) - (sandbox-coverage-enabled) ; autoload it - (parameterize ([sandbox-coverage-enabled #t]) - (define e - (call-with-trusted-sandbox-configuration - (λ () (make-module-evaluator file)))) - (define uncovered - (map (λ (x) (let ([p (sub1 (syntax-position x))]) - (cons p (+ p (syntax-span x))))) - (get-uncovered-expressions e #t))) - (kill-evaluator e) - (call-with-input-file file - (λ (inp) - ;; this is a naive and inefficient solution, could be made efficient - ;; using `mzlib/integer-set' - (let loop () - (let* ([start (file-position inp)] - [line (read-line inp)] - [len (and (string? line) (string-length line))] - [end (and len (+ len start))] - [indent (and len (regexp-match-positions #px"\\S" line))] - [indent (and indent (caar indent))]) - (when len - (displayln line) - (when indent - (string-fill! line #\space) - (for ([u (in-list uncovered)]) - (when (and ((car u) . < . end) - ((cdr u) . > . indent)) - (for ([i (in-range (max (- (car u) start) indent) - (min (- (cdr u) start) len))]) - (string-set! line i #\^)))) - (displayln (regexp-replace #rx" +$" line ""))) - (loop))))))))) - -;; ---------------------------------------------------------------------------- -;; namespace switching - -(define default-namespace-name '*) -(define current-namespace-name (make-parameter default-namespace-name)) -(define namespaces - (let* ([r (namespace-symbol->identifier '#%top-interaction)] - [r (identifier-binding r)] - [r (and r (mpi->name (caddr r)))] - [t (make-hasheq)]) - (hash-set! t (current-namespace-name) (cons (current-namespace) r)) - t)) -(defcommand (switch-namespace switch) "[] [? | - | ! []]" - "switch to a different repl namespace" - ["Switch to the namespace, creating it if needed. The of a" - "namespace is a symbol or an integer where a `*' indicates the initial one;" - "it is only used to identify namespaces for this command (so don't confuse" - "it with racket bindings). A new namespace is initialized using the name" - "of the namespace (if it's require-able), or using the same initial module" - "that was used for the current namespace. If `! ' is used, it" - "indicates that a new namespace will be created even if it exists, using" - "`' as the initial module, and if just `!' is used, then this happens" - "with the existing namespace's init or with the current one's. You can" - "also use `-' and a name to drop the corresponding namespace (allowing it" - "to be garbage-collected), and `?' to list all known namespaces." - "A few examples:" - " ,switch ! reset the current namespace" - " ,switch ! racket reset it using the `racket' language" - " ,switch r5rs switch to a new `r5rs' namespace" - " ,switch foo switch to `foo', creating it if it doesn't exist" - " ,switch foo ! racket switch to newly made `foo', even if it exists" - " ,switch foo ! same, but using the same as it was created" - " with, or same as the current if it's new" - " ,switch ? list known namespaces, showing the above two" - " ,switch - r5rs drop the `r5rs' namespace" - "(Note that you can use `^' etc to communicate values between namespaces.)"] - (define (list-namespaces) - (printf "; namespaces and their languages:\n") - (define nss (sort (map (λ (x) (cons (format "~s" (car x)) (cddr x))) - (hash-map namespaces cons)) - string no need to set the current directory - (file-exists? (modspec->path name)))) - ;; if there's an , then it must be forced - (let* ([name (or name (current-namespace-name))] - [init - (cond [init] - [(or force-reset? (not (hash-ref namespaces name #f))) - (when (eq? name default-namespace-name) - ;; no deep reason for this, but might be usful to keep it - ;; possible to ,en xrepl/xrepl to change options etc - (cmderror "cannot reset the default namespace")) - (cdr (or (hash-ref namespaces name #f) - (and (is-require-able? name) (cons #f name)) - (hash-ref namespaces (current-namespace-name) #f) - ;; just in case - (hash-ref namespaces default-namespace-name #f)))] - [else #f])]) - (when init - (printf "; *** ~a `~s' namespace with ~s ***\n" - (if (hash-ref namespaces name #f) - "Resetting the" "Initializing a new") - name - (->relname init)) - (current-namespace (make-base-empty-namespace)) - (namespace-require init) - (hash-set! namespaces name (cons (current-namespace) init)))) - (when (and name (not (eq? name (current-namespace-name)))) - (printf "; *** Switching to the `~s' namespace ***\n" name) - (let ([x (hash-ref namespaces (current-namespace-name))]) - (unless (eq? (car x) old-namespace) - (printf "; (note: saving current namespace for `~s')\n" - (current-namespace-name)) - (hash-set! namespaces (current-namespace-name) - (cons old-namespace (cdr x))))) - (current-namespace-name name) - (current-namespace (car (hash-ref namespaces name))))) - (define (syntax-error) - (cmderror "syntax error, see ,help switch-namespace")) - (match (getarg 'sexpr 'list) - [(list) (cmderror "what do you want to do?")] - [(list '?) (list-namespaces)] - [(list '? _ ...) (syntax-error)] - [(list '- name) (delete name)] - [(list '- _ ...) (syntax-error)] - [(list '!) (switch #f #t #f )] - [(list '! init) (switch #f #t init)] - [(list name) (switch name #f #f )] - [(list name '!) (switch name #t #f )] - [(list name '! init) (switch name #t init)] - [_ (syntax-error)])) - -;; ---------------------------------------------------------------------------- -;; syntax commands - -(define current-syntax (make-parameter #f)) -(defautoload racket/pretty pretty-write) -(defautoload macro-debugger/stepper-text expand/step-text) -(define not-in-base - (λ () (let ([base-stxs #f]) - (unless base-stxs - (set! base-stxs ; all ids that are bound to a syntax in racket/base - (parameterize ([current-namespace hidden-namespace]) - (let-values ([(vals stxs) (module->exports 'racket/base)]) - (map (λ (s) (namespace-symbol->identifier (car s))) - (cdr (assq 0 stxs))))))) - (λ (id) (not (ormap (λ (s) (free-identifier=? id s)) base-stxs)))))) -(define (macro-stepper . args) - (define-values [i o] (make-pipe)) - (parameterize ([current-output-port o]) - (thread (λ () (apply expand/step-text args) (close-output-port o)))) - (let loop () - (define l (read-line i)) - (unless (eof-object? l) - ;; hack: beautify the stepper's output -- remove empty line, indent code - (unless (equal? "" l) - (printf (if (regexp-match? #px"^[A-Z][a-z]+\\b" l) - "; ---- ~a ----\n" "; ~a\n") - l)) - (loop)))) -(defcommand (syntax stx st) "[] [ ...]" - "set syntax object to inspect, and control it" - ["With no arguments, will show the previously set (or expanded) syntax" - "additional arguments serve as an operation to perform:" - "- `^' sets the syntax from the last entered expression" - "- other sexprs set the current syntax explicitly" - "- `+' will `expand-once' the syntax and show the result (can be used again" - " for additional `expand-once' steps)" - "- `!' will `expand' the syntax and show the result" - "- `*' will use the syntax stepper to show expansion steps, leaving macros" - " from racket/base intact (does not change the currently set syntax)" - "- `**' similar to `*', but expanding everything" - "Note that you can specify several syntaxes and operations in a single" - "invocation."] - (define args (getarg 'syntax 'list)) - (for ([stx (in-list (if (null? args) '(#f) args))]) - (define (show/set label stx) - (printf "; ~a\n" label) - (current-syntax stx) - (display "; ") (pretty-write (syntax->datum stx))) - (define (cur) (or (current-syntax) (cmderror "no syntax set yet"))) - (case (and stx (if (identifier? stx) (syntax-e stx) '--none--)) - [(#f) (show/set "Current syntax:" (cur))] - [(^) (if (last-input-syntax) - (show/set "Using last expression:" (last-input-syntax)) - (cmderror "no expression entered yet"))] - [(+) (show/set "expand-once ->" (expand-once (cur)))] - [(!) (show/set "expand ->" (expand (cur)))] - [(*) (printf "; Stepper:\n") (macro-stepper (cur) (not-in-base))] - [(**) (printf "; Stepper:\n") (macro-stepper (cur))] - [else - (if (syntax? stx) - (begin (printf "; Syntax set\n") (current-syntax stx)) - (cmderror "internal error: ~s ~s" stx (syntax? stx)))]))) - -;; ---------------------------------------------------------------------------- -;; dynamic log output control - -(define current-log-receiver-thread (make-parameter #f)) -(define global-logger (current-logger)) - -(defcommand log "" - "control log output" - ["Starts (or stops) logging events at the given level. The level should be" - "one of the valid racket logging levels, or #f for no logging. For" - "convenience, the level can also be #t (maximum logging) or an integer" - "(with 0 for no logging, and larger numbers for more logging output)."] - (define levels '(#f fatal error warning info debug)) - (define level - (let ([l (getarg 'sexpr)]) - (cond [(memq l levels) l] - [(memq l '(#f none -)) #f] - [(memq l '(#t all +)) (last levels)] - [(not (integer? l)) - (cmderror "bad level, expecting one of: ~s" levels)] - [(<= l 0) #f] - [(< l (length levels)) (list-ref levels l)] - [else (last levels)]))) - (cond [(current-log-receiver-thread) => kill-thread]) - (when level - (let ([r (make-log-receiver global-logger level)]) - (current-log-receiver-thread - (thread - (λ () - (let loop () - (match (sync r) - [(vector l m v) - (display (format "; [~a] ~a~a\n" - l m (if v (format " ~.s" v) ""))) - (flush-output)]) - (loop)))))))) - -;; ---------------------------------------------------------------------------- -;; meta evaluation hook - -;; questionable value, (and need to display the resulting values etc) -#; -(defcommand meta "" - "meta evaluation" - ["Evaluate the given expression where bindings are taken from the xrepl" - "module. This is convenient when you're in a namespace that does not have" - "a specific binding -- for example, you might be using a language that" - "doesn't have `current-namespace', so to get it, you can use" - "`,eval (current-namespace)'. The evaluation happens in the repl namespace" - "as usual, only the bindings are taken from the xrepl module -- so you can" - "use `^' to refer to the result of such an evaluation."] - (eval (datum->syntax #'here `(#%top-interaction . ,(getarg 'sexpr)))) - (void)) - -;; ---------------------------------------------------------------------------- -;; setup xrepl in the user's racketrc file - -(define init-file (find-system-path 'init-file)) -(defcommand install! #f - "install xrepl in your Racket init file" - ["Installs xrepl in your Racket REPL initialization file. This is done" - "carefully: I will tell you about the change, and ask for permission." - "You can then edit the file if you want to; in your system, you can find it" - ,(format "at \"~a\"." init-file)] - (define comment "The following line loads `xrepl' support") - (define expr "(require xrepl)") - (define dexpr "(dynamic-require 'xrepl #f)") - (define contents (file->string init-file)) - (read-line) ; discard the newline for further input - (define (look-for comment-rx expr) - (let ([m (regexp-match-positions - (format "(?<=\r?\n|^) *;+ *~a *\r?\n *~a *(?=\r?\n|$)" - comment-rx (regexp-quote expr)) - contents)]) - (and m (car m)))) - (define existing? (look-for (regexp-quote comment) expr)) - (define existing-readline? - (look-for "load readline support[^\r\n]*" "(require readline/rep)")) - (define (yes?) (flush-output) (regexp-match? #rx"^[yY]" (getarg 'line))) - (cond - [existing? - (printf "; already installed, nothing to do\n") - (when existing-readline? - (printf "; (better to remove the readline loading, xrepl does that)"))] - [(let ([m (regexp-match - (string-append (regexp-quote expr) "|" (regexp-quote dexpr)) - contents)]) - (and m (begin (printf "; found \"~a\", ~a\n" - (car m) "looks like xrepl is already installed") - (printf "; should I continue anyway? ") - (not (yes?)))))] - [else - (when existing-readline? - (printf "; found a `readline' loading line\n") - (printf "; xrepl will already do that, ok to remove? ") - (if (yes?) - (set! contents (string-append - (substring contents 0 (car existing-readline?)) - (substring contents (cdr existing-readline?)))) - (printf "; it will be kept ~a\n" - "(you can edit the file and removing it later)"))) - (printf "; writing new contents, with an added \"~a\"\n" expr) - (printf "; (if you want to load it conditionally, edit the file and\n") - (printf "; use \"~a\" instead, which is a plain expression)\n" dexpr) - (printf "; OK to continue? ") - (if (yes?) - (begin - (call-with-output-file* init-file #:exists 'truncate - (λ (o) (write-string - (string-append (regexp-replace #rx"(?:\r?\n)+$" contents "") - (format "\n\n;; ~a\n~a\n" comment expr)) - o))) - (printf "; new contents written to ~a\n" init-file)) - (printf "; ~a was not updated\n" init-file))]) - (void)) - -;; ---------------------------------------------------------------------------- -;; eval hook that keep track of recent evaluation results - -;; saved interaction values -(define saved-values (make-parameter '())) -(define (save-values! xs) - (let ([xs (filter (λ (x) (not (void? x))) xs)]) ; don't save void values - (unless (null? xs) - ;; the order is last, 2nd-to-last, ..., same from prev interactions - ;; the idea is that `^', `^^', etc refer to the values as displayed - (saved-values (append (reverse xs) (saved-values))) - (let ([n (saved-values-number)] [l (saved-values)]) - (when (< n (length l)) (saved-values (take l n))))))) - -(define last-saved-names+state (make-parameter '(#f #f #f))) -(define (get-saved-names) - (define last (last-saved-names+state)) - (define last-num (cadr last)) - (define last-char (caddr last)) - (define cur-num (saved-values-number)) - (define cur-char (saved-values-char)) - (if (and (equal? last-num cur-num) (equal? last-char cur-char)) - (car last) - (let ([new (for/list ([i (in-range (saved-values-number))]) - (string->symbol (make-string (add1 i) (saved-values-char))))]) - (last-saved-names+state (list new cur-num cur-char)) - new))) - -;; make saved values available through bindings, but do this in a way that -;; doesn't interfere with users using these binders in some way -- set only ids -;; that were void, and restore them to void afterwards -(define (with-saved-values thunk) - (define saved-names (get-saved-names)) - (define vals (for/list ([id (in-list saved-names)]) - (box (namespace-variable-value id #f void)))) - (define res #f) - (dynamic-wind - (λ () - (for ([id (in-list saved-names)] - [saved (in-list (saved-values))] - [v (in-list vals)]) - ;; set only ids that are void, and remember these values - (if (void? (unbox v)) - (begin (namespace-set-variable-value! id saved) - (set-box! v saved)) - (set-box! v (void))))) - (λ () (call-with-values thunk (λ vs (set! res vs) (apply values vs)))) - (λ () - (for ([id (in-list saved-names)] [v (in-list vals)]) - ;; restore the names to void so we can set them next time - (when (and (not (void? (unbox v))) ; restore if we set this id above - (eq? (unbox v) ; and if it didn't change - (namespace-variable-value id #f void))) - (namespace-set-variable-value! id (void)))) - (when res (save-values! res))))) - -(provide make-xrepl-evaluator) -(define (make-xrepl-evaluator builtin-evaluator) - (λ (expr) - ;; not useful: catches only escape continuations - ;; (with-handlers ([exn:break? (λ (e) (last-break-exn e) (raise e))]) ...) - (if (saved-values) - (with-saved-values (λ () (builtin-evaluator expr))) - (builtin-evaluator expr)))) - -;; ---------------------------------------------------------------------------- -;; capture ",..." and run the commands, use readline/rep when possible - -(define get-prefix ; to show before the "> " prompt - (let () - (define (choose-path x) - ;; choose the shortest from an absolute path, a relative path, and a - ;; "~/..." path. - (if (not (complete-path? x)) ; shouldn't happen - x - (let* ([r (path->string (find-relative-path (current-directory) x))] - [h (path->string (build-path (string->path-element "~") - (find-relative-path home-dir x)))] - [best (if (< (string-length r) (string-length h)) r h)] - [best (if (< (string-length best) (string-length x)) best x)]) - best))) - (define (get-prefix* path) - (define x (path->string path)) - (define y (->relname path)) - (if (equal? x y) - (format "~s" (choose-path x)) - (regexp-replace #rx"[.]rkt$" y ""))) - (define (get-prefix) - (let* ([x (here-source)] - [x (and x (if (symbol? x) (format "'~s" x) (get-prefix* x)))] - [x (or x (toplevel-prefix))]) - (if (eq? (current-namespace-name) default-namespace-name) - x (format "~a::~a" (current-namespace-name) x)))) - (define last-directory #f) - (define last-namespace #f) - (define prefix #f) - (λ () - (define curdir (current-directory)) - (unless (and (equal? (current-namespace) last-namespace) - (equal? curdir last-directory)) - (report-directory-change) - (set! prefix - (with-handlers - ([exn? (λ (e) - (eprintf "error during prompt calculation: ~a\n" - (exn-message e)) - "[internal-error]")]) - (get-prefix))) - (set! last-namespace (current-namespace)) - (set! last-directory curdir)) - prefix))) - -;; the last non-command expression read -(define last-input-syntax (make-parameter #f)) - -(struct more-inputs (list) - #:constructor-name more-inputs* #:omit-define-syntaxes) -(define (more-inputs . inputs) (more-inputs* inputs)) - -(provide make-xrepl-reader) -(define (make-xrepl-reader) - (define (plain-reader prefix) ; a plain reader, without readline - (display prefix) (display "> ") (flush-output) (zero-column!) - (let ([in ((current-get-interaction-input-port))]) - ((current-read-interaction) (object-name in) in))) - (define RL ; no direct dependency on readline - (with-handlers ([exn? (λ (_) #f)]) - (collection-file-path "pread.rkt" "readline"))) - (define (make-readline-reader) - (let ([p (dynamic-require RL 'current-prompt)] - [r (dynamic-require RL 'read-cmdline-syntax)]) - (λ (prefix) ; uses the readline prompt - (parameterize ([p (bytes-append (string->bytes/locale prefix) (p))]) - (r))))) - (define reader - (case (object-name (current-input-port)) - [(stdin) - (if (or (not (terminal-port? (current-input-port))) - (regexp-match? #rx"^dumb" (or (getenv "TERM") "")) - (not RL)) - plain-reader - (with-handlers ([exn? - (λ (e) - (eprintf "Warning: no readline support (~a)\n" - (exn-message e)) - plain-reader)]) - (dynamic-require 'readline/rep-start #f) - ;; requiring readline should have changed the reader - (if (eq? (current-prompt-read) - (dynamic-require RL 'read-cmdline-syntax)) - (make-readline-reader) - (begin (eprintf "Warning: could not initialize readline\n") - plain-reader))))] - [(readline-input) - (eprintf "Note: readline already loaded\n~a\n" - " (better to let xrepl load it for you)") - (make-readline-reader)] - [else plain-reader])) - ;; IO management - (port-count-lines! (current-input-port)) - ;; wrap the reader to get the command functionality - (define more-inputs '()) - (define (reader-loop) - (parameterize ([saved-values #f]) - (define from-queue? (pair? more-inputs)) - (define input - (if from-queue? - (begin0 (car more-inputs) (set! more-inputs (cdr more-inputs))) - (begin (fresh-line) (reader (get-prefix))))) - (syntax-case input () - [(uq cmd) (eq? 'unquote (syntax-e #'uq)) - (let ([r (run-command (syntax->datum #'cmd))]) - (cond [(void? r) (reader-loop)] - [(more-inputs? r) - (set! more-inputs (append (more-inputs-list r) more-inputs)) - (reader-loop)] - [else (eprintf "Warning: internal weirdness: ~s\n" r) r]))] - [_ (begin (unless from-queue? (last-input-syntax input)) input)]))) - reader-loop) diff --git a/collects/xrepl/xrepl.scrbl b/collects/xrepl/xrepl.scrbl deleted file mode 100644 index b6654962a7..0000000000 --- a/collects/xrepl/xrepl.scrbl +++ /dev/null @@ -1,496 +0,0 @@ -#lang scribble/doc -@(require scribble/manual "doc-utils.rkt" - scribble/decode (only-in scribble/core) - (for-label racket readline racket/help racket/enter - racket/trace profile)) - -@title{XREPL: eXtended REPL} -@author+email["Eli Barzilay" "eli@barzilay.org"] - -@defmodule[xrepl]{ - The @filepath{xrepl} collection extends the @exec{racket} @tech[#:doc - GUIDE]{REPL} significantly, turning it into a more useful tool for - interactive exploration and development. This includes ``meta - commands'', using readline, keeping past evaluation results, and - more.} - -@; --------------------------------------------------------------------- -@section{Installing XREPL} - -To use XREPL, start @exec{racket} and enter @racket[(require xrepl)]. -You will know that it works when the prompt changes to a @litchar{->}, -and, if you're working on a capable terminal, you will now have readline -editing. You can also start @exec{racket} and ask for XREPL to be -loaded using command-line arguments: -@commandline{racket -il xrepl} - -If you want to enable XREPL automatically, add this expression to your -Racket initialization file. -@margin-note*{To load XREPL conditionally (e.g., not in older Racket - versions), you can use @racket[(dynamic-require 'xrepl #f)]. This - is a plain expression that can be placed inside @racket[when] and - elsewhere.} -An easy way to do the necessary editing is to enter @cmd[install!], -which will inspect and edit your initialization file (it will describe -the change and ask for your permission). Alternatively, you can edit -the file directly: on Unix, it is @filepath{~/.racketrc}, and for -other platforms evaluate @racket[(find-system-path 'init-file)] to see -where it is. - -XREPL will set up a readline-based reader, so you do not need to load -that yourself. If your initialization file was previously set to load -readline via @racket[install-readline!], the @cmd[install!] command -will (notify you and) remove it. If you added it yourself, consider -removing it. (This is not strictly needed, but XREPL is slightly -better at detecting when to use readline.) - -@; --------------------------------------------------------------------- -@section{Meta REPL Commands} - -Most of the XREPL extensions are implemented as meta commands. These -commands are entered at the REPL, prefixed by a @litchar{,} and followed -by the command name. Note that several commands correspond directly to -Racket functions (e.g., @cmd[exit]) --- but since they work outside of -your REPL, they can be used even if the matching bindings are not -available. - -@; --------------------------------- -@subsection{Generic Commands} - -@defcmd[help]{ - Without an argument, displays a list of all known commands. Specify a - command to get help specific to that command. -} - -@defcmd[exit]{ - Exits Racket, optionally with an error code (see @racket[exit]). -} - -@defcmd[cd]{ - Sets the @racket[current-directory] to the given path. If no path is - specified, use your home directory. Path arguments are passed through - @racket[expand-user-path] so you can use @litchar{~}. An argument of - @litchar{-} means ``the previous path''. -} - -@defcmd[pwd]{ - Reports the value of @racket[current-directory]. -} - -@defcmd[shell]{ - Use @cmd[shell] (or @cmd[sh]) to run a generic shell command (via - @racket[system]). For convenience, a few synonyms are provided --- - they run the specified executables (still using @racket[system]). - - When the REPL is in the context of a module with a known source file, - the shell command can use the @envvar{F} environment variable as the - path to the file. Otherwise, @envvar{F} is set to an empty string. -} - -@defcmd[edit]{ - Runs an editor, as specified by your @envvar{EDITOR} environment - variable, with the given file/s arguments. If no files are specified - and the REPL is currently inside a module's namespace, then the file - for that module is used. If the @envvar{EDITOR} environment variable - is not set, use the @cmd[drracket] command instead. -} - -@defcmd[drracket]{ - Runs DrRacket with the specified file/s. If no files are given, and - the REPL is currently inside a module, the file for that module is - used. - - DrRacket is launched directly, without starting a new subprocess, and - it is then kept running in a hidden window so further invocations are - immediate. (When this command is used for the first time, you will - see DrRacket start as usual, and then its window will disappear --- - that window is keeping DrRacket ready for quick editing.) - - In addition to file arguments, arguments can specify one of a few - flags for additional operations: - @itemize[ - @item{@litchar{-new}: opens a new editing window. This is the default - when no files are given and the REPL is not inside a module,} - @item{@litchar{-open}: opens the specified file/s (or the current - module's file). This is the default when files are given or when - inside a module.} - @item{@litchar{-quit}: exits the running DrRacket instance. Quitting - DrRacket is usually not necessary. Therefore, if you try to quit it - from the DrRacket window, it will instead just close the window but - DrRacket will still be running in the background. Use this command - in case there is some exceptional problem that requires actually - quitting the IDE. (Once you do so, future uses of this command will - start a fresh instance.)}] -} - -@; --------------------------------- -@subsection{Binding Information} - -@defcmd[apropos]{ - Searches for known bindings in the current namespace. The arguments - specify which binding to look for: use a symbol (without a - @litchar{'}) to look for bindings that contain that name, and use a - regexp (e.g., @racket[#rx"..."]) to use a regexp for the search. - Multiple arguments are and-ed together. - - If no arguments are given, @emph{all} bindings are listed. -} - -@defcmd[describe]{ - For each of the specified names, describe where where it is coming - from and how it was defined if it names a known binding. In addition, - desribe the module (list its imports and exports) that is named by - arguments that are known module names. - - By default, bindings are searched for at the runtime level (phase 0). - You can add a different phase level for identifier lookups as a first - argument. In this case, only a binding can be described, even if the - same name is a known module. -} - -@defcmd[doc]{ - Uses Racket's @racket[help] to browse the documentation, look for a - binding, etc. Note that this can be used even in languages that don't - have the @racket[help] binding. -} - -@; --------------------------------- -@subsection{Requiring and Loading Files} - -@defcmd[require]{ - Most arguments are passed to @racket[require] as is. As a - convenience, if an argument specifies an existing file name, then use - its string form to specify the require, or use a @racket[file] in case - of an absolute path. In addition, an argument that names a known - symbolic module name (e.g., one that was defined on the REPL, or a - builtin module like @racket[#%network]), then its quoted form is used. - (Note that these shorthands do not work inside require subforms like - @racket[only-in].) -} - -@defcmd[require-reloadable]{ - Same as @cmd[require], but arranges to load the code in a way that - makes it possible to reload it later, or if a module was already - loaded (using this command) then reload it. Note that the arguments - should be simple specifications, without any require macros. If no - arguments are given, use arguments from the last use of this command - (if any). - - Module reloading is enabled by turnning off the - @racket[compile-enforce-module-constants] parameter --- note that this - prohibits some opimizations, since the compiler assumes that all - bindings may change. -} - -@defcmd[enter]{ - Uses @racket[enter!] to have the REPL go `inside' a given module's - namespace. A module name can specify an existing file as with the - @cmd[require-reloadable] command. If no module is given, and the REPL - is already in some module's namespace, then `enter!' is used with that - module, causing it to reload if needed. Using @racket[#f] makes it go - back to the toplevel namespace. - - Note that this can be used even in languages that don't have the - @racket[enter!] binding. In addition, @racket[enter!] is used in a - way that does not make it require itself into the target namespace. -} - -@defcmd[toplevel]{ - Makes the REPL go back to the toplevel namespace. Same as using the - @cmd[enter] command with a @racket[#f] argument. -} - -@defcmd[load]{ - Uses @racket[load] to load the specified file(s). -} - -@; --------------------------------- -@subsection{Debugging} - -@defcmd[time]{ - Times execution of an expression (or expressions). This is similar to - @racket{time} but the information that is displayed is a bit easier to - read. - - In addition, you can provide an initial number to specify repeating - the evaluation a number of times. In this case, each iteration is - preceded by two garbage collections, and when the iteration is done - its timing information and evaluation result(s) are displayed. When - the requested number of repetitions is done, some extreme results are - removed (top and bottom 2/7ths), and the remaining results are be - averaged. Finally, the resulting value(s) are from the last run are - returned (and can be accessed via the bindings for the last few - results, see @secref["past-vals"]). -} - -@defcmd[trace]{ - Traces the named function (or functions), using @racket[trace]. -} - -@defcmd[untrace]{ - Untraces the named function (or functions), using @racket[untrace]. -} - -@defcmd[errortrace]{ - @racketmodname[errortrace] is a useful Racket library which can - provide a number of useful services like precise profiling, test - coverage, and accurate error information. However, using it can be a - little tricky. @cmd[errortrace] and a few related commands fill this - gap, making @racketmodname[errortrace] easier to use. - - @cmd[errortrace] controls global use of @racketmodname[errortrace]. - With a flag argument of @litchar{+} errortrace instrumentation is - turned on, with @litchar{-} it is turned off, and with no arguments it - is toggled. In addition, a @litchar{?} flag displays instrumentation - state. - - Remember that @racketmodname[errortrace] instrumentation hooks into - the Racket compiler, and applies only to source code that gets loaded - from source and therefore compiled. Therefore, you should use it - @emph{before} loading the code that you want to instrument. -} - -@defcmd[profile]{ - This command can perform profiling of code in one of two very - different ways: either statistical profiling via the - @racketmodname[profile] library, or using the exact profiler feature - of @racketmodname[errortrace]. - - When given a parenthesized expression, @cmd[profile] will run it via - the statistical profiler, as with the @racket[profile] form, reporting - results as usual. This profiler adds almost no overhead, and it - requires no special setup. In particular, it does not require - pre-compiling code in a special way. However, there are some - imprecise elements to this profiling: the profiler samples stack - snapshots periodically which can miss certain calls, and it is also - sensitive to some compiler optimizations like inlining procedures and - thereby not showing them in the displayed analysis. See - @other-doc['(lib "profile/scribblings/profile.scrbl")] for more - information. - - In the second mode of operation, @cmd[profile] uses the precise - @racketmodname[errortrace] profiler. This profiler produces precise - results, but like other uses of the @racketmodname[errortrace], it - must be enabled before loading the code that is to be profiled. It - can add noticeable overhead (potentially affecting the reported - runtimes), but the results are accurate in the sense that no procedure - is skipped. (For additional details, see - @other-doc['(lib "errortrace/scribblings/errortrace.scrbl")].) - - In this mode, the arguments are flags that control the profiler. A - @litchar{+} flag turns the profiler on --- and as usual with - @racketmodname[errortrace] functionality, this applies to code that is - compiled from now on. A @litchar{-} flag turns this instrumentation - off, and without any flags it is toggled. Once the profiler is - enabled, you can run some code and then use this command to report - profiling results: use @litchar{*} to show profiling results by time, - and @litchar{#} for the results by counts. Once you've seen the - results, you can evaluate additional code to collect more profiling - information, or you can reset the results with a @litchar{!} flag. - You can also combine several flags to perform the associated - operations, for example, @cmd[prof]{*!-} will show the accumulated - results, clear them, and turn profiler instrumentation off. - - Note that using @emph{any} of these flags turns errortrace - instrumentation on, even @cmd[prof]{-} (or no flags). Use the - @cmd[errortrace] command to turn off instrumentation completely. -} - -@defcmd[execution-counts]{ - This command makes it easy to use the execution counts functionality - of @racketmodname[errortrace]. Given a file name (or names), - @cmd[execution-counts] will enable errortrace instrumentation for - coverage, require the file(s), display the results, disables coverage, - and disables instrumentation (if it wasn't previously turned on). - This is useful as an indication of how well the test coverage is for - some file. -} - -@defcmd[coverage]{ - Runs a given file and displays coverage information for the run. This - is somewhat similar to the @cmd[execution-counts] command, but instead - of using @racketmodname[errortrace] directly, it runs the file in a - (trusted) sandbox, using the @racketmodname[racket/sandbox] library - and its ability to provide coverage information. -} - -@; --------------------------------- -@subsection{Miscellaneous Commands} - -@defcmd[switch-namespace]{ - This powerful command controls the REPL's namespace. While - @cmd[enter] can be used to make the REPL go into the namespace of a - specific module, the @cmd[switch-namespace] command can switch between - @emph{toplevel namespaces}, allowing you to get multiple separate - ``workspaces''. - - Namespaces are given names that are symbols or integers, where - @litchar{*} is the name for the first initial namespace, serving as - the default one. These names are not bindings --- they are only used - to label the known namespaces. - - The most basic usage for this command is to simply specify a new name. - A namespace that corresponds to that name will be created and the REPL - will switch to that namespace. The prompt will now indicate this - namespace's name. The name is usually insignificant, except when it - is a @racket[require]-able module: in this case, the new namespace is - initialized to use that module's bindings. For example, - @cmd[switch]{racket/base} creates a new namespace that is called - @litchar{racket/base} and initializes it with - @racketmodname[racket/base]. For all other names, the new namespace - is initialized the same as the current one. - - Additional @cmd[switch] uses: - @itemize[ - @item{@cmd[switch]{!} --- reset the current namespace, recreating it - using the same initial library. Note that it is forbidden to reset - the default initial namespace, the one named @litchar{*} --- this - namespace corresponds to the one that Racket was started with, and - where XREPL was initialized. There is no technical reason for - forbidding this, but doing so is not useful as no resources will - actually be freed.} - @item{@cmd[switch]{! } --- resets the current namespace with - the explicitly given simple module spec.} - @item{@cmd[switch]{ !} --- switch to a newly made namespace. If - a namespace by that name already existed, it is rest.} - @item{@cmd[switch]{ ! } --- same, but reset to the given - module instead of what it previously used.} - @item{@cmd[switch]{- } --- drop the specified namespace, making - it possible to garbage-collect away any associated resources. You - cannot drop the current namespace or the default one (@litchar{*}).} - @item{@cmd[switch]{?} --- list all known namespaces.}] - - Do not confuse namespaces with sandboxes or custodians. The - @cmd{switch} command changes @emph{only} the - @racket[current-namespace] --- it does not install a new custodian or - restricts evaluation in any way. Note that it is possible to pass - around values from one namespace to another via past result reference; - see @secref["past-vals"]. -} - -@defcmd[syntax]{ - Manipulate syntaxes and inspect their expansion. - - Useful operations revolve around a ``currently set syntax''. With no - arguments, the currently set syntax is displayed; an argument of - @litchar{^} sets the current syntax from the last input to the REPL; - and an argument that holds any other s-expression will set it as the - current syntax. - - Syntax operations are specified via flags: - @itemize[ - @item{@litchar{+} uses @racket[expand-once] on the current syntax and - prints the resulting syntax. In addition, the result becomes the - new ``current'' syntax, so you can use this as a poor-man's syntax - stepper. (Note that in some rare cases expansion via a sequence of - @racket[expand-once] might differ from the actual expansion.)} - @item{@litchar{!} uses @racket[expand] to completely expand the - current syntax.} - @item{@litchar{*} uses the macro debugger's textual output to show - expansion steps for the current syntax, leaving macros from - @racketmodname[racket/base] intact. Does not change the current - syntax. - See @other-doc['(lib "macro-debugger/macro-debugger.scrbl")] for - details.} - @item{@litchar{**} uses the macro debugger similarly to @litchar{*}, - but expands @racketmodname[racket/base] macros too, showing the - resulting full expansion process.}] - Several input flags and/or syntaxes can be spacified in succession as - arguments to @cmd{syntax}. For example, @cmd[stx]{(when 1 2) ** !}. -} - -@defcmd[log]{ - Starts (or stops) logging events at a specific level. The level can - be: - @itemize[ - @item{a known level name (currently one of @litchar{fatal}, - @litchar{error}, @litchar{warning}, @litchar{info}, - @litchar{debug}),} - @item{@racket[#f] for no logging,} - @item{@racket[#t] for maximum logging,} - @item{an integer level specification, with @racket[0] for no logging - and bigger ones for additional verbosity.}] -} - -@defcmd[install!]{ - Convenient utility command to install XREPL in your Racket - initialization file. This is done carefully, you will be notified of - potential issues, and asked to authorize changes. -} - -@; --------------------------------------------------------------------- -@section[#:tag "past-vals"]{Past Evaluation Results} - -XREPL makes the last few interaction results available for evaluation -via special toplevel variables: @racketidfont{^}, @racketidfont{^^}, -..., @racketidfont{^^^^^}. The first, @racketidfont{^}, refers to the -last result, @racketidfont{^^} to the previous one and so on. - -As with the usual REPL printouts, @void-const results are not kept. In -case of multiple results, they are spliced in reverse, so -@racketidfont{^} refers to the last result of the last evaluation. For -example: -@verbatim[#:indent 4]{ - -> 1 - 1 - -> (values 2 3) - 2 - 3 - -> (values 4) - 4 - -> (list ^ ^^ ^^^ ^^^^) - '(4 3 2 1)} -The rationale for this is that @racketidfont{^} always refers to the -last @emph{printed} result, @racketidfont{^^} to the one before that, -etc. - -These bindings are made available only if they are not already defined, -and if they are not modified. This means that if you have code that -uses these names, it will continue to work as usual. - -@; --------------------------------------------------------------------- -@section{Hacking XREPL} - -XREPL is mainly a convenience tool, and as such you might want to hack -it to better suite your needs. Currently, there is no convenient way to -customize and extend it, but this will be added in the future. - -Meanwhile, if you're interested in tweaking XREPL, the @cmd[enter] -command can be used as usual to go into its implementation. For -example --- change an XREPL parameter: -@verbatim[#:indent 4]{ - -> ,en xrepl/xrepl - xrepl/xrepl> ,e - xrepl/xrepl> (saved-values-char #\~) - xrepl/xrepl> ,top - -> 123 - 123 - -> ~ - 123} -or add a command: -@verbatim[#:indent 4]{ - -> ,en xrepl/xrepl - xrepl/xrepl> (defcommand eli "stuff" "eli says" ["Make eli say stuff"] - (printf "Eli says: ~a\n" (getarg 'line))) - xrepl/xrepl> ,top - -> ,eli moo - Eli says: moo} -While this is not intended as @emph{the} way to extend and customize -XREPL, it is a useful debugging tool should you want to do so. - -If you have any useful tweaks and extensions, please mail the author or -the Racket developer's -@hyperlink["http://racket-lang.org/community.html"]{mailing list}. - -@; --------------------------------------------------------------------- -@section{License Issues} - -Under most circumstances XREPL uses the @racketmodname[readline] -library, and therefore a similar license caveat applies: XREPL cannot be -enabled by default because of the @seclink["readline-license" #:doc -RL]{readline licensing}, you have to explicitly do so yourself to use -it. (Note that XREPL is intended to be used only for enhanced -interaction, not as a library; so there are no additional issues.) - -@; --------------------------------------------------------------------- -@(check-all-documented) From 45d34dda042cfa9553e590ce060fffb2b9be61a4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 19 Jul 2011 11:47:17 -0500 Subject: [PATCH 300/746] change autowrapping preference default please merge to release branch (cherry picked from commit 2a78ea97237e93e980b8a4ef16563882d8f03822) --- collects/framework/private/main.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/framework/private/main.rkt b/collects/framework/private/main.rkt index d29864552f..ba59746ee7 100644 --- a/collects/framework/private/main.rkt +++ b/collects/framework/private/main.rkt @@ -201,7 +201,7 @@ (preferences:set-default 'framework:windows-mdi #f boolean?) (preferences:set-default 'framework:menu-bindings #t boolean?) (preferences:set-default 'framework:verify-change-format #f boolean?) -(preferences:set-default 'framework:auto-set-wrap? #t boolean?) +(preferences:set-default 'framework:auto-set-wrap? #f boolean?) (preferences:set-default 'framework:display-line-numbers #t boolean?) (preferences:set-default 'framework:show-status-line #t boolean?) (preferences:set-default 'framework:col-offsets #f boolean?) From 533b8ed384eebb980cc1aaf9f5d055d607591123 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 19 Jul 2011 15:06:58 -0600 Subject: [PATCH 301/746] fix optimizer bug related to `case-lambda' at module level The bug triggered a crash on ARM, and probably doesn't affect other platforms, but I'm not competely sure. Merge to 5.1.2 (cherry picked from commit d9ae1d048d7ad4bbe9e516c7f48f001bcb1fdce8) --- src/racket/src/optimize.c | 105 +++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/src/racket/src/optimize.c b/src/racket/src/optimize.c index cf52296c68..83caa8e41e 100644 --- a/src/racket/src/optimize.c +++ b/src/racket/src/optimize.c @@ -3159,18 +3159,63 @@ static Scheme_Object *make_clones(Scheme_Compiled_Let_Value *retry_start, return first; } +static int set_one_code_flags(Scheme_Object *value, int flags, + Scheme_Object *first, Scheme_Object *second, + int set_flags, int mask_flags, int just_tentative, + int merge_flonum) +{ + Scheme_Case_Lambda *cl, *cl2, *cl3; + Scheme_Closure_Data *data, *data2, *data3; + int i, count; + + if (SAME_TYPE(scheme_compiled_unclosed_procedure_type, SCHEME_TYPE(value))) { + count = 1; + cl = NULL; + cl2 = NULL; + cl3 = NULL; + } else { + cl = (Scheme_Case_Lambda *)value; + cl2 = (Scheme_Case_Lambda *)first; + cl3 = (Scheme_Case_Lambda *)second; + count = cl->count; + } + + for (i = 0; i < count; i++) { + if (cl) { + data = (Scheme_Closure_Data *)cl->array[i]; + data2 = (Scheme_Closure_Data *)cl2->array[i]; + data3 = (Scheme_Closure_Data *)cl3->array[i]; + } else { + data = (Scheme_Closure_Data *)value; + data2 = (Scheme_Closure_Data *)first; + data3 = (Scheme_Closure_Data *)second; + } + + if (merge_flonum) { + merge_closure_flonum_map(data, data2); + merge_closure_flonum_map(data, data3); + merge_closure_flonum_map(data, data2); + } + + if (!just_tentative || (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_RESULT_TENTATIVE)) { + flags = (flags & SCHEME_CLOSURE_DATA_FLAGS(data)); + SCHEME_CLOSURE_DATA_FLAGS(data2) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data2) & mask_flags); + SCHEME_CLOSURE_DATA_FLAGS(data3) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data3) & mask_flags); + } + } + + return flags; +} + static int set_code_flags(Scheme_Compiled_Let_Value *retry_start, Scheme_Compiled_Let_Value *pre_body, Scheme_Object *clones, int set_flags, int mask_flags, int just_tentative, int merge_flonum) { - Scheme_Case_Lambda *cl, *cl2, *cl3; Scheme_Compiled_Let_Value *clv; Scheme_Object *value, *first; int flags = CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS; - Scheme_Closure_Data *data, *data2, *data3; - int i, count; /* The first in a clone pair is the one that is consulted for references. The second one is the clone, and it's the one whose @@ -3183,43 +3228,11 @@ static int set_code_flags(Scheme_Compiled_Let_Value *retry_start, if (IS_COMPILED_PROC(value)) { first = SCHEME_CAR(clones); - if (first) { - if (SAME_TYPE(scheme_compiled_unclosed_procedure_type, SCHEME_TYPE(value))) { - count = 1; - cl = NULL; - cl2 = NULL; - cl3 = NULL; - } else { - cl = (Scheme_Case_Lambda *)value; - cl2 = (Scheme_Case_Lambda *)SCHEME_CAR(first); - cl3 = (Scheme_Case_Lambda *)SCHEME_CDR(first); - count = cl->count; - } - - for (i = 0; i < count; i++) { - if (cl) { - data = (Scheme_Closure_Data *)cl->array[i]; - data2 = (Scheme_Closure_Data *)cl2->array[i]; - data3 = (Scheme_Closure_Data *)cl3->array[i]; - } else { - data = (Scheme_Closure_Data *)value; - data2 = (Scheme_Closure_Data *)SCHEME_CAR(first); - data3 = (Scheme_Closure_Data *)SCHEME_CDR(first); - } - - if (merge_flonum) { - merge_closure_flonum_map(data, data2); - merge_closure_flonum_map(data, data3); - merge_closure_flonum_map(data, data2); - } - - if (!just_tentative || (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_RESULT_TENTATIVE)) { - flags = (flags & SCHEME_CLOSURE_DATA_FLAGS(data)); - SCHEME_CLOSURE_DATA_FLAGS(data2) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data2) & mask_flags); - SCHEME_CLOSURE_DATA_FLAGS(data3) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data3) & mask_flags); - } - } - } + if (first) + flags = set_one_code_flags(value, flags, + SCHEME_CAR(first), SCHEME_CDR(first), + set_flags, mask_flags, just_tentative, + merge_flonum); clones = SCHEME_CDR(clones); } @@ -4352,7 +4365,6 @@ static int set_code_closure_flags(Scheme_Object *clones, int just_tentative) { Scheme_Object *clone, *orig, *first; - Scheme_Closure_Data *data; int flags = CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS; /* The first in a clone pair is the one that is consulted for @@ -4365,13 +4377,10 @@ static int set_code_closure_flags(Scheme_Object *clones, clone = SCHEME_CAR(first); orig = SCHEME_CDR(first); - data = (Scheme_Closure_Data *)orig; - if (!just_tentative || (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_RESULT_TENTATIVE)) { - flags = (flags & SCHEME_CLOSURE_DATA_FLAGS(data)); - SCHEME_CLOSURE_DATA_FLAGS(data) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data) & mask_flags); - data = (Scheme_Closure_Data *)clone; - SCHEME_CLOSURE_DATA_FLAGS(data) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data) & mask_flags); - } + flags = set_one_code_flags(orig, flags, + orig, clone, + set_flags, mask_flags, just_tentative, + 0); clones = SCHEME_CDR(clones); } From 35bbe90dcb89edc62998ed0c347e26c93a2aa36b Mon Sep 17 00:00:00 2001 From: Casey Klein Date: Wed, 20 Jul 2011 09:23:54 -0500 Subject: [PATCH 302/746] Updates Redex history for v5.1.2 (cherry picked from commit 7d103bdfd81d8099f35d3d3727308fcba0b18056) --- doc/release-notes/redex/HISTORY.txt | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/release-notes/redex/HISTORY.txt b/doc/release-notes/redex/HISTORY.txt index bf36412979..55e838c326 100644 --- a/doc/release-notes/redex/HISTORY.txt +++ b/doc/release-notes/redex/HISTORY.txt @@ -1,11 +1,35 @@ +v5.1.2 + * added support for typsetting define-relation relations * made apply-reduction-relation* call remove-duplicates on the result of apply-reduction-relation + * extended render-reduction-relation-rules to accept rule indices + in addition to rule names + + * added the to-lw/stx procedure + + * fixed domain checking for unioned reduction relations + * added the #:cache-all? argument to apply-reduction-relation* and the current-cache-all? parameter + * fixed stepper's handling of symbols that required || quoting + + * removed all undocumented exports + + * added the redex-let form + + * added the #:source argument to generate-term + + * changed redex-match to hide bindings for named ellipses such + as ..._x + + * improve test-->E failure message + + * fixed misc. bugs in examples and typos in documentation + v5.1.1 * changed pattern language to disallow unquote From 925a6ae9f25fafc69fc47c6be50f7ec6587ac1b3 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 20 Jul 2011 14:50:45 -0400 Subject: [PATCH 303/746] Fix types of kernel struct constructors to include parent fields. Merge to 5.1.2. (cherry picked from commit 7a763a2da89a1432285c06cdf9d112d04b29c762) --- .../unit-tests/typecheck-tests.rkt | 7 ++++--- .../typed-scheme/typecheck/tc-structs.rkt | 20 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt b/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt index 058749ba4a..e6a2167e50 100644 --- a/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt +++ b/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt @@ -1380,9 +1380,10 @@ exn:break arity-at-least date - srcloc) -Void) - - + srcloc) + -Void) + [tc-e (raise (exn:fail:contract "1" (current-continuation-marks))) (t:Un)] + [tc-err (exn:fail:contract)] ) (test-suite "check-type tests" diff --git a/collects/typed-scheme/typecheck/tc-structs.rkt b/collects/typed-scheme/typecheck/tc-structs.rkt index 5f62b2674e..39d7aea32c 100644 --- a/collects/typed-scheme/typecheck/tc-structs.rkt +++ b/collects/typed-scheme/typecheck/tc-structs.rkt @@ -289,16 +289,16 @@ (c-> identifier? (or/c #f identifier?) (listof identifier?) (listof Type/c) (or/c #f identifier?) #;(listof fld?) any/c) - (let* ([parent-name (if parent (make-Name parent) #f)] - [parent-flds (if parent (get-parent-flds parent-name) null)]) - (let ((defs (mk/register-sty nm flds parent-name parent-flds tys - #:mutable #t))) - (if kernel-maker - (let* ((result-type (lookup-type-name nm)) - (ty (->* tys result-type))) - (register-type kernel-maker ty) - (cons (make-def-binding kernel-maker ty) defs)) - defs)))) + (define parent-name (if parent (make-Name parent) #f)) + (define parent-flds (if parent (get-parent-flds parent-name) null)) + (define parent-tys (map fld-t parent-flds)) + (define defs (mk/register-sty nm flds parent-name parent-flds tys #:mutable #t)) + (if kernel-maker + (let* ([result-type (lookup-type-name nm)] + [ty (->* (append parent-tys tys) result-type)]) + (register-type kernel-maker ty) + (cons (make-def-binding kernel-maker ty) defs)) + defs)) ;; syntax for tc/builtin-struct From a6e596ba71ce4c95b08fb965651f19fe7d6eabf0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 20 Jul 2011 13:25:52 -0600 Subject: [PATCH 304/746] another try at Mac OS X 10.4 x86 libraries Merge to 5.1.2 (cherry picked from commit 30174b3c81371d36ef8ad065d9399b68942e40e3) --- src/get-libs.rkt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/get-libs.rkt b/src/get-libs.rkt index aaf4993596..3d772166d8 100644 --- a/src/get-libs.rkt +++ b/src/get-libs.rkt @@ -28,19 +28,19 @@ ;; GUI Libraries [gui [i386-macosx - ["libcairo.2.dylib" 805952] + ["libcairo.2.dylib" 803196] ["libintl.8.dylib" 57604] - ["libgio-2.0.0.dylib" 747088] + ["libgio-2.0.0.dylib" 736720] ["libjpeg.62.dylib" 412024] - ["libglib-2.0.0.dylib" 1014032] - ["libpango-1.0.0.dylib" 347300] - ["libgmodule-2.0.0.dylib" 18996] - ["libpangocairo-1.0.0.dylib" 84364] - ["libgobject-2.0.0.dylib" 288244] - ["libpixman-1.0.dylib" 527016] - ["libgthread-2.0.0.dylib" 24556] - ["libpng14.14.dylib" 183016] - ["PSMTabBarControl.tgz" 91302 "PSMTabBarControl.framework" 247768]] + ["libglib-2.0.0.dylib" 1009572] + ["libpango-1.0.0.dylib" 345476] + ["libgmodule-2.0.0.dylib" 18836] + ["libpangocairo-1.0.0.dylib" 83612] + ["libgobject-2.0.0.dylib" 284384] + ["libpixman-1.0.dylib" 526564] + ["libgthread-2.0.0.dylib" 24368] + ["libpng14.14.dylib" 182732] + ["PSMTabBarControl.tgz" 94103 "PSMTabBarControl.framework" 251764]] [x86_64-macosx ["libcairo.2.dylib" 919840] ["libintl.8.dylib" 61016] From 196ac13bdd3e20d2a82e9175c6982c56b58ac35f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 20 Jul 2011 13:57:52 -0600 Subject: [PATCH 305/746] fix bug in .zo writing The bug showed up in the "racket/embed.rktl" test. Merge to 5.1.2 (cherry picked from commit 5b8a892fbba0afc56deeda1d4e3a24a3ddb048b5) --- src/racket/src/marshal.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/racket/src/marshal.c b/src/racket/src/marshal.c index c8a0a20343..725ab5dfd8 100644 --- a/src/racket/src/marshal.c +++ b/src/racket/src/marshal.c @@ -923,7 +923,10 @@ static Scheme_Object *write_variable(Scheme_Object *obj) sym = (Scheme_Object *)(SCHEME_VAR_BUCKET(obj))->key; home = scheme_get_bucket_home((Scheme_Bucket *)obj); - m = home->module; + if (home) + m = home->module; + else + m = NULL; /* If we get a writeable variable (instead of a module variable), it must be a reference to a module referenced directly by its From eddf893dc675e3b173a425c2ffc1c603d72ec216 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 20 Jul 2011 14:08:30 -0600 Subject: [PATCH 306/746] fix validation of top-level define-{syntaxes,values-for-syntax} (Only appears in bytecode for non-module code.) Merge to 5.1.2 (cherry picked from commit 0d2b08f0534efa3151a9c9d5430b410f77589a9a) --- src/racket/src/validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racket/src/validate.c b/src/racket/src/validate.c index c1fbbd6374..94595ebde1 100644 --- a/src/racket/src/validate.c +++ b/src/racket/src/validate.c @@ -429,7 +429,7 @@ static void do_define_syntaxes_validate(Scheme_Object *data, Mz_CPort *port, Scheme_Object *name, *val, *base_stack_depth, *dummy; int sdepth; - if (!SCHEME_VECTORP(data) + if (!SAME_TYPE(SCHEME_TYPE(data), (for_stx ? scheme_define_for_syntax_type : scheme_define_syntaxes_type)) || (SCHEME_VEC_SIZE(data) < 4)) scheme_ill_formed_code(port); From f87c5acdf93078de947385bf23de34c59952d4ad Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 20 Jul 2011 14:09:27 -0600 Subject: [PATCH 307/746] fix `raco ctool -e' for syntax taints Merge to 5.1.2 (cherry picked from commit 85049968624b0f0f67ab46416281b0ac3d19d0a0) --- collects/compiler/src2src.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/compiler/src2src.rkt b/collects/compiler/src2src.rkt index 175ad03a68..f6d635f772 100644 --- a/collects/compiler/src2src.rkt +++ b/collects/compiler/src2src.rkt @@ -1576,7 +1576,7 @@ norm?)))) (define (parse-let % rec? stx env loop) - (syntax-case stx () + (syntax-case (syntax-disarm stx code-insp) () [(_ ([vars rhs] ...) . body) (let* ([varses (syntax->list (syntax (vars ...)))] [rhses (syntax->list (syntax (rhs ...)))] From 4389a4671d02ffe5521baeb8ba4a29862bbbfdcf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 20 Jul 2011 14:24:43 -0600 Subject: [PATCH 308/746] code-inspector fix for top-level code from bytecode Merge to 5.1.2 (cherry picked from commit 530bb1b9ba9db8b3e1bbb604f9f285f6febf3d8b) --- src/racket/src/eval.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/racket/src/eval.c b/src/racket/src/eval.c index 8bb4e7738b..a421bd8ef0 100644 --- a/src/racket/src/eval.c +++ b/src/racket/src/eval.c @@ -815,7 +815,10 @@ static Scheme_Object *link_toplevel(Scheme_Object **exprs, int which, Scheme_Env exprs, which); } else { Module_Variable *mv = (Module_Variable *)expr; - + + if ((!insp || SCHEME_FALSEP(insp)) && !mv->insp) + insp = scheme_get_param(scheme_current_config(), MZCONFIG_CODE_INSPECTOR); + return link_module_variable(scheme_modidx_shift(mv->modidx, src_modidx, dest_modidx), From 4db334ee2a649bb565f3dcf3fe60ca866bc93d28 Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Wed, 13 Jul 2011 18:54:27 -0400 Subject: [PATCH 309/746] add make-lazy-proc to lazy stepper skipped fns list (Edited version of 3f79c37) --- collects/stepper/private/macro-unwind.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/stepper/private/macro-unwind.rkt b/collects/stepper/private/macro-unwind.rkt index 6c798491ba..ad7f4bac7a 100644 --- a/collects/stepper/private/macro-unwind.rkt +++ b/collects/stepper/private/macro-unwind.rkt @@ -70,6 +70,7 @@ [(#%plain-app f arg) (let ([fn (syntax->datum #'f)]) (or (eq? fn 'lazy-proc) + (eq? fn 'make-lazy-proc) (eq? fn 'force) (eq? fn '!) (eq? fn '!!) (eq? fn '!list) (eq? fn '!!list) (equal? fn '(#%plain-app parameter-procedure)))) From 631fed5386243ea4da045653ae1e593b946f6546 Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Mon, 18 Jul 2011 12:34:14 -0400 Subject: [PATCH 310/746] fix lazy stepper test - lazy-cond1 (cherry picked from commit 7eedae8f697f24dfa93799723952bd83aa1454ec) --- collects/tests/stepper/test-cases.rkt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/collects/tests/stepper/test-cases.rkt b/collects/tests/stepper/test-cases.rkt index 99706ae16e..93f8846b1e 100644 --- a/collects/tests/stepper/test-cases.rkt +++ b/collects/tests/stepper/test-cases.rkt @@ -1948,6 +1948,25 @@ (else ,clause2))} -> ,def {(cond (else ,clause2))} -> ,def {,clause2} -> ,def {10}) + ) + (let* ([make-test1 (λ (x) `(> 0 ,x))] + [make-test2 (λ (x) `(< 0 ,x))] + [test1 (make-test1 0)] + [test2 (make-test2 0)] + [test12 (make-test1 2)] + [test22 (make-test2 2)] + [make-clause1 (λ (x) `(* ,x 10))] + [make-clause2 (λ (x) `(+ ,x 10))] + [clause1 (make-clause1 0)] + [clause2 (make-clause2 0)] + [clause12 (make-clause1 2)] + [clause22 (make-clause2 2)] + [cnd (λ (x) `(cond (,(make-test1 x) ,err) + (,(make-test2 x) ,(make-clause1 x)) + (else ,(make-clause2 x))))] + [make-def (λ (x) `(define (f x) ,(cnd x)))] + [def (make-def 'x)] + [lam (λ (x) `(lambda (x) ,(cnd x)))]) (t 'lazy-cond2 m:lazy ,def (f 2) :: ,def ({f} 2) -> ,def ({,(lam 'x)} 2) From 8ccff338fd8bc60d60a5a6ba9fad3add6629f9e6 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 21 Jul 2011 21:46:36 -0500 Subject: [PATCH 311/746] add version number to release notes please merge to release branch (cherry picked from commit f7f3971d1561487a9c247e5ed6aded332936bf2a) --- doc/release-notes/drracket/HISTORY.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/release-notes/drracket/HISTORY.txt b/doc/release-notes/drracket/HISTORY.txt index 0b5454df53..365603d657 100644 --- a/doc/release-notes/drracket/HISTORY.txt +++ b/doc/release-notes/drracket/HISTORY.txt @@ -1,3 +1,7 @@ +------------------------------ + Version 5.1.2 +------------------------------ + . The EoPL language is no longer available via the Language dialog in DrRacket; use @@ -5,6 +9,8 @@ and the 'language declared in the source' language in DrRacket. + . Minor bug fixes + ------------------------------ Version 5.1.1 ------------------------------ From ad4377d44bdedb8aba5e96bac8cd85137cd32cf0 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 21 Jul 2011 17:26:38 -0600 Subject: [PATCH 312/746] work around win64 drawing problem Merge to 5.1.2 (cherry picked from commit 8711aa6c5d819899fce1ff06f5bf60fe01cc10cb) --- collects/mred/private/wx/win32/dc.rkt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/collects/mred/private/wx/win32/dc.rkt b/collects/mred/private/wx/win32/dc.rkt index 649e673d5d..85caeb7fac 100644 --- a/collects/mred/private/wx/win32/dc.rkt +++ b/collects/mred/private/wx/win32/dc.rkt @@ -1,5 +1,6 @@ #lang racket/base (require ffi/unsafe + ffi/winapi racket/class "utils.rkt" "types.rkt" @@ -20,6 +21,8 @@ request-flush-delay cancel-flush-delay)) +(define-gdi32 SelectClipRgn (_wfun _pointer _pointer -> _int)) + (define win32-bitmap% (class bitmap% (init w h hwnd [gl-config #f]) @@ -70,6 +73,21 @@ (super-new [transparent? transparent?]) + (inherit internal-get-bitmap) + (define/override (reset-clip cr) + (super reset-clip cr) + ;; Work around a Cairo(?) bug. When a clipping + ;; region is set, we draw text, and then the clipping + ;; region is changed, the change doesn't take + ;; until we draw more text --- but only under Win64, + ;; and only with DDB surfaces. + (when win64? + (let ([bm (internal-get-bitmap)]) + (when (bm . is-a? . win32-bitmap%) + (SelectClipRgn (cairo_win32_surface_get_dc + (send bm get-cairo-surface)) + #f))))) + (define gl #f) (define/override (get-gl-context) (or gl From cbd7e37cfce789cadcf5fefd29752cab80ab9194 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 22 Jul 2011 08:09:17 -0500 Subject: [PATCH 313/746] fix the png conversion code for 2htdp/image images closes PR 12061 please merge to the release branch (cherry picked from commit 56b82ba83c5d29afaafbed602c8e14873a14f953) --- collects/2htdp/tests/test-image.rkt | 14 ++++++++++++-- collects/mrlib/image-core.rkt | 4 ++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/collects/2htdp/tests/test-image.rkt b/collects/2htdp/tests/test-image.rkt index 083dd16fe2..4a20cd227b 100644 --- a/collects/2htdp/tests/test-image.rkt +++ b/collects/2htdp/tests/test-image.rkt @@ -2194,8 +2194,18 @@ (test (convertible? (circle 20 "solid" "red")) => #t) (test (bytes? (convert (circle 20 "solid" "red") 'png-bytes)) => #t) - - +(let () + (define tmpfile (make-temporary-file "2htdpimage-test-~a")) + (define i (circle 15 "solid" "red")) + (call-with-output-file tmpfile + (lambda (p) + (display (convert i 'png-bytes) p)) + #:exists 'truncate) + (define i2 (rotate 0 (read-bitmap tmpfile))) ;; add rotate to be sure we get an image so that equal? works properly + (delete-file tmpfile) + (test (image-width i2) => 30) + (test (image-height i2) => 30) + (test i2 => i)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; diff --git a/collects/mrlib/image-core.rkt b/collects/mrlib/image-core.rkt index c90e337685..a22a338805 100644 --- a/collects/mrlib/image-core.rkt +++ b/collects/mrlib/image-core.rkt @@ -231,8 +231,8 @@ has been moved out). (define (to-bitmap img) (let* ([bb (send img get-bb)] [bm (make-bitmap - (add1 (inexact->exact (ceiling (bb-right bb)))) - (add1 (inexact->exact (ceiling (bb-bottom bb)))))] + (inexact->exact (ceiling (bb-right bb))) + (inexact->exact (ceiling (bb-bottom bb))))] [bdc (new bitmap-dc% [bitmap bm])]) (send bdc erase) (render-image img bdc 0 0) From 40637616ad28a55c218f01c6261c875420793329 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Fri, 22 Jul 2011 10:34:00 -0400 Subject: [PATCH 314/746] fixed a totally misleading error message in big-bang; MUST GO INTO RELEASE (cherry picked from commit ed7f16c872987a6aead663452abc4a7ebbbc059b) --- collects/2htdp/tests/on-tick-defined.rkt | 13 +++++++++++-- collects/2htdp/universe.rkt | 8 ++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/collects/2htdp/tests/on-tick-defined.rkt b/collects/2htdp/tests/on-tick-defined.rkt index bec034fb80..f210c16be7 100644 --- a/collects/2htdp/tests/on-tick-defined.rkt +++ b/collects/2htdp/tests/on-tick-defined.rkt @@ -7,8 +7,17 @@ (error-print-source-location #f) (define legal "big-bang: ~a clauses are not allowed when using big-bang") -(define double - "big-bang: the on-tick clause appears twice") +(define double "big-bang: the on-tick clause appears twice") +(define atleast "big-bang: expects a [to-draw handler] clause, missing") + +;; is the mandatort to-draw clause specified +(with-handlers ((exn:fail:syntax? + (lambda (x) + (unless (string=? (exn-message x) atleast) (raise x))))) + (eval '(module a scheme + (require 2htdp/universe) + (local ((define (run) (big-bang 0 (on-tick add1)))) + 10)))) (with-handlers ((exn:fail:syntax? (lambda (x) diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index 7d382c7049..bffdf4e22e 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -218,7 +218,7 @@ "wheel-down")) (define-syntax (big-bang stx) - (define world0 "expects an expression for the initial world and at least one clause, but nothing's there") + (define world0 "expects an expression for the initial world and at least one clause") (syntax-case stx () [(big-bang) (raise-syntax-error #f world0 stx)] [(big-bang w clause ...) @@ -234,7 +234,7 @@ [dom (syntax->list #'(clause ...))]) (cond [(and (not (contains-clause? #'to-draw dom)) (not (contains-clause? #'on-draw dom))) - (raise-syntax-error #f "expects at least one clause after the initial world, but nothing's there" stx)] + (raise-syntax-error #f "expects a [to-draw handler] clause, missing" stx)] [else (stepper-syntax-property #`(run-it ((new-world (if #,rec? aworld% world%)) w #,@args)) @@ -314,8 +314,8 @@ (define-syntax (universe stx) (syntax-case stx () - [(universe) (raise-syntax-error #f "expects an expression for the initial world and at least one clause, but nothing's there" stx)] - [(universe u) (raise-syntax-error #f "expects at least one clause after the initial world, but nothing's there" stx)] + [(universe) (raise-syntax-error #f "expects an expression for the initial world" stx)] + [(universe u) (raise-syntax-error #f "expects at least an on-new and an on-msg clause after the initial world" stx)] [(universe u bind ...) (let* ([args (->args 'universe stx #'u #'(bind ...) UniSpec void)] [dom (syntax->list #'(bind ...))]) From 7ee468a85733e9719781a98acbb323a51c83b56b Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Fri, 22 Jul 2011 15:29:59 -0400 Subject: [PATCH 315/746] revised history, push to release branch (cherry picked from commit b4d091438de4218d087f4906cec5f2f51f9858d4) --- doc/release-notes/teachpack/HISTORY.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/release-notes/teachpack/HISTORY.txt b/doc/release-notes/teachpack/HISTORY.txt index fd9bd64f91..4954df644d 100644 --- a/doc/release-notes/teachpack/HISTORY.txt +++ b/doc/release-notes/teachpack/HISTORY.txt @@ -1,3 +1,11 @@ +------------------------------------------------------------------------ +Version 5.1.2 [Fri Jul 22 15:27:37 EDT 2011] + +* The error messages of the image and universe teachpacks have been + revised substantially. They will be improved again next release. + +* 5.1.3: the on-tick clause now takes a max number of ticks + ------------------------------------------------------------------------ Version 5.1.1 [Tue Apr 26 22:38:44 EDT 2011] From fd6e9c28d3a4cc4d696a4b6d35ca4d12b2c3bd80 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 22 Jul 2011 22:19:19 -0400 Subject: [PATCH 316/746] fix compiler/zo-parse for sequence splice Merge to 5.1.2 (cherry picked from commit 42f41d868a133751722a426467168005d8cfb0ef) --- collects/compiler/zo-parse.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/compiler/zo-parse.rkt b/collects/compiler/zo-parse.rkt index 287498ba73..12ccf16a82 100644 --- a/collects/compiler/zo-parse.rkt +++ b/collects/compiler/zo-parse.rkt @@ -353,7 +353,7 @@ (cons 'require-form-type read-require) (cons 'varref-form-type read-#%variable-ref) (cons 'apply-values-type read-apply-values) - (cons 'sequence-splice-type read-splice)))) + (cons 'splice-sequence-type read-splice)))) (define (get-reader type) (hash-ref type-readers type From 7895045a1c17e09bc51d2cd91598dc3c89c452f4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 23 Jul 2011 19:52:42 -0600 Subject: [PATCH 317/746] win32: fix `copy-file' handling of file-exists error The specific error reported by CopyFileW doesn't seem to be documented. It's unclear whether Racket's old test for ERROR_EXISTS_ALREADY was the wrong choice (as opposed to ERROR_FILE_EXISTS) or whether some Windows versions use it; we test for both for now. Also, improve error reporting when an errno or GetLastError() value is available. Closes PR 12074 Merge to 5.1.2 (cherry picked from commit c9d4e0fb8cb775288fbcdd0378d7306a38488c06) --- src/racket/src/error.c | 27 ++++++++++++++++++++------- src/racket/src/file.c | 22 ++++++++++++++++++---- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/racket/src/error.c b/src/racket/src/error.c index dcae959205..4d2937ee08 100644 --- a/src/racket/src/error.c +++ b/src/racket/src/error.c @@ -202,12 +202,14 @@ Scheme_Config *scheme_init_error_escape_proc(Scheme_Config *config) %- = skip int %L = line number as intptr_t, -1 means no line - %e = error number for strerror() + %e = error number for strerror()/FormatMessage() %E = error number for platform-specific error string %Z = potential platform-specific error number; additional char* is either NULL or a specific error message %N = boolean then error number like %E (if boolean is 0) or error number for scheme_hostname_error() + %m = boolean then error number like %e, which + is used only if the boolean is 1 */ static intptr_t sch_vsprintf(char *s, intptr_t maxlen, const char *msg, va_list args, char **_s) @@ -259,6 +261,7 @@ static intptr_t sch_vsprintf(char *s, intptr_t maxlen, const char *msg, va_list ints[ip++] = mzVA_ARG(args, int); break; case 'N': + case 'm': ints[ip++] = mzVA_ARG(args, int); ints[ip++] = mzVA_ARG(args, int); break; @@ -389,14 +392,19 @@ static intptr_t sch_vsprintf(char *s, intptr_t maxlen, const char *msg, va_list } break; case 'e': + case 'm': case 'E': case 'Z': case 'N': { - int en, he; + int en, he, none = 0; char *es; - - if (type == 'N') { + + if (type == 'm') { + none = !ints[ip++]; + type = 'e'; + he = 0; + } else if (type == 'N') { he = ints[ip++]; type = 'E'; } else @@ -412,7 +420,7 @@ static intptr_t sch_vsprintf(char *s, intptr_t maxlen, const char *msg, va_list if (he) es = (char *)scheme_hostname_error(en); - if (en || es) { + if ((en || es) && !none) { #ifdef NO_STRERROR_AVAILABLE if (!es) es = "Unknown error"; @@ -443,8 +451,13 @@ static intptr_t sch_vsprintf(char *s, intptr_t maxlen, const char *msg, va_list sprintf((char *)t, "%s; errno=%d", es, en); tlen = strlen(t); } else { - t = "errno=?"; - tlen = 7; + if (none) { + t = ""; + tlen = 0; + } else { + t = "errno=?"; + tlen = 7; + } } } diff --git a/src/racket/src/file.c b/src/racket/src/file.c index d62f2d827d..1924b7b47d 100644 --- a/src/racket/src/file.c +++ b/src/racket/src/file.c @@ -3834,7 +3834,7 @@ failed: static Scheme_Object *copy_file(int argc, Scheme_Object **argv) { char *src, *dest, *reason = NULL; - int pre_exists = 0; + int pre_exists = 0, has_err_val = 0, err_val = 0; Scheme_Object *bss, *bsd; if (!SCHEME_PATH_STRINGP(argv[0])) @@ -3885,12 +3885,16 @@ static Scheme_Object *copy_file(int argc, Scheme_Object **argv) s = fopen(src, "rb"); if (!s) { + err_val = errno; + has_err_val = 1; reason = "cannot open source file"; goto failed; } d = fopen(dest, "wb"); if (!d) { + err_val = errno; + has_err_val = 1; fclose(s); reason = "cannot open destination file"; goto failed; @@ -3916,6 +3920,8 @@ static Scheme_Object *copy_file(int argc, Scheme_Object **argv) else if (errno != EINTR) break; } + err_val = errno; + has_err_val = 0; reason = "cannot set destination's mode"; } else reason = "read or write failed"; @@ -3927,15 +3933,23 @@ static Scheme_Object *copy_file(int argc, Scheme_Object **argv) return scheme_void; reason = "copy failed"; - if (GetLastError() == ERROR_ALREADY_EXISTS) + err_val = GetLastError(); + if ((err_val == ERROR_FILE_EXISTS) + || (err_val == ERROR_ALREADY_EXISTS)) pre_exists = 1; + has_err_val = 1; #endif scheme_raise_exn(pre_exists ? MZEXN_FAIL_FILESYSTEM_EXISTS : MZEXN_FAIL_FILESYSTEM, - "copy-file: %s; cannot copy: %q to: %q", + "copy-file: %s; cannot copy: %q to: %q%s%m%s", reason, filename_for_error(argv[0]), - filename_for_error(argv[1])); + filename_for_error(argv[1]), + has_err_val ? " (" : "", + has_err_val, + err_val, + has_err_val ? ")" : ""); + return NULL; } From 602ddbf48aa559727339ee29ee072c79e0b5ce97 Mon Sep 17 00:00:00 2001 From: Stephen Bloch Date: Sun, 24 Jul 2011 07:20:56 -0400 Subject: [PATCH 318/746] Changed error messages in test case to match corrected error messages in 2htdp. (cherry picked from commit ab01d563ca6a0313e1cb5c07372a2bd2929ae4bc) --- collects/picturing-programs/tests/map-image-bsl-tests.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/picturing-programs/tests/map-image-bsl-tests.rkt b/collects/picturing-programs/tests/map-image-bsl-tests.rkt index 673a3615fb..ccbe94dc2d 100644 --- a/collects/picturing-programs/tests/map-image-bsl-tests.rkt +++ b/collects/picturing-programs/tests/map-image-bsl-tests.rkt @@ -208,7 +208,7 @@ (define (return-minus-5 x y) -5) (check-error (build3-image 17 24 x-gradient-2 y-gradient-2 return-minus-5) - "make-color: Expected an integer between 0 and 255 as third argument, given: -5") + "make-color: expects an integer between 0 and 255 as third argument, given -5") "Test cases for build4-image:" "(build4-image 50 50 x-gradient-2 x-gradient-2 zero-2-args y-gradient-2) should be a square, increasingly yellow from left to right and increasingly alpha from top to bottom. On a blue background." From 861301537cbe935a5268805600d790ed50bd3939 Mon Sep 17 00:00:00 2001 From: Stephen Bloch Date: Sun, 24 Jul 2011 18:39:40 -0400 Subject: [PATCH 319/746] Fixed an off-by-one bug in "myflip", an example for build-image. Now it passes its tests :-) (cherry picked from commit 9a24e66df0e2f7c3a516ce3d3542aab099afaaa3) --- collects/picturing-programs/tests/map-image-isl-tests.rkt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/collects/picturing-programs/tests/map-image-isl-tests.rkt b/collects/picturing-programs/tests/map-image-isl-tests.rkt index 2f35d137e2..62b62166c6 100644 --- a/collects/picturing-programs/tests/map-image-isl-tests.rkt +++ b/collects/picturing-programs/tests/map-image-isl-tests.rkt @@ -15,10 +15,13 @@ ; myflip : image -> image ; vertical reflection defined by bitmap operations (define (myflip pic) - (local [(define (other-pixel x y) (get-pixel-color x (- (image-height pic) y) pic))] + (local [(define (other-pixel x y) (get-pixel-color x (- (image-height pic) y 1) pic))] (build-image (image-width pic) (image-height pic) other-pixel))) + +(check-expect (myflip pic:bloch) (flip-vertical pic:bloch)) + (define RADIUS 1) (define (clip-to n low high) From 37eca3412ffa3246bc98ec05ce5e21cd264d08fa Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Sun, 24 Jul 2011 12:18:09 -0400 Subject: [PATCH 320/746] change recon-val in stepper to use render-to-sexpr for non-lazy lists Picked from 8956364 and edited for conflicts due to indentation changes. --- collects/stepper/private/reconstruct.rkt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/collects/stepper/private/reconstruct.rkt b/collects/stepper/private/reconstruct.rkt index b562a13028..c51b592a17 100644 --- a/collects/stepper/private/reconstruct.rkt +++ b/collects/stepper/private/reconstruct.rkt @@ -173,8 +173,10 @@ (add1 next-unknown-promise)))])] ; STC: handle lists here, instead of deferring to render-to-sexp fn ; because there may be nested promises - [(null? val) #'empty] - [(list? val) + #;[(null? val) #'empty] + [(and (not (null? val)) + (list? val) + (ormap promise? val)) (with-syntax ([(reconed-vals ...) (map @@ -183,7 +185,9 @@ (if (render-settings-constructor-style-printing? render-settings) #'(#%plain-app list reconed-vals ...) #'`(reconed-vals ...)))] - [(pair? val) + [(and (pair? val) + (or (promise? (car val)) + (promise? (cdr val)))) (with-syntax ([reconed-car (recon-value (car val) render-settings From 2c5e9b9e42613ea070dbc5d1375aeebd945977f9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 27 Jul 2011 15:25:30 +0100 Subject: [PATCH 321/746] fix problem with initialization of tag name array The bug to lead to a crash from `(dump-memory-stats)' Mrege to 5.1.2 (cherry picked from commit e6b4d547c9c53a682b411f48af3c4393a1a6406f) --- src/racket/src/type.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/racket/src/type.c b/src/racket/src/type.c index e11c8893d5..98f1bbb915 100644 --- a/src/racket/src/type.c +++ b/src/racket/src/type.c @@ -66,9 +66,10 @@ static void init_type_arrays() allocmax = maxtype + 100; type_names = RAW_MALLOC_N(char *, allocmax); + memset(type_names, 0, allocmax * sizeof(char *)); scheme_type_readers = RAW_MALLOC_N(Scheme_Type_Reader, allocmax); n = allocmax * sizeof(Scheme_Type_Reader); - memset((char *)scheme_type_readers, 0, n); + memset(scheme_type_readers, 0, n); #ifdef MEMORY_COUNTING_ON scheme_type_table_count += n; @@ -77,7 +78,7 @@ static void init_type_arrays() scheme_type_writers = RAW_MALLOC_N(Scheme_Type_Writer, allocmax); n = allocmax * sizeof(Scheme_Type_Writer); - memset((char *)scheme_type_writers, 0, n); + memset(scheme_type_writers, 0, n); #ifdef MEMORY_COUNTING_ON scheme_type_table_count += n; @@ -85,15 +86,15 @@ static void init_type_arrays() scheme_type_equals = RAW_MALLOC_N(Scheme_Equal_Proc, allocmax); n = allocmax * sizeof(Scheme_Equal_Proc); - memset((char *)scheme_type_equals, 0, n); + memset(scheme_type_equals, 0, n); scheme_type_hash1s = RAW_MALLOC_N(Scheme_Primary_Hash_Proc, allocmax); n = allocmax * sizeof(Scheme_Primary_Hash_Proc); - memset((char *)scheme_type_hash1s, 0, n); + memset(scheme_type_hash1s, 0, n); scheme_type_hash2s = RAW_MALLOC_N(Scheme_Secondary_Hash_Proc, allocmax); n = allocmax * sizeof(Scheme_Secondary_Hash_Proc); - memset((char *)scheme_type_hash2s, 0, n); + memset(scheme_type_hash2s, 0, n); } void @@ -213,6 +214,7 @@ scheme_init_type () set_name(scheme_regexp_type, ""); set_name(scheme_rename_table_type, ""); set_name(scheme_bucket_type, ""); + set_name(scheme_prefix_type, ""); set_name(scheme_resolve_prefix_type, ""); set_name(scheme_readtable_type, ""); @@ -323,35 +325,36 @@ Scheme_Type scheme_make_type(const char *name) naya = malloc(allocmax * sizeof(char *)); memcpy(naya, type_names, maxtype * sizeof(char *)); + memset(naya, 0, maxtype * sizeof(char *)); free(type_names); type_names = (char **)naya; naya = malloc(n = allocmax * sizeof(Scheme_Type_Reader)); - memset((char *)naya, 0, n); + memset(naya, 0, n); memcpy(naya, scheme_type_readers, maxtype * sizeof(Scheme_Type_Reader)); free(scheme_type_readers); scheme_type_readers = (Scheme_Type_Reader *)naya; naya = malloc(n = allocmax * sizeof(Scheme_Type_Writer)); - memset((char *)naya, 0, n); + memset(naya, 0, n); memcpy(naya, scheme_type_writers, maxtype * sizeof(Scheme_Type_Writer)); free(scheme_type_writers); scheme_type_writers = (Scheme_Type_Writer *)naya; naya = malloc(n = allocmax * sizeof(Scheme_Equal_Proc)); - memset((char *)naya, 0, n); + memset(naya, 0, n); memcpy(naya, scheme_type_equals, maxtype * sizeof(Scheme_Equal_Proc)); free(scheme_type_equals); scheme_type_equals = (Scheme_Equal_Proc *)naya; naya = malloc(n = allocmax * sizeof(Scheme_Primary_Hash_Proc)); - memset((char *)naya, 0, n); + memset(naya, 0, n); memcpy(naya, scheme_type_hash1s, maxtype * sizeof(Scheme_Primary_Hash_Proc)); free(scheme_type_hash1s); scheme_type_hash1s = (Scheme_Primary_Hash_Proc *)naya; naya = malloc(n = allocmax * sizeof(Scheme_Secondary_Hash_Proc)); - memset((char *)naya, 0, n); + memset(naya, 0, n); memcpy(naya, scheme_type_hash2s, maxtype * sizeof(Scheme_Secondary_Hash_Proc)); free(scheme_type_hash2s); scheme_type_hash2s = (Scheme_Secondary_Hash_Proc *)naya; From f4cab3e47bb1dfda878234bd9f1c335782e37d51 Mon Sep 17 00:00:00 2001 From: John Clements Date: Thu, 28 Jul 2011 22:50:11 -0400 Subject: [PATCH 322/746] updated history. Merge to 5.1.2 (cherry picked from commit b346665c5c759b33baf711df35d4b42bcccd3b45) --- doc/release-notes/stepper/HISTORY.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/release-notes/stepper/HISTORY.txt b/doc/release-notes/stepper/HISTORY.txt index 640c6e0320..381b630f9f 100644 --- a/doc/release-notes/stepper/HISTORY.txt +++ b/doc/release-notes/stepper/HISTORY.txt @@ -1,6 +1,12 @@ Stepper ------- +Changes for v5.1.2: + +Support for 'require' in stepped programs, fixed a number of +bugs, lots of cleanup & refactoring, some documentation +changes. + Changes for v5.1.1: None. From de605d4fe15e865931e64f8a04ef19d7baf31bca Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 2 Aug 2011 12:43:12 -0400 Subject: [PATCH 323/746] Updated DrRacket images (cherry picked from commit a748b35f35b46a4760f01044d399fa98ae02bbff) --- collects/scribblings/drracket/debugger1.png | Bin 45690 -> 85380 bytes collects/scribblings/drracket/example.png | Bin 42557 -> 74298 bytes collects/scribblings/drracket/io.png | Bin 33097 -> 59919 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/collects/scribblings/drracket/debugger1.png b/collects/scribblings/drracket/debugger1.png index f5e75ba542502606185a46a1d4c5e4a627ae431b..2fdfce6ddcb0cddbe8ec51daef0e1b7a630a46f0 100644 GIT binary patch literal 85380 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°5%=izT7ug#Mop!#SIP*9i9>&AnZ19bG|oMV}X*% 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

u9`13aS5-;AvJ_4NR} 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 L6vQh;jROAH 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 QKvCWyJra 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 OpVx|N3gs_M!~P$nZGhGQ diff --git a/collects/scribblings/drracket/example.png b/collects/scribblings/drracket/example.png index 4ffe4d2c233c44e461c7ae57eab02b29e212165a..1c43cd504b8e4c2d9fae6a8ab6b8f137643b5e20 100644 GIT binary patch literal 74298 zcma&NWl&sQ&^3w#5;O#N3GVI?2=4Cg?(PH#?(XjH?(Xg$+}-`2JbAzGt-5u8T&kvK zn6u|>Ila4AuU1O!f0L_iJ%1k4l!1hno8B=C(XdsPSU25K)S%m-32 zfqex01F0u2EC9R%e^30a-oP7_jfko}2*_6s;Drb}V&G^3eEHcyR8sKs>K8Bscut(> zoHgJp3-XdjV zP(%>W=#qs*Kp=-EBVz!QYXE~VBd_ysFip){_VTWSG96k;keqzE8=+)<*s!;oct~?U zKk%BgGo(oz?Vk+FRCW3U=EIAR@Y_d%8o^GW}; z`0^=HJyApQibQif4917_ZzG>ScC+Z&d(!qAyu0lj?r#P>_H_!0BDQ!;r&D6~$*FOcKIESTl*2)=yk)QCnqZWHNOmJh0j z46Q3bG?pY-!6aPzy@d2%XU{0gaB!ebJQYdwKOXm4+^A@Glrv&8;-T*kMfK4S~l}tamlZOfuzf?{2WPr}sA&kzVjm z=4FXg8U(1pI;|Rd<)VpyOv2b;?l{vtJN(_4xh%fF)^jsHnB_~ym42Z;E;or3cu&!i zXUaR7X4TsCJZD>fY5VBi?9h3^qIT-N%443BM=3^tA*t#K-n2Xvp%9{rCe6U^k4?W6 z3A*fwB{{vfH;b$&d}ZGEc=!n1fxCIfIaOin?3HwHdNN0pR+A5|77>Lel}|H6zr}h%x$OSo-E9fsQKxi4-trD_f`U5 zYTzzeD8Kt-b6skXaG}0w{YG;_%BV9Z^@h8W7~Z?iTF>!mGd@3)8RYNBu+U~3>_Ie* z{!%v(R10)mL~p$1vgV61cH|HuB+7)jZA97w6HRhTBCvuoky!}>jq)Rj?0Rt>W7tVP zq<-K_J*1;Ei$E5{>VZ2IqAXejDfL52W5lg}z?d8iwvuApXwX2Fj@m8v#|aXw+im z@l25$77MnLHu`w2-<>U6mGig3b|_nw^_M+Xoon|+^jnqwxBe&oFpIIMhpW`reCcQ= z+C;eZSx+GXd4enX7-B{Kgfo~NTH~23sI2nSWYEzhJ)xI;c~H^!H-G0&;;ly$ClacV z#k|+VOpZvaMwHQD)A1He`jAv*)3>&VVA`QSBalmkDM&CQ;6gC-d;PaaE5nsGeDwaA z;teb3Y~~_$nrKkR6=aGdW=SdI61#4sC`=(9yPWQR>)EO%hD4Dd#Y~STvNV%ejx6$b z$=_(-C6^?F>Pjy}VMs#0qnLJV&|A|ccU~F#IQa4Cq8@U}{X|U=37rc?E#`$GnepIx zZ!_NtV$$B)vmP*N61NHZ`)v5~g8xpU6)M{4Zsvefe>O7+##yPLQUw zBAmxF$$)O#Ca>;F{7=e41gapA{Jy!*V18ft{>`Mj&3NO58Wjcw1tm#>q)f@YtEt`F z-F>`AGl6g^ZbO8!{EN3^ueSIR(%$zTZQ8~Dy_R5@*3egG#b@7g&wbCeO&xFTpZh}P zO1XfkL>RtSE zKEaDyFM|XI7EEvbbKhFq)s-E%VYyOh@7AB!r<-s$q+kDeAu!N6x3xJlX3TKN+GPo# z6-E3=<>0t;JCk<~h03HxQShhisGe{79jouZQ#z}nz1FtYAQ@A~fpN&@{&S{GP{5d5 z*CU8T$>POEMn^?OL@rBh)1-_=d{8XbRP|eV@_BQpu($RphuQ|c{a>!`3!35d>eZr& zf>Tm3WmEs>F6_+A%tL#2WlE*OVNWL&u!%ag(pVh5j5*8cTQuI&2tNDg6Al;lSkwwF z7A#l?p&^eK-V3r0e?S&Oph4#7>Cs!A@)xbo2{udwiWLG3Z7$fpz8b?Fz@HAPX`vZg zP>r`b<(^mvu#!#G_6wGM9P?mv*!~JBvD2VIo0g@|Yd9I0>h3j-M)yklx7L_}^JaG@ z2p3l-R+ihisr!^YzEI5C(@Y+V9+5adJeo3e!JzO;=SSXY z8!pdg3=ikc5K~EGrb(y}P=+4=`9(Z(j$6sX0 zmzr$M1Z68?MGcd^95EeCq-C$@<&P5TAH}_wR_%-}Hz%Wk zaPpgOxmwJ_d$~{Q=WW^v53xb`7W8?-Q6Psv`Zungks*g)2h-aFj+cy5?* zs;#r#KlQ=@Z1ct=lDXf&H!7n}#K`^G$@w{?ffsDtIkR``i>X5D_&}t(-O^iSV-o>I zNF7W05xoN$jyETC;%s;H9_3P_F8GU7rqM&^1|Lc6^qVpUS^P+rE$;d=#Gq1}=-|HF z^R3uc!0JVx%Yh%hvW?S?@UHdpPzJXvw)z!`9fpHMC!s-_y0d3Dr}+j^g(UL&Oa0D7 z>V>Yzg+xgi$@|TjyTyktWnc%b&QS_$^sqtRCL)(q_hf9jdgDxsqxnjs^~JLD`5HSs zHXE;-o15QuS#h!M&HgwnE*E;c*2O~_v-v`m(Ku#JZ7tR2eKmxmtY)S(#K}uJL3BI&6SYVR7~Sw=bWfx3mJxFE-k-+3h}+ z&ST#5XN~Uhl`G9w>kGTx9&RPqW55RX%37Z$KQLfh>F!%wq*NMH$J9^v+!Zh%*2_e< zvExs9S^Mm_|0;iRCKC${S!(rwz;RTwiU`T6?-ljXC72)-wqeKV%OuZhofS=^39;6s zxu?;)p^p-2xqh>M zT6%+^T3k7W7^1@mIi0ijm?iYCPBh}tv*-Ct63qWM@}VNqdwPBGd+pXvCK$gUCf z>is$2!E`a6NT1R+|Gh`0#sG>x5T2NrxWAT`hbOaf(<`;x?{grEFyM%!3S&{J)j)Ju zQe8jZ9*#EJIn~Nh6GsKTynaxt)$tb2f@UdDL=%yh1?KVsCMV?YeDn6OS?lp+H#0k1 zTvC$L)RaUh95L1D?Oh;|j3{H`7TErFzdAfRy0e$4O~S|+JBaIECTnUI=2=o&N=`wM zquJ_|;|udiSFc)Ssm+z~U^3JAa4I`5KmQvF%HGw|i@M7~IZjDQ$x@>=-pNAw&gpXP zn(ZJ?hU1j4>r9#yDc}%es!h+|veT5hf2TACmQ7dsL*EW=xy|=r`0Yz)xkifKpj!H{ z)m_4((2Gtio=4Z8CF*c+i-(U09x}>q2%Z`6twxB}=CD zkn~d-6@oI`+)bC%ptG`r^Q)Y0QnUvQRI%VCUP z-5F+NgDaDnAF5#;rsxT;6({_VjKFGi9vM+OShHG=@}kSN_*aPV8-?X>E9(HN*<~Y& z2NNX_E~t{R;0YN$;+x@^Dy?I~Hml=+vwR`3D>)2OK|4naan|4Rq;7r~&*aI3$KjCC z)EplO#{xo^&gXZSbz8KrFIa=+>VUd+`<`eZXPH)I zVL`#bY`kv0n(NItE4$t97XXXg9?ypk$CBpC6@#z=--str5%BQf`SW#05%9a*P7Bix zZ`K%&lF`y043lOGkisk963Lgj_FV-)~y56_Z?tZjfYpils;rvkGtX#n3vtJtM z(VxVliEQQ?5hSQq6fmb81%YJZLjuzjenL6J_f1jDN0$6sp)69lOjZmLvKSOH;t)tZ z^stq%ZsSfJC*4R{T%z(PPs|8qrD-m9P)R+eV>X--GG@E*-x}Fn{xGK;M5WOFO8ye$ z(_8>VF%+F*qfAF}uv`Rd*9w%2Atc`wxnB9&RK^%f&2nzu-CkK%76t?W`&G-vtLKx-n*l8ADz`hcnwlDy-Du&V(NRKn_GHow7qHTK zF;!Ize}DgsfRp@0ExpIfEnxTfO{8^G|05Rrib@Lsv zYkxfT>9lq-iQAn8*c^Y_A2!V8q*GdPt|CS)SlkDWP>_+QY7E6kMn)bFb0b|Iw*r&d zZ1vh32K1_J9xrv3Dl~@Ioj1eP%J1_o3R11~R_aVeV)_6B8Up;W_{aMjIXSuRKp4iF z-6%C+G=WV`Y!hkhJKtQ+naVX=6Vf@IuYozaEZD#rRNkMh-t-|!R~ZZ=CQzyR_HJFa zZA;-Jd=e_0oo=>2a2vIOaK|&wLLudFJnoy$749`l^$<*YXkuz49d{luCi|>ZMa2Gy)vAVq>C*Lt%Hv0*bKUCJwDwA&Q{`r^_%2A)9}CNp&F`ULQ(N9T&=xigsa<%TUA*8`R<3Q9^s zB5*kEULS3(I-ZO=Ua!TeP(uefmDJQiluG-p8r@HC?iRIgt_Ja9)6>Jpje3t90_qZ5 zvnxtUu2%z~KY{T)Nan{B0i)5E>FqYE%~qhmBA#gja>#9}C=r;2b&O)2SU&D)$di#U zg)#`tSk$5uM)Z;d>S7A&pQd#9ks*AjSm2Q00>XFz}3cv?KoW2zFDKrVmStg zR<4++*188B3l=Qu+|xU#vgdCbs~bH-)I~~VDqEubjaKVq6cpb{NCJT8Wp|M7ET^gp z1#Ek?*AQ`5S6A0E&DQ&vH~oRIY{!!YAiV>DhJoSUp4hVaW7ixM9J~c&Gj~0h;X;46 zk1qtwQnNiNsdUC|n6N!ZdYMYKuXV@Mzz(^%sA%_=4KRJ7Ql;{!VFO(2#8vry2admS z^lG~w7K5R0_7R-mY;Pj)#lwde0n@LWS5;NDT~q>Lim`Fy@$Ow?#~jVEm=WI-S0}eAz1I-c;oTs%wg`BUR3ruWzegx! zN~4PvmWYUXP|}H8+#9nri$iwL(uh4P11_V+m}2&7@-5f(uD-$7CBkhW`dEjL!`K?*1FTLQp7WO6R#A*6cItSgkkGdV2UmLPLQBxSdFn zB0hxY?MPZ8l?BePyX&lR6CPnkYvV8K-kPpASBA&?Ap!V1thO*Iz!L|4#VashtRSf5 z@%}#Uegt<>A*CI@(<)NlXcF3Ijw(_n8t#gsfM30UV7qS}rbdSdxgqxS{^oJw5QB>r z`29zRQjwtGypuCUJU%$-<@ys$RFp{1FLiRpRPX_eP4_Q6mX8^D@F>&PGQu(xQIva4 z2K586qIPLC7;HM5+22dd@QW7_M#g-!wdX5mEwS0^{Rmqpr#|lCi+080>`Sy}2+j9rZ>lVruF$MCs%Q zYwJmQIXSs@di0Hh=61XBRMrCkvf)Z6IHz4*T>$|(F<(6KyC@g zrc$IV!q`DtJ=fpGa8eSh}NKBK#F_xY?Tnr!EaoXkQdlWNziOQD@kQWHJ=!GPt) z%USt3#dfAd`f!WYy8uo(#E3jyZj5zmM+%*Yghqoch2~TmoBP4dzZDGgTJXVks#JJ* z{tCfhFoY0+$1_o;S}P(Ukylq2m%;6Rox1s2u<^^@+IE{W;6%Ce8HLmN++ZY*oa_B@ z=kK)b*E}bzy))+I+4t?wP!Wt*|@%W4tf8l+m9gpSPN;` z_88fa=aiUy4^oZUTu36Fv^=LJrDsNNB8^K>;=zh+rS7l)|GDEhsH%BMi1K7EdW0<8 z3O`QYH!meb)+rQGl6cj-rAvrZQi2i&(9UYk! z6%`L1IDp9jdGw$T9gxSfyWgJ@-vgdF-}Po6aP}@1h(lT+z$ALi>gD9+`32Wo{UN}9 z+7O9;|M4ROfVBW|$z7=peHV2AM9i|XUBDcG&A!3dz!aBpIFlc0ydAGWBOF6yz@XZ0 z$g}p+rj4`rcIBlQ_rh$~Q5g(<5HGv&@Tv1VHFoy?3*W5`2{=H@o;ta!d>^-5G8#{r zrV^VhK3mPMK`fUF1W;Z}3uf|%4*LLNZE*!E6&I{K(n|UQ(utxOVvv8Z_7})KIc#&GjdmNh2ja5%QNeg4r_oqA|uK z`utc;I^ptcp}UZrg~c0mHua|`QmvgHziTx4&rl{*)O~nuWJ8-4g+d*kpc{J!xskXu zqW7tLFezp{yj$CCw!YK}g)(XD?oY< z?u9Y}T7}5nw{$qSZa1=T3sI4s!JncrpX`v=?hp$9V|sl9HWNMlRq-W}Bo16)SgqHQ zCtf%SQBAuCq<*`Bx)b?QPhpzkd0hGwvHv4LX()4r!drIzk2}Qee!Jlq(Sf3x4TlGz z)`lZ{2U`T`+$h#ubbfUFZ}Uu#>tJo^l+H+=vmNW7t0LS+K2d>$U2Wc<)%&Pt5-UC< zng6@T?#sj6q6X^+_co(HydxW)Xo*5d2^m)z;}~PL`_{?f zGPrd%BnY2UOc16|rM$O`=|fioR)7FnK@GSJmo0xZm3FuKgZv8sE=3axGng+>!9w=Z zj^Ot9_X93Qzgh(_HHWj6c>Tc$+ub2iE2(9n?xR>X4KY1+IJEc!4r1fp1CPgZp2MYL zcIl5NxCopTX}!`<9UHgwegW&Fqte_x;L>kjaatdmX&}^W1?l0H&-9MtYs3)s5i4D@ zNorN-!f?ZnSFLpiU@tvIn3842Qv-ExO-2%Ezmm`O%oBCD(ECwqVTlDn5N;E*^`Mw# z8@W9*`XZS6jz*@xdTz>pn@z5ZTROqtFc;5ScfV-I=5YAZtReMqz7EP}^9SUj{Q(zn zMq9DcKbn2{&W@Mcii(10J6~h|q8zPuH(7v}0Z5Lg&5t*2z#|4lM(Q7qN>`t^S|`!z zwjH3*`K4Z9zTEorf+;HMn`*^(*9DFaWF!{LHCcSrGq%QX$@R-q#O#r&DAN0u9LuMeFcdsEr`5*b{{SXNCw0PK#yi?=&n_ojq#oHVOr%dV4d1Z4p->LqsVVbU6VnFLjC1D7A3bJYes&PUfs%#F z*nuzfgBFJXS$AI>i@M#+R&v@K_a58I{BTP^!RzQtY<=&IeDUszT1t^#q-mzP*3_@e zo{?KF8g^B#m2&yCGLa6fA_JWA|Iq>jUZ!q#F;4!HQ~kIZW2_(i@%&|eA{|)UpGMUJ zL^Hmo2{z2qbmMbm(rRqqAjKv4`%*eV-IV7y0?+Fl%}U ziyzN^;W08E%wqT8(Z7uW^LPp5}5U$bO5>ff8U)eccbLvD6tN znwdVp5iXSAlkSJ5Y&%64_3}c@>bfC8f&}E3d^CwbPA>^OMy^2)hr=!)FX{&%jcUCa z%3n0rgPH5(G-#(3E4uLOUS(vW%C(yd6o&L(1i(cby-t3>DS{itS81*5LaDAev z_xX8pyjO0W=qGPjxU6}}%@P=1KG;D-UCe0?{~GA{c`;Yf?CHBTjGH3zg9Cm-{J3j1Z8>Hl;?%WeDa5jFg0 zUU{qct1R~;K5+S=)u%O^pW$!0 zLt4F~5rm9vxs&iMHcQ%jMvZK_osKXIhX(K9F|$K|S$-q0QD(!lK`G17T7B}d^(A`2 z9sg^jcLp`YlZ06760uYFy2i@cQe_?sw=?Fi_)00lc5R+>ybox>(!uG+2@cN9@brauvJ?K-GXoXQ$=|*<=ycnn0O}sNp>69)$l+2lf&)!p zbiJzhB3D>OIWnr9fW=~w1tf+ZZ+DA8z3F#b8`t&qHJj5Z`d}p9-%T4A9}jA?KZdaZ z-1pD-TB*_Vq&J8st>DS^ni4BY=-^WR%N94+lhwUHywjiy`xW~A84ql(TSNz?G?&vG ziXQ17%s|c%9>`kV`o|qakGUH5i~+e>B0?>fphb}CU?Q_$uUb~WQMaO6R<~Y8OMh>! z*<%|?4dMYSb7im_1_7shucyP)qh6Oew1aCPUc=&;Zyw@QiW4#&v|KE7*{EPd&0kFp zsWg;W2@T7RYh}IyX{JK+ayPaf%<|d6<*dGowDVr=jGa)ZD^_|T08W1Jcd6v}X&yL1 z+~P-QC$FZfPmH{NjEU+VYmOJNph|Iv=7#=TL$^Er&6WC205m?()+-8dhT^Q?lG$$ zNEtv9zE~3u`?mgqYl|}?wc20_lTn$go}3QDzyF%9+tCosWYTtuXv{4*Q8SDl8!O6U z6xH6|HHzaL^|V9d6i>6NxI4dsYq(rytEE{y%YHZ+s^tn?Vi-z0Sw)dim$rX6cwwsx zRbgTGvxRANhl1l=MT;P`Ul5{FsBv;5somI=lDapLURgW(@%S!L17ajW+-qX6FenVl z*_tqZEoM%#yn1s|b48y#0J~qoef-oIqq%H=PFmZ(3q7)cnY#Fu`)F3{J0*(U0d=d% zqRt+u4)?&IJ)>v^<)}Zq)#}3X=}xHYm^No<*b$!laay}Urt;d3N)mVC*jTeyD|#tV zU8AJj>GA=`=60*g;N=9&3n17|*IO5F)G&SlC=)q#95sLdwTgZ5txv9Nr3}t-RWYLl zp@_2@ftbL}@04$#hHuUofL$fvIj$iTph7nOVFH+c^orjTE~YRSZwCB$Y3n);dI_N799?djVO0Cc=v=^k^AN zm9w*=8?!MgH$JM1EXhH9Y}sghM}RMKaH^;f!^NkG(~S<1B+ke0wj%ZBZ@6b zup*I0Q2ij`plP(v>fuBNemN1eqj4HV?nO(hSKGZ&7{L!44h(%IFKPWbaTYhxR^)2& za`jnh{DglYNY;Y3c>H4x>vMGdBeK1cmEOa-WtkegFPpV&nH-ql7+%Ii8=UjyOkL}V zqy91H#=s|?d&0&jc5{r++~8GV4ksvs0n6Sy?hoxP2Bft{)>+bSUzvCfui#OoafS&q zHB-(Pz=atwMbhbflou-xqSe*GP)8&nYZk3{0`VH?t#9Ft!Zd`TvM%V-3TwAj=)4d{ z;nlM2(2#`3vc}VbVI`Ur_MA_bz5xX&fEfYGG_AWXT3WcD;jwx1<)(p>me3qDVJ9x@ zr=lKNwF?b+i;62ZgU(fNul=bJPp_bMoje!c_-|U)``h4h zRhunYITs^$TQOjks&~GS@F>3Q4##41xm0D)*@xBwUf9mwo}8Mxe9_YO`PNh_ode}D z!Ppm6-Y5oYOr^C@YSUU56kO$Y0=sM1bqH1=A^X^HuNa4F5_44HhD^!x*?GkTI>~zn z--yb3a3pR0bfY2W$L6HYRQL^fRiL~w_Blul*I}-4tjI-2Xmje z+|4Vy-p%KqvMYYOSIm!5=o9SERv;sVJ1~HLVdl}QmZ(hPFyo*NyIe5k zNcraLW$w1c5F+5A@}*P6D4CmDYYC3&u)7!Lb|z2b3srvTQ)Tvt9Sq{xCspaPe6Y(& zjYRRp#6uU$D_!evWFBStgyfugXq)lJGQ=sW7W1O6dcCqfI9+1E%GX6_5Z1U@IsXuJ zO)bjchsQckl|C@IBCcjEbiu`z_v*8o=NLy1cxEQ)*u06JA?C+u^aCA&Tzw@oMcpvI)3)VX+IFHfRVGV3sE$m zaw|$1o(HVxQ*P>exM2QP@dy4^LYw0%C>TKPDe)lV* zl~h_^<)Q%{cHA@@;xR%#zFxW$ys&+^jUX!iN8H#J;S#+L?gx72{-P1UHicocBNomM z??m!wNf+(y?Oi?YMD93n43CXj+@_cs&5}>vxK>@;gkl$zv6+?h<0tn@t zjnD)Dlgd!UD=0yBE(4v~z6z9ywTIf`CH#XmoaiA3l2&9ySj zSf`VTsaZYgV8S`kAcixK(S3_c2N%n3w6~=6{a9Uplw#?sYWsd9_rhN2d|5+l`5BYe z<42%op_6SLTV$fW)|NJBEvO6o0m{bny(LB2yMLqx&B6VxE}6oy+BX_-(fpqkaY4*| zF;ipcEm}LD(iGCTd%VAbnTj5soOkWR6tbIk9NN|=Ps+-kqx2 z`N4Kn|E9*n{o)=JnHN>HY#Em%X49;}6lx_DMgv(dCmF^P&{V`021yt|1|IWWL|G!w zQBV7@1$BbigZYbaA(Ox$lN*+qt7pYEctFC&={XQwjlG3 zuutt9g-;7pRM~KOBvT9o4GZR5D2DInI3N~UESVS0U1nKtu9SkLcE6IjR%kJxn$B1W zb+jaTqqo-Uml1rNs<9S!2K8sblA7N^W0(;gn!>*oJ5FxggV~{igR?MNpFgNXSp0%x z)rCL|qpwFKXF=tjq9TExP)WbFR+jdd$y z)UdJ`EGHU7w4~jK7Tp^Sh6_|KIZF|w{*HuY;iF3}zIvgw7JNwKmU9LS&Lc5wjmMIJ zUzmI1b(mk3jy!#r#x?9{CQ~pOkd2VMGbjvSV_>1v86)B3O&vkHugf<&FRBr*CXVYH zEa>6K&nax45c|-7JUG{|NEiy!P_1y294nsVqze2c|nTF^Tv&O5_hm8R$y!=NX^36uCBqY_|n^K8{N_|8)Cq|4lvrc3u*XM!SD;`)nz~DYvJyau85** ziLhCyQAVse&5`8SnG1wnj4uorZkwL4SS%@$sdnh|^w6XJaw6?)kkoP8j-la@Fiaq+ zD01t|jQWssYW~{&dXNFHZe(BASi_=cS)yyHW62t!Xy;i7PSMypgls`)T8Np0%bCX2 zqoBvUPHLy5lbGKJp_a$%2@Whqa)CtVN&`tn*yJ1dWqCPO?juxG zD_ZCbEq&_@Z+l{pm&kY!Os~5~Y#o-#_jinh*pb+W0{?icNcQ&qu(%8N%xKlnC-({6 zkdTJU``;3owc5L)^upDd&O!$E`V1T7w6v@cP8l#@h~*=;Ye@rTR)DD|qM?aMpjHQD ziYGG8GEC%t!(#r+`hzuTP-~m&+SW&fS%w%nTF(oqYN`8n&%TR?!Z*ubPLA{M%1uX0 z-T~W!x3y%`q-n@p`dPS-LobB2tXYNSH_#Oh#Tu~KQRGm^?3Ay_M~bK)6C`IIHHr+2 ziS4FQ-3tu`&hYg1D4_;U%px3=TG{e0O<8A^`rF+gzE>A~PIt45k~)6K&`vtBa9D3! zqo19E8ty_4wo~f2>>}Shj5Wn^Tlypq9!K=KJp~13++YEMVYHJqi&`GUbqO;Q=(kAG z*}++qrR(vHmWl>DuSYxf;#{|!uUpoktUVFXAAaBK2b`kJTU=tVTQ=mMH$cnwRRpmC z>OL>OL5S9;TAXJny}Q7Vc!}~x^?6ZzFppUf&A9z^a|+y!XUByYzdmmgBu{$}NI|DAH;_7zu5B=T%96C45H>4g9tDk(9QP9YSH~V{vOF@xP;+?uC?w`Ig=no>W>{)MJ7BcES5oKtgdL&eK>*&0{K4G)j z`~t)d)quDN5V&>$6|N^hF!UYO3~d5u$HeQ$)06OWy)8y^dO%GIXjvL#$P&UHsH6T& zjh4|_1{hTWA`4AQH>4bfyE4U}tbMT4r8^v9m}^ze2O3;e8(F_2`Ol1?N%Rg>Fq__) z%{yVR<7zl`qvZ7!UTQo$q@1J%qG*-Q&-6rzFnV&iiTd@N6VZ_P zG@P~kM$;BB&P6pT6I`=RgGx+XWXG~@cygTf&MUC?GHK&RF9n>FlkF4FP$s)8}46GY0BVM6*zXG zO>%*=9Rb&6%!)a_v15$vp^uu+U*u}mv@XakUhK;Ue-?vXFw@bz&rLlT|n-M1Lg_gMK-Q|K}BcxxpA z#vuF^&}}`~eOpaD9m5&Zc8|;d>ilQXzUGO{lWRRe+7~ogOMixFCUbMV&G>nSv3WuU zd_TI;Ev&V$tCE(m>J4mAS-J$E>KM!+3)op1sm4XFzEUPfL$GdovkDczSLdV&Qi-JZ zZox}7im7)F<5d;!ffY!lbZeFxyWn8-jC`K=dJV!a&N*&T03lC4_pnlke>9FjAP~47tBDl2AY9-~+Js_DJ5_ z{|=~h{&+ql#C7=t`WG1tMH2#)s$y4#v?9|k4f~= z;wl3Z?Sa~*eZjz84f(DjX2 zN&`Gbhl)Rg(d^ONZVN0_Xo>?`=fCQv`eL9EnhA(#0iG8SXuNKH_5Px2yn1L}*+uiv z*;imCA9RuAB>GTBFQR%*Tb_*MIyov>?!O(HL zVAp=p9iK^DbbWjDV({g$+K`*9@N$kII*9}?cft9O`vaau#ow-X(qkhf-1i&qbVjfX zoELc((>bFnn#a;;%)4;l9Ya99o-!`w*7K=(_NdKZ^*;%g4I4I~W|;i((CEGjh}yhX z&zt}SHcM*x#?{)I#y|uP*7qY+F|iR4>VV%%m-7Yvz7SC1Lf2Tv`4G20T6nsRGN#pp zrnh$q_EicA`iVJH<`q*RLJ6K>;?1GLPG~mHHJ_Yd_7t6R^zOXQbc)ORB7SRaGU*kG zZr5THF&Z*Re>C~~KqYny-2?Sj3iCl`Q#hhNGt8(-yE1rx?N+6P#2uNU;2HDp-ZRw- za&oG{>+sK?2;GW1w5g1h7$T`AwgYoa(XkMmn^7v6R*R`B`9eYj34PjY(kSNoj%hcq z0ie*2o4rshUzo*LUcIN=sKT53vxm>M8AVW`ERwt1syJ^1y1LrUJCP}7Kj(~fLd@v& zKKZrDkin;950DNgu~=e4KtKR$0X;f&puR6uxkxCAXgrbDedO?0uQ}D>DNkdG)IvpA znpl6uF7sF~dDwDX*#SXODwbflF;qxsr@~zTzPG3N!w}`z#bt4CFYi(TH1yyj{x$Y< zQA2{PAvtM2zw`U^wH$1KPPhu3JC90NHhivYk@LC>)r+g$hG*)9_{`(_Tx(S3Yrv`Z zA~&}K##s6l>Eo+{aRJvHczovNfw#usDwfXeoVy7D1gf!JGIqO=bR0)Xh7MT;*}#!q zj{M0KMSV9Z43lX37lp+h+J{h#vhK@1q#{=9fW6VJXyMn)Mmu7lT6h=1N%peX$&1pI zcmjyb37DBtL}Q{x_W%WSoEWiPGqz|9AT7@DWJref=i6eRbXTWITwJ}lZ)$yLZCrl= z_v8YTBx$YrK2ALb)WmlN!ub()ImlNAzqt#~#4s4*@DYN=Dua`4G2!onC9VC?7ysxd~X;?(G>O#n9R8eSR zcL9mr`5c#!roVAo{Q9`Vs*qf+Vku?yGGCd@eB$WPGSGQ4V_KO#0FN17Vw=#QAg5cw zn>&YqhH|i&YQNuup)t4dypyv%RZ_QT(*A{DuHzAmMDqH@*AbPv=ebndAKAnzdI3;< zRSBdt;GE;DP?gUfa+5tR-Q7u_VKtbUY3F@xFhw8>bch&5 zavCFd@vwSMrHb7Gv~^W&puSD&SP)RcjJ)5`!XlC8c)VD47A~E)#n!NH!jex_IQ}O6 zuV(L?Ioq4j8!@ii8iHGM0<$Ih-&t2)8^I`KIfI?CPm5GNX#Z2Y|68K}SLWvpV)}Pv z7K~u#-(j&YpCtR4Icug&nEr~9LJ6d*bU6nNLQW2uMd|5O_Iz!Aa!>G*%gfMEJR(uMyW z18^u3vO1Mcwabb@7j2L1zjMI6L3QSSFq>`NG41{y%;t#NnoUieHmj);X>8Gj2bNve z_LS7_1mc;v<891?n26}H!{5!?{+lLWo~DsPby4vj1xNFk9NKfK7E`Lqj%TK;mq?xG z=J5_j zxKxA4dGU&io1*l*KU4RoQBhebESB`^MdDLCg}_K_#h^;wpfbsSenM&;_D)knSy72E zy81WIXs70?TJQ1H*DLAHgKF2x8`BBWwx&PaQUTMk&UT|<3=9DbN0E_;xowGXjy_bR ztaMi!(_9~~0zzw7WX^rJTjQGj88(3nV?qV(empGC^X$8!X@2zib|-lqf`)l`Vfc1kbe)* z{rUCTf&S*L`6Br#IDK1BeX6cYG^2Az5O>`|Uq;XJ$|Bj5wpDy=N((#&noMVPX3xWW z68eX`F0v@1Oq-8zCe;CBYUw>|Kh;o^-$TNw-W;4?QtPXu3xEGwnODvN%zwr&uwvNd z6~k)$mVUe=B5Y6S{Xz;O$BR*_{RfqivgJdU@OV~2y z2bYKQL5ud4gB2FcuOo*ajj!+D)_ON`S~n+0k(Bg6b9zN8!rdQB^k~|1&BxP|il8!3 z<-hGm%X5Lj;p^{{8Z>#6#qa)L^+ofEytZ)kg_RH_9oFTs9(T*QF=EW}hi{BBXaG%7 zi!~AONBeKxgX%^Twy~1f9t3lQKcesLy@WGUb@q|9FQWEi##HZV4;qO(|L969{2wjA zV7-S(dC@ZXOCu%sU_5Vpq$&}9i$1NLb>`^1SLGBp{C#Cgw|(g9O(1Kpcm*Og^N$zb z0^*e*r+JNg>B%hj^dg4zHKB=O7Faw7a2>)syv>{8IHR$N!(LxB9(}P+qMTSxx}4;A z(gP`ii8tW_J?QBLLs7vapIP4Y@>5g^C%9?8Ca8altTwBgBe0md8jnUs7TMCY>J{c1 z$=$oCaCy|4@1azK<26ISx9)G?fYA-Z1800YtDVhR9h-|16C{xTD33e_3?nl&i)5}KLWe&I4Sfw1F357 z3w_ez&7t@h_A-WKRNWZ%M)Hxk6`}m9AG~+V=k=p>i>Knxm7Oo&m!xZS4yjMu9^C&x z;%2(Rlv|nhlOnwjx5AKKM|NWGIjMfNdXk6SJvY26EPvcCB(AU3&ULqmJeR&jZ})@M zgi=TS=o|Ap!B|!;`sZLP1P!DLXZPN>?3#VO0I+wk>iqu(c`y2nt0$J6=~5OfsRtUZ z>rz%$GzSyuJN1iNFk~|eRBsU-emb+m_hF+=1Y@Tw}@umi!&Uf-y>yYl%bq zgpz+Ks8J!KWqh{e3by^0H*b~mm`1L{CT~kXQpY46)~bcl@}En@oygz@bo)>MyOJ*# ztX3`*Lj-6oV~7Yu5uyEo>R^Nf33ySVq?Y%aV~fL)FOev4d>9!T0%+c>aSnCTK8cg) z-udw3;thZr$rAg^7aL9&UvICzFeRV5wMz>#dT5-HmD`>XLXk!%#m#|mJH|Yqdh$YD zuB%T@zga(pBb#jH3C>p4i2+hi2wZBk^d#g36^?(QNEvNQ0%}x@8r^2nW{icHP*|FP zT*~1aaBSo6_3vkxyuEN|oG^_4BW2SY^8aU82w#4S{0lumh>0fo7c~Ai%=~|aI^fLv z|3tn2+y4J|g!=#0mCyeTZvWdAX1If7;l%$#**iv8(zX4AvF(nNPRF*{9ox2T+fJur z+qOEkofF%(G3UOY_nH5Em|1Jywa$mEovJ#u_qlfM>)Jn*!rOr(DD!WsOn-DM6-3Jz zq)hz^hdkwR`xQZQ=)~>PGT}VMARVx8+m#z}2$moXlOdWv`k^RK6D?! zEAApr+LI2Oy5;_E`;CEiNR8fJN@>6NW9$GZWbK#?DH@98my}CtgNl(20qZdcwM75< zD?l0yL%q^<0T+=C$(}pQJkinEe?u{(FuBJBx&+;rSukQyIfQ)4ADv6~+j0PNLjq+L zeg^ykbM1;?2?VD9ctqPdn5GCVQd)2)``QCW8-m$J3pkLSt65gr(9r4HjbLdlTV75) zgc33jd)wZVq=IFb&)Rg<24aRdVxnL1COQPjsTw}D|HE(n^CAbZGHP0vyI@(TMJtYr z_(0mcCY0Bc08&y_y{+xiZNiD~Unp8Fzi^OCk4R79nAXtTw_MfaFse-~;o_PYw1U7* zFm-CVZ%IeFuMfT;X-{<;O*U-X0`%yRr_=@>2ik%DDd1&CNTH^3_|-kFV|iAsn{atf zV@yIqVhsz6;u=s34<;alYK%cZkmc~rrE8CI?>HJMwty3kI)6J5p@Nu)EL4Y>7)U-P zBk{VDx^PLkd)r$tufC-9A48Zu`tW?HD4*Jx;(Aiek`p-Mn%*OaiR4$MjW~iF*e$LO z3i806qmm~X4B$tLp`uKgXsS9sp@u{WJ;C5HNO<7%IGw zu(@AjA%rmSxl)3#%HNzLUYwAFbHj7+K&1A7rX#}Z?qD$X_<(zv((el8y-YDTx8DkQ z!36%``#1MA*BLRLi;pCA+CTTBg&rQRvJV(;x94K;EY%z><-8jo2gnso@Q;P2^4#nB zvjZIQhqXn-2o5kw?n&-z_vj@<1`Lal2CYY7So@B37YpvV?CG2`kw%`J{R?`VG`!~& z+3nmB@kgAm`e+VnZ|q^kSBv$=({z<5plZVB_>cYF*9V*F#$FH(6hViVj9I=}PZZ(P zSPGk$pKBKLKnkHipjupIlE{Rqu>7tEW98otz!X*w?qM1Gfe`V7wuge!vu> zWdhP2=(?e`t%-{#zJe9|Sf+%_Lz&md{G!8?r=2@fhc3x=4X=IxMmK5UYNIKaPcK`~ z59*659Cs_ofl=?C#vgbN@@z80A2VqYsly`#ZQN{EOqB(pL#}~ML3<$YJ}Y<`FUx7l z2q2_B*mZM5vnns~8yB4yB~ToDKyLv{|Kl(g!fcd&8odk`!`=jIVN=b4RjMt3lFLZy zyq{C9nai5CNhqk4BfDqDjNt5&hPp)~YymRHS2#~H8Vv1Al-M31bnO}O!{<%|*&iU~ z@uqp*QI;_ysD9j6=5(_8&Ru;=LaB7Rf~hgW`?t%M5&>7LfF2#;UYIH>BU*?Fyg5)2 zmLVfAb27J+cuonoisVppAKoMpY`k8ON|*tJ!Cx_rI3Y-o<+3LY-{*ezef#xH<7Gxf zp8DHEjf+a|2{AE(SS0_J`kXRMb)Ya*qgX1Qe=b51Z$v6s_s_f*^qTJR_3q%Htu;tp zQ0D;UIWPfeZsZVM^4RL2TESJ=a4O`YyHa8)uK9?mdo-yw1Z!R7X0uONn8@7mTs}jG z4E2e?8Hy}f`6;vVr)40En1#8(xE|}-3W-}3I)-$Tv(VO5Q0$7SQ!y+ z*fgQ8hZsMj+f=6W<@Tf??1`i0hG|HSp^9$5fH1;VB7h5!l%PbNWNu-xldI9-ap*Sf zFe)Yxi|6Kk{m65IhqK>@>;nUHeH*m?_K}lkjZKt+F2|L$RJT{RE0MhQWaVnTHd@aj zyH^)RsK1sxnb~yCN&x4_a}z`r3ZCMO_9l4#Q^1PEqscG<-2WUA+ugb zwa-kZgJ-hlY^^=r>9#TY$0*M1a7U`PiX=$6kUx495;54>W@}2M`;#p|%@jxqlg{Q0 z0Lmg9dNR|jwYp;u#)ivUj)bu_qRBU1U0W90T00heBg89KoeCn3Hmq2NdmJ z%S!ZroY{-Sh1tD)!`obr-Q%1{XNxM3BkLGXWlZ*HpdJCVcbYe78@cG3ijC$f4s^r(1*7F#9f37*)d1e47fHM_jiGAQ7)Jh+;g*&h+(IFiD7g(ZVYbjwo5Ajv&lI`^TqP$AW?hZ64PF8 zbu5qVCl@eTW0~d-%lSMvLojvpK8{45&llYxJFTsXWQ4CPu+YL6^WA|ELit(PDMHCI zsc{QOX2bI9Fy*eb4kEUK5|i0_voRJHefW>LBp4|7mK^)qbdNpB#6L zso)97fx5fTMk}HVujiFcrt1WnDWMm_Ge2IACm8;(GAjzarLMk`u6wQ#g0R|_+~i{+>}w?bpxl13=RwX5&qK-6!_zv zEt^wS0&lR`*?xp4%?;59#lKB1PE%gClTt(~2^)7g+%^YW9gJ|;OmN%x0}c#nLX6e~ z!_kvt{E`SLOf8h8Oj3MMX8yjfJK=i|F?%+< z)E*bUWIE4D%*^%KUHwg{1^}2mZ;dZI@BCU%S#qjh3qGbF08Z+|LYy`>`0d6d6418Y z4{F}`Mmfat?6G)aTu7QCZQ6Y?gR^k7VyF=5Q?Xfpn=e(`U2TWq`0%w*AwWxVe7RwZ zhzUzv-XS!_V)CkdXgN0Bzei!w8D9Ps>2WR3$`c_n(O7PdL3c{!H$kI&aFFfV_U_s7 z^S%B)#rwurc;5@Y;*^o*W-d%i~#4k+O~TS)LY4tV3b0KYnVy!xQP&Tfca z7mNky`9z$+hE?GK93M}{OEb8@tuvC`wgzcv2u&{I!<_c~{4(S|HnxPy30bwjuJn#- zx~_kWJUU&zG3-aYT^?a`Y>k8oI78aD$8S!_;+qs}%AhMRauPyihqL}?QLB|z8k06d z%?Br%rr8-n8?cV*e(T%9tMQOZJE>5_GNGEgD0rDm`HBy)7UU(QfbhQ9qsFFDq#mmy zMsUEJ+s5SD={&0U9duM(zgKdu8%a!q4tzX0xisEwt&<-SVn%80 zYK0(lu-gN9n+qNdVttgw#Jl=Yb~ zi(oD9!u|eLwpf}FdIe!`C^po=##qlcB)OP1F_M*S2`K0l+8z)J!}pq)rS-d4Fin!; zgv)L}0su)s@WT!>U1r`hubz2jur=!2--$jM3-RiNCn8abBdMa38CcT{_&wB)k$AUEhxmI^fp)*=X#~j>hoza|FX_qz$kIUF za@&LRZ#9ji%IrJ2xMp0aa@_8>GPbDKhc>xW`AC{5NkljJlHO^^~P2X0%v=>XlM?|yH;disQSD52q5p0Gm+lT}_L$dxbDd(9E(iEkB$mH;=gukrrkh=Ij9?!Y(&E9*3Pt zpsPg=lbyMR8C|@+R4guJ5!l1S!@!=y_Z=u`b37iX>z+q0`%8D`BAvnujC&WOK}r21 zstO^)2a;z#PAZ~4P)A<|@DQY-Gv7=M=fCagj~-!rZmzfMPSXy{@$eFI+0jkjkYWUW zV1@HTVzlk-gQS#Ez1sZsU}eXPr1#!qLTT!}5%sixm@L)Y zvpzAU1UaTzv%|v~MsWIkd<*|!j>kdR{zeI%da{br{sw*G^P-}8I0;?k{+{h6u?U#w z^nn`l4gO`8Y4vKvX!HpxQ8Gyitq)}2nnrTua4a=PN|n`5kS?2p2Gmn;eFHv9gnq8_ z1e>H``UTWXTJq8SG*Fs4(x`iPK+0x`0}?;4g^gsS7DNnwH(7DmU;l+P*UO_tFYi$m z`IPEXBgb+R3JHD@sx-;*B_5!}QD}77@+p~47%u${dYR;NyE*QBnqOIw2`_HwNOAW; zZ@?xPWbktY&&tYjetMi;+ZenVrZc%sl$ep925mUJ4zl{nm^C5~bo6*=a(Uk{K(q225$qarNHOhvM4kfi! zR==^61qRQ-&92uda*iJ8T4pym#Kk_j7Vau$H4|h@B;-;d0!(k}hHrw-{KU1i@PttQ zQM1#x?W3iaNbjTobi~};IC#9EM_#btW7P-#zJ%!y?vmw4o|Ts>n#KgFu^X_^Mi(u_ z82$RR%vx){8CtUOK4i)1l}N*EUA?Qd_ELvIDH-af%b1*7o9(6RZjV7vrZ^*fk`}VNVfZupcdC0&SP4vDk7EQ>P{`sj31@*T4_Xd&B_gUzBW)%NM(64Nd9TTK% zwiKeTV^P!Y`hXsZoBOB=2Y`*?T`a)_|1mKV-wkVD0H`eIgSGE-)fIEI3v2UPZBA-DO7(omMlW(UNuh8#68EyFHRlBhLG8`4IIwPJLDQFogv)jcqDm8SPil z$5<&Fo|fd~^#$Kw`^tUmg92e*1smv3tVyT#rulN`11P zKJ5VdJf`IGdug>w!Id5-PrM)d3EH1(M8neu_KFsi#w3TePIp$7>NhY~o!dUGGDcy} zrK=n17!bd#*ZKwkw=)M|+}E||BY{9=2Q9^_v>X@G%M=pO0jYln9$VC*HD6tw8qPT{ zKUIr6*b(VkChY)6DEHhPqDsAodV>h5)3Ts2(3;R>xXzHi^+sI#TXzA9lbp2);tN@b z;IYz_F%VYDzrX?Q-z%hgKUP9z`{d*Pu6Bp`P(7Mai&_al#fbU^@^glrLx*k()s8;Fw-W6 zCaBI#B8=1CeDfCR*&xq2Zk)vIz(`v`j+3PaO9q{15z}OIGJaNRAWLj zNZ;dJoB=|%DrPyBO{2gK(Q%+JnFBsF&8?KH4)%C``S4P*%9ILK4P6DDnxu+OGc}<4 z@8wwyH!Ib{|Tkeka!FvC=F8cThi=`xFpBt@wa#d z4BIbdtUx2-BwPio2$u292HhDpQW?CYi^i`!HI?3Ea`v) zWn(oJ4hRLUD#;9*fO*TOa(epO07{UINIV@Bw#o8Y*1Sj+x@=KD^Xq*7zqS+M3xWYv zlVA`u?a2iCA=L_KV{F4Asu;S1k*`LSBj;Lv=9T5hX)l%EyIFL;*KUGorg^Gd)(~2R zLKupuN>?5WHCb|(2NDnvajSsFLf#a6vXTh>64W9g(+M}aY`L9Ou23~y)uOuFtaC*- z`(D&V44f8Uchy)HdC02!Zv;`pu>F)({x-8S++)YNKS`NgxzuOPdl{?w^!BbLusdW?4%0paaXR_{UgP`t;LEoFA2x`#+B%k7tHr zxl|VOwAaG9hru{x+vJIpm-{g^Wu7A?_IN=rBNu53Xo%|Qhi&k#ZIz09d+>M>0idK_&Q2ruMS zUDN@~rIzj=JC5|rG7#$V>J6mh+Rnf5yb+t1)XPPmsm3P`msADCOqSz+P2r-c^y^-< zSwQX zmH2h-QNSXpW7AwNEuV2(pKu&b44ny-&NRmk;%ys#S^Iqk!tGDhxSgP;)sn@2TrBk@ zTmYLCVgjMLa365wn_uuRz_&$DCkffzwY=~b!m90%Ys4mLOI0GeRratCJ+|AE(@2-o3>1Q)Mf@~A z#PglvYvTjL9GZA*nUUVr3*x=PF%{}Rs{a5uFhsJ7#AX)7{-CX zY9C-kM5^3p4--fnF76d}Ev1q9llS(C3AQC^?%5!X@!Da7dyhfoJHGNn{x)_v7dyMq z;?o$u7VQ4%0zM<_?{dM6q(8}sSY$fTF~#cCXmMPWh(*HLKXtMkj+-k<&ZH(WipmvW zEs?)>lv9@Cj>oL-`EwWgE)Z4<;>!5>3Al`6)VbrEXqZoPSXvvq21pV-85S#gVPG39 z0wiNlAYEnhj*{dxGZ;~DVc3eaW8HPYsq2r+P~j|7>*OzNe^p>scSKe5Ma6SG_1AAE zn^X-Y*jzcvqi*DE47SEN3^v?fN-jew(nHJ+l$NKGh#))r19A$?e~7cOX2{btlOi-p z#G7h-mo0r-r^iguNW1`AZ8I0dll)7=%IGB$YDBn~BHKQk%7m1Z zaUY>+O|T+g9^F8`VU?Nn&W)RuoO+mD$W90Q0K3l6C07_N7L349V@ek@q%JVTv}uzO zQ~B(vD8@w|fK<73onF5BS2kY1;*#k47M=m&N$fCa@D8Zwn&WWg~JgTSE8qb+zg5>*`si>(Wc^-ZJJaPH3s**D305WAT@BqF_F0 z7o8==Q(x!MHsfkb^K{mZXN%+36V+5`l#N#^gC^&DlWRtOxy|g`Dd03+>kc`fO1KfJ zoaZGd$XfS{`;5azlma)E^Fy#$hR1CDmG?TH$bTt*MPbPqE|B=0>$W-@nTm?i zNa0?GH;b59R1hI1%8H^^UOga9vOJClq79+>(f$LCorIkp%fa~=1qy2$B^2vGkqVd6 z=Q=8vm(s-JnZr#Gp%!fB2W>Y<`%mGQT=;G5iEW%$Hp!vjPRh4*!@6ii5;&qFUdjVv zO58K?HgS^(VLLrJ=MUy*4`<(=0S|a^7~#JG-p0x|q_;@1sT_A8j(k~- z?1lO6y1p25!h1<@LtM0I?kktJPCnhi689%*P8LLwTz9}^F48}4i9}OHI7(e4ij1`P z7mDLoR*TZ*3A0cBI7)IFzZn*tivwI*uXye+Lx%evIN18mT&Y|>XMQEjZ@w@^D3Z9m zCYl5wMStq(cTy%R*p;>*O!^$DsPA%9N$}4@8R31ift!{zXCw|7p{Ct4EH<>plW#L| z%6Y%|)j()(SHR5U9E+hF!}KP8`e;MdfFu%+fc~OH6!o!Gg?u^?_Lh!5kna_27F@aO zg`>iR`tCqDs1NVcz$mD-4e9KPcs*v7q2W9cLCbk-KO~naUP}8ONv?#|W!KgI;!TgX zPjX;L-wwbs#|FER{?AH3_KZ&Nha!2>FXCa5CFTflJIgWbR%bPT<^>!tzjJ1=fg6 zPM_J1cv62 z(nFK(A#%Y~YZQf=oIEtwg{mp^O?y!P3F-Pam)9E5>w*csp)>0P8%<1u9m5%?ai{|A zY_}1ZGXA@qCE`TMMIu+4)-;GdL#0udtd#(Ah5s6U->nmr30`0xncLW&QLKHc4_?~6 zQJXzCk0j!372<&O<|o4Sa+66yS&3ToKmpWNNnTz6&^B>yeRJw~w!p$#JVA1Z5@QS_ z>Ttyce?~~WoIXU4IyZ>9uJ9)1{!YWWtTs-b;a}jP?;qg7BICCfy8(tj8*vU%PaUmf z2(!RvZwu#D=3OeI4fm&hoI{tbtkM+Hb-|Ty%2TEftkIAhNfIvHpn(RKE3IiIQZlM2 z!CLd}K;*&sYFp6fCck0zY@!3f0f#*b6Prlh!@;Hg8Cu zjZSF+dv-Afo-l7YUAxvsX5ZpdxNXG*rPmbz;D+l3?p!2O}ssK_u=b)U92&;{r1agoN`Dybs&B? zCs1tyU6a19HR?*lid*!kT6Uxl3(Z)T~Dfu1agtwmybJ! zdc#3Ua_RJmy|}OBS#%2fksUE+-}Rrkr-mX8oBnfz2NT3_aduyTrq<^EVg8SAx_%Fs zwjCF;^qu=b(wQuB|HUF$2G-5x;l?P%gyaXvi4TWz&lRQ+nU~iP6UcW9l?3q{<@j0r z=SXzR#8DvpqmC@B#eU7+T#WpISY`*_OWl5I(fRT%)ZO7!Z!>{-Ni;iEQrp>--d$Qn zP3*2u@cMfYk&~toP1PPnfylM+9^R3tQVd-|x&#ks+|!eN&s>4J{i#=vqq@TuIPcSh z629+*VJz3FIN`GlH1eh&G6fx9_R9#d(&jz=4e%kYSZyv|>I z+P*K)FnoJvPYZi-^BZ+p5f89SH9jG6-jDMtsIEsb9FEI>j8Zwxd}9P~;uF*x-xXIf z-FGFdGnqpmrLgc&v0upzxVPU-rug1y$)~eK@*0A~2z^o1e{wEQ_djh-mvmiw^z`B3 z@5gprngG3PSz~ex=YC*D4kW;i9WYlRN*IMS=wHxOwC>g;&v06RA((nRu51a(7q734 zM~V?07UVork{SLc+FteR2#tHc5ZG;Qp6|AzL3rF_UvioorMP`AKo(&NTbvt-4h>3k zc;5LvIt$1-IKa*^xsfRGf8^SUo^Sma=BT}`3*$PfWD#$U377yeDC?=}ZcU5xKL0*5 z1CmC|vE>b)P)r!E0}zyQ>VQ@F!!Wb76rF=NP}eKb?tLWinLtz18vR;#f#S~VeUzon zZF~>PlG+~8qKr)~WHLuGO|5hTzMc1>lQ+R(+}TKMx2-EVS|c*DgHH3l4PhM&w|s&9NL;BdHQlm#9Z|+s@KuvC znVyIBc_X))@m@yXjYOOL5nX-I#(pK!@&vKC1U z*t{ENyF0P$^nf%Y<>n#5Y2f0W5`XKrWPA~i_I`IHRI~7Gu`M*&#n^QSyUbd{VKa@656??W=i8lmsq}I| zdTh9~{$jn=6jhweUJyFwVUKAf)?&Xvb;VTH#vCNCCue&{e)`8D+xs5Xvx7%ssVHJi zo~Wf3o!&gBcheU)BZHXMU{8cr^yv_w@%P&PbZu>-vFwV;q|Y56Gu7;;hIJe&+x&hWJZ@)<2@qE|5QN3FdyPQ z%9+yzBMn`{S9+R*QPZ7$MOWPzEk%nkk&55`uureM5mo4|4IKD=44#$+5)V{IFcsB_ z7vX^b!J?g2tc^~e;51rQZW~(RW+3Y4aE^1MV6zBQ4TQXnUMo#&rR^2aYbJ!l_7YHI$*$L-pb&lP_cbBsc4tqv z#BAIY>eXx1q+y}xj5xtSUmwKZ(2PPyM@Rb};D=bm>~sg*0)A{0$DkfLGPjkUZ}MO% zFq;VUboz_VBH@ai;}mP5*98-S!AW&ZytO4_Bo*aBs1qVN1k3Ufoz55lebo^bGE8Ka zy{8@x^y6f**u~gOQKg^X+?)bB1*Nh$pbifHSIX`KG$7 zp+kaQNvhdJJAljm6U-SWpEa>_LjT5525tl7qUs~;Zhvh&LK)$8q;2!DGWp24`U z(E{Ilgv9$J=QB+MTG~uajpGiPE1HVMOmW1t&d^~!l?MZszdjrl3W%3PNt5^Q0d(Zd z^paVoy8R=ZkjVjygTU7e2Q3e1QB4X2~K&YE{Tpqw_pq9SV6h{FDg@2T#*^N7jh)VaF*GwdJtdZ79Go+f)2 z_BI)Y6LR+S3jjx z3xw!>4*QgX0nVRE)0fc)z#eAQ0${Pucvcw56lJK<75Ng3ou3v+p&;}N99FF+%a*J^ z=A&?0{bqLiQRA0op@gj8Uo6AQ-ekX;W;V<0P_OVeZ)n`i9A{CKYF_MbHPV;|kQFib zp!WquM@NTX>^PChmN8VUYHq$Ar1p*}$NLJBmaP+QS!r}wxdPGo(I}ffAS5*MJ&wMl zqasL|cS?|ax)@uP>A@d7yl9U1xnga3Wko{GjiErah2?Y*JB`Z<>S@y#dacFQV7;)+ z`STF;a4KUO_~tEf=8c{kikvZy&(Ej{0eAXlo4dX%wY$9TSDb?4Y0{+9eg-UuUD$VN z0a+a|nhls>e7AR4?Y9Rz`<}+Kzc)j8_+IyhhLd#iw;rAcd)DjsP(U(AiQYS(QHk`y z%=b9MiB<{DGEd-4{NW9)PnGSl&y?-q_#=TLcDTwex6A~i!taY3h`GtO-WS}$|3d&I z0wNa+B1ScvM|wD+i-7p6AYwr)859TzA$hurzp9_!TSSli2qL`G6_;mk{8meqc?}H- zR$VtSl!VF{n?i5foCwa&w*^EWsofv>9A-?8a~nf8R*wjqbW^4SKY4d-%e@H*;dGxZsf5o5@M1Jw$ZaRy{s)khbu zx3$`64a$NSXY>>EOhm}RPgn=LbiKDqx+cT9yWK!a+E(yWrqL6}O(k388EvA_7L+Lc z&(Mq;mLDF9vt3Ce*;F-HQB<)Jb4Bc<%|{*{6;mV`XV%2_mYIgAapKf&Mbn%p_J&B4 zrPE&z9g~ccepj-*4JE`Qt1esxpdMg26?fkT{g&?0UrMAnqc)YEKLXeJ&F<@im*X8e z3eC`GO91XGcolom7;OO!V4e?2YP&Lw&z0|srO2z!7M4RERVauKnIF$MBFzre20fh< zxtWqImThlYlSYlR<@h4wgmtQ663${|tq^hv&mkBns{kk1etOy+&=D^xzgS%1E$=d* z6ic>Aocx@&pCI-E+vC&!`b=D39 zl<|j2u%dQ2kz)7s*VutDi4zIHGQp~*GZ|<>yvG@

4j_TAjvJhOeci%B5EHx4E)e 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�xmcs_A2s43r3!>4N4XH= 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 V(pL&jQ!XR!J}DNm9ifYG``maBv*9n(8_ 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 I+&Ag}0HV1{^#A|> literal 42557 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�K+*#Rz(0`v8=-WF#_FehHJ7G<( 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 diff --git a/collects/scribblings/drracket/io.png b/collects/scribblings/drracket/io.png index 0efc145f13617bfa0114493a454fa97b9eb22baa..59eb2c8e90f23fe59ac34559744ac8e5136d1c99 100644 GIT binary patch literal 59919 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 literal 33097 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 F`afbAd_4dF From 4806c15bfee3d847a72444fecbf744a72333bcc4 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 1 Aug 2011 14:54:53 -0400 Subject: [PATCH 324/746] Fix `unstable/time' & xrepl use. (Just the relevant part of 1caa28d) --- collects/unstable/time.rkt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/collects/unstable/time.rkt b/collects/unstable/time.rkt index 5350346c6f..df54abe409 100644 --- a/collects/unstable/time.rkt +++ b/collects/unstable/time.rkt @@ -1,11 +1,11 @@ #lang racket/base ;; An improved `time' variant: better output, and repetitions with averages -(provide time) +(provide time*) (require racket/list) -(define (time* thunk times) +(define (time/proc thunk times) (define throw (if (<= times 0) (error 'time "bad count: ~e" times) @@ -43,7 +43,7 @@ cpu (- cpu gc) gc real)) (apply values results)) -(define-syntax time +(define-syntax time* (syntax-rules () - [(_ n expr0 expr ...) (time* (lambda () expr0 expr ...) n)] - [(_ expr0 expr ...) (time* (lambda () expr0 expr ...) 1)])) + [(_ n expr0 expr ...) (time/proc (lambda () expr0 expr ...) n)] + [(_ expr0 expr ...) (time/proc (lambda () expr0 expr ...) 1)])) From 7ddf119c4d163b7da9e177a6497a99a4ecce0051 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 2 Aug 2011 23:26:02 -0400 Subject: [PATCH 325/746] Update version number for the v5.1.2 release --- src/racket/src/schvers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 55caba2563..7dea218c99 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.1.1.900" +#define MZSCHEME_VERSION "5.1.2" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 1 -#define MZSCHEME_VERSION_Z 1 -#define MZSCHEME_VERSION_W 900 +#define MZSCHEME_VERSION_Z 2 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From e75fc54f64553506f4d5071e0fbc889c1415affb Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 2 Aug 2011 23:26:08 -0400 Subject: [PATCH 326/746] New Racket version 5.1.2. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index f385cd85e2..cfc0dcd9f6 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index fefc4dffc3..3f62ed67d6 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,900 - PRODUCTVERSION 5,1,1,900 + FILEVERSION 5,1,2,0 + PRODUCTVERSION 5,1,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 1, 1, 900\0" + VALUE "FileVersion", "5, 1, 2, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 1, 900\0" + VALUE "ProductVersion", "5, 1, 2, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index a4d5c58f1d..8810ba95cd 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,900 - PRODUCTVERSION 5,1,1,900 + FILEVERSION 5,1,2,0 + PRODUCTVERSION 5,1,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 1, 1, 900" + VALUE "FileVersion", "5, 1, 2, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 1, 1, 900" + VALUE "ProductVersion", "5, 1, 2, 0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index 57221f610c..b6f4396c6f 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.1.1.900 = s 'MzObj Class' + MzCOM.MzObj.5.1.2.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.1.1.900' + CurVer = s 'MzCOM.MzObj.5.1.2.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.1.1.900' + ProgID = s 'MzCOM.MzObj.5.1.2.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 38a36b1736..6ba8306cb7 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index d70780fd27..581a4c356c 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,900 - PRODUCTVERSION 5,1,1,900 + FILEVERSION 5,1,2,0 + PRODUCTVERSION 5,1,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 1, 1, 900\0" + VALUE "FileVersion", "5, 1, 2, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 1, 900\0" + VALUE "ProductVersion", "5, 1, 2, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 8fa54b7f8e..594f962327 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,900 - PRODUCTVERSION 5,1,1,900 + FILEVERSION 5,1,2,0 + PRODUCTVERSION 5,1,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 1, 1, 900\0" + VALUE "FileVersion", "5, 1, 2, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 1, 900\0" + VALUE "ProductVersion", "5, 1, 2, 0\0" END END BLOCK "VarFileInfo" From f49b095c07a296419730e9880d6b63165f4dde8f Mon Sep 17 00:00:00 2001 From: Eric Dobson Date: Wed, 6 Jul 2011 11:48:05 -0400 Subject: [PATCH 327/746] Fix kernel-struct tests in TR. (cherry picked from commit e6030295fff3c50dd66ddcd6d1d39a5b8ea18247) --- collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt | 2 -- collects/typed-scheme/base-env/base-structs.rkt | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt b/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt index e6a2167e50..f16ae1bad5 100644 --- a/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt +++ b/collects/tests/typed-scheme/unit-tests/typecheck-tests.rkt @@ -1356,8 +1356,6 @@ |# ;Kernel Structs, check that their hidden identifiers type - ;Currently broken in test-suite because of binding differences - #; (tc-e (void exn exn:fail exn:fail:contract diff --git a/collects/typed-scheme/base-env/base-structs.rkt b/collects/typed-scheme/base-env/base-structs.rkt index 833de9dfe0..daf9779814 100644 --- a/collects/typed-scheme/base-env/base-structs.rkt +++ b/collects/typed-scheme/base-env/base-structs.rkt @@ -7,7 +7,9 @@ (except-in (rep filter-rep object-rep type-rep) make-arr) (types convenience union) (only-in (types convenience) [make-arr* make-arr]) - (typecheck tc-structs)) + (typecheck tc-structs) + ;;For tests + (prefix-in k: '#%kernel)) (require (for-template racket/base (prefix-in k: '#%kernel))) From 9bd8e67e86b2b66300dae56bfe711055440d793d Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 3 Aug 2011 15:23:14 -0400 Subject: [PATCH 328/746] v5.1.2 stuff (cherry picked from commit 89dfe3dc50fd07cb9392803593911bf1c96b50e9) --- collects/meta/web/download/installers.txt | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index 5090d8cddf..44fbbf3aae 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -84,6 +84,34 @@ 16M 5.1.1/racket/racket-5.1.1-src-mac.dmg 16M 5.1.1/racket/racket-5.1.1-src-unix.tgz 19M 5.1.1/racket/racket-5.1.1-src-win.zip +9.9M 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-linux-f12.sh +9.9M 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-linux-ubuntu-jaunty.sh +11M 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-osx-mac.dmg +7.4M 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-win32.exe +9.8M 5.1.2/racket-textual/racket-textual-5.1.2-bin-ppc-darwin.sh +11M 5.1.2/racket-textual/racket-textual-5.1.2-bin-ppc-osx-mac.dmg +10M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-debian-lenny.sh +10M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-debian-squeeze.sh +10M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-f14.sh +11M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-osx-mac.dmg +7.7M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-win32.exe +5.7M 5.1.2/racket-textual/racket-textual-5.1.2-src-mac.dmg +5.6M 5.1.2/racket-textual/racket-textual-5.1.2-src-unix.tgz +6.6M 5.1.2/racket-textual/racket-textual-5.1.2-src-win.zip +48M 5.1.2/racket/racket-5.1.2-bin-i386-linux-f12.sh +48M 5.1.2/racket/racket-5.1.2-bin-i386-linux-ubuntu-jaunty.sh +50M 5.1.2/racket/racket-5.1.2-bin-i386-osx-mac.dmg +32M 5.1.2/racket/racket-5.1.2-bin-i386-win32.exe +48M 5.1.2/racket/racket-5.1.2-bin-ppc-darwin.sh +51M 5.1.2/racket/racket-5.1.2-bin-ppc-osx-mac.dmg +49M 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-debian-lenny.sh +49M 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-debian-squeeze.sh +49M 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-f14.sh +50M 5.1.2/racket/racket-5.1.2-bin-x86_64-osx-mac.dmg +32M 5.1.2/racket/racket-5.1.2-bin-x86_64-win32.exe +16M 5.1.2/racket/racket-5.1.2-src-mac.dmg +16M 5.1.2/racket/racket-5.1.2-src-unix.tgz +19M 5.1.2/racket/racket-5.1.2-src-win.zip 11M 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-f12.sh 11M 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-ubuntu-jaunty.sh 11M 5.1/racket-textual/racket-textual-5.1-bin-i386-osx-mac.dmg From 71cf6d1c15fe01878198f9e673fc2834215fd929 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 14 Aug 2011 08:42:06 -0400 Subject: [PATCH 329/746] Version number for the v5.1.3 bugfix release --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 7dea218c99..4a7a117521 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,11 +13,11 @@ consistently.) */ -#define MZSCHEME_VERSION "5.1.2" +#define MZSCHEME_VERSION "5.1.3" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 1 -#define MZSCHEME_VERSION_Z 2 +#define MZSCHEME_VERSION_Z 3 #define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) From aa27d4f1caf9c7b44586ca2bf751de981f67b823 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 3 Aug 2011 09:57:31 -0500 Subject: [PATCH 330/746] get rid of a broken attempt to optimize the 20,000-ft overview refreshing closes PR 12083 (cherry picked from commit 29a843ac379438a6b7540716c68537a09c62ac51) --- collects/framework/private/text.rkt | 1 - 1 file changed, 1 deletion(-) diff --git a/collects/framework/private/text.rkt b/collects/framework/private/text.rkt index bb9609d414..b8c7c1d8ad 100644 --- a/collects/framework/private/text.rkt +++ b/collects/framework/private/text.rkt @@ -1531,7 +1531,6 @@ (refresh-delegate)) (define/private (refresh-delegate) - (set! todo '()) (to-delegate (λ () (refresh-delegate/do-work)))) (define/private (refresh-delegate/do-work) From 75ab172281c647ae4c9a97b804d998b9062089ff Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 7 Aug 2011 18:39:22 -0500 Subject: [PATCH 331/746] manage the state for delegates better (used by the drracket contour window) closes PR 12094 (cherry picked from commit 38596a9b581c06a7bdc8faba26c8e0cfb1b09492) --- collects/framework/private/text.rkt | 34 +++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/collects/framework/private/text.rkt b/collects/framework/private/text.rkt index b8c7c1d8ad..1535d8d7fe 100644 --- a/collects/framework/private/text.rkt +++ b/collects/framework/private/text.rkt @@ -1505,15 +1505,22 @@ (send new-snip set-style (send snip get-style)) new-snip)) + ;; todo : (listof (-> void)) + ;; actions that have happened to this editor, but that + ;; have not yet been propogated to the delegate (define todo '()) + (define timer (new timer% [notify-callback (λ () - (send delegate begin-edit-sequence) - (for ([th (in-list (reverse todo))]) - (th)) - (send delegate end-edit-sequence) + ;; it should be the case that todo is always '() when the delegate is #f + (when delegate + (send delegate begin-edit-sequence) + (for ([th (in-list (reverse todo))]) + (th)) + (send delegate end-edit-sequence)) (set! todo '()))])) + (define/private (to-delegate thunk) (when delegate (send timer stop) @@ -1524,6 +1531,25 @@ (inherit get-highlighted-ranges) (define/public-final (get-delegate) delegate) (define/public-final (set-delegate _d) + (set! todo '()) + + (when delegate + ;; the delegate may be in a bad state because we've killed the pending todo + ;; items; to clear out the bad state, end any edit sequences, and unhighlight + ;; any highlighted ranges. The rest of the state is reset if the editor + ;; is ever installed as a delegate again (by refresh-delegate) + (let loop () + (when (send delegate in-edit-sequence?) + (send delegate end-edit-sequence) + (loop))) + (for ([range (in-list (send delegate get-highlighted-ranges))]) + (send delegate unhighlight-range + (range-start range) + (range-end range) + (range-color range) + (range-caret-space? range) + (range-style range)))) + (set! delegate _d) (set! linked-snips (if _d (make-hasheq) From 0816b0542535cb2dbacff1e27d02a23862b49ff7 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 6 Aug 2011 20:58:45 -0400 Subject: [PATCH 332/746] Make `mzlib/etc' reprovide `identity' from `racket/function'. (cherry picked from commit d952a05ea9cbc974e65dd45b04adbf752bfd3b50) --- collects/mzlib/etc.rkt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/mzlib/etc.rkt b/collects/mzlib/etc.rkt index bb72508e63..376d0a8bb9 100644 --- a/collects/mzlib/etc.rkt +++ b/collects/mzlib/etc.rkt @@ -2,8 +2,10 @@ (require setup/main-collects racket/local - racket/bool + racket/bool racket/block + (only racket/function + identity) (only scheme/base build-string build-list @@ -51,8 +53,6 @@ begin-lifted) -(define identity (lambda (x) x)) - (define (loop-until start done? next body) (let loop ([i start]) (unless (done? i) From c7562516a2a28b4b16fe5d8b8dd55adf9d331ade Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 14 Aug 2011 09:57:55 -0400 Subject: [PATCH 333/746] New Racket version 5.1.3. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index cfc0dcd9f6..b187660584 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 3f62ed67d6..03a6a42c1f 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,2,0 - PRODUCTVERSION 5,1,2,0 + FILEVERSION 5,1,3,0 + PRODUCTVERSION 5,1,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 1, 2, 0\0" + VALUE "FileVersion", "5, 1, 3, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 2, 0\0" + VALUE "ProductVersion", "5, 1, 3, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 8810ba95cd..24f7a11430 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,2,0 - PRODUCTVERSION 5,1,2,0 + FILEVERSION 5,1,3,0 + PRODUCTVERSION 5,1,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 1, 2, 0" + VALUE "FileVersion", "5, 1, 3, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 1, 2, 0" + VALUE "ProductVersion", "5, 1, 3, 0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index b6f4396c6f..1e4604a620 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.1.2.0 = s 'MzObj Class' + MzCOM.MzObj.5.1.3.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.1.2.0' + CurVer = s 'MzCOM.MzObj.5.1.3.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.1.2.0' + ProgID = s 'MzCOM.MzObj.5.1.3.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 6ba8306cb7..563d1c4cb3 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 581a4c356c..a0ab3ff6e7 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,2,0 - PRODUCTVERSION 5,1,2,0 + FILEVERSION 5,1,3,0 + PRODUCTVERSION 5,1,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 1, 2, 0\0" + VALUE "FileVersion", "5, 1, 3, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 2, 0\0" + VALUE "ProductVersion", "5, 1, 3, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 594f962327..5974d07637 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,2,0 - PRODUCTVERSION 5,1,2,0 + FILEVERSION 5,1,3,0 + PRODUCTVERSION 5,1,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 1, 2, 0\0" + VALUE "FileVersion", "5, 1, 3, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 2, 0\0" + VALUE "ProductVersion", "5, 1, 3, 0\0" END END BLOCK "VarFileInfo" From 413a717bccd7c542893ab65d5f9b22e754e2e2bc Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 14 Aug 2011 17:18:55 -0400 Subject: [PATCH 334/746] Remove badly-licensed file for 5.1.3. (In the head it gets auto-downloaded.) --- collects/scribble/sigplan/sigplanconf.cls | 1251 +-------------------- 1 file changed, 2 insertions(+), 1249 deletions(-) diff --git a/collects/scribble/sigplan/sigplanconf.cls b/collects/scribble/sigplan/sigplanconf.cls index 19a4871f5b..015b13c2b4 100644 --- a/collects/scribble/sigplan/sigplanconf.cls +++ b/collects/scribble/sigplan/sigplanconf.cls @@ -1,1251 +1,4 @@ -%----------------------------------------------------------------------------- -% -% LaTeX Class/Style File -% -% Name: sigplanconf.cls -% Purpose: A LaTeX 2e class file for SIGPLAN conference proceedings. -% This class file supercedes acm_proc_article-sp, -% sig-alternate, and sigplan-proc. -% -% Author: Paul C. Anagnostopoulos -% Windfall Software -% 978 371-2316 -% sigplan-style [atsign] acm.org -% -% Created: 12 September 2004 -% -% Revisions: See end of file. -% -%----------------------------------------------------------------------------- - - \NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesClass{sigplanconf}[2010/05/24 v2.4 ACM SIGPLAN Proceedings] +\ProvidesClass{sigplanconf} -% The following few pages contain LaTeX programming extensions adapted -% from the ZzTeX macro package. - -% Token Hackery -% ----- ------- - - -\def \@expandaftertwice {\expandafter\expandafter\expandafter} -\def \@expandafterthrice {\expandafter\expandafter\expandafter\expandafter - \expandafter\expandafter\expandafter} - -% This macro discards the next token. - -\def \@discardtok #1{}% token - -% This macro removes the `pt' following a dimension. - -{\catcode `\p = 12 \catcode `\t = 12 - -\gdef \@remover #1pt{#1} - -} % \catcode - -% This macro extracts the contents of a macro and returns it as plain text. -% Usage: \expandafter\@defof \meaning\macro\@mark - -\def \@defof #1:->#2\@mark{#2} - -% Control Sequence Names -% ------- -------- ----- - - -\def \@name #1{% {\tokens} - \csname \expandafter\@discardtok \string#1\endcsname} - -\def \@withname #1#2{% {\command}{\tokens} - \expandafter#1\csname \expandafter\@discardtok \string#2\endcsname} - -% Flags (Booleans) -% ----- ---------- - -% The boolean literals \@true and \@false are appropriate for use with -% the \if command, which tests the codes of the next two characters. - -\def \@true {TT} -\def \@false {FL} - -\def \@setflag #1=#2{\edef #1{#2}}% \flag = boolean - -% IF and Predicates -% -- --- ---------- - -% A "predicate" is a macro that returns \@true or \@false as its value. -% Such values are suitable for use with the \if conditional. For example: -% -% \if \@oddp{\x} \else \fi - -% A predicate can be used with \@setflag as follows: -% -% \@setflag \flag = {} - -% Here are the predicates for TeX's repertoire of conditional -% commands. These might be more appropriately interspersed with -% other definitions in this module, but what the heck. -% Some additional "obvious" predicates are defined. - -\def \@eqlp #1#2{\ifnum #1 = #2\@true \else \@false \fi} -\def \@neqlp #1#2{\ifnum #1 = #2\@false \else \@true \fi} -\def \@lssp #1#2{\ifnum #1 < #2\@true \else \@false \fi} -\def \@gtrp #1#2{\ifnum #1 > #2\@true \else \@false \fi} -\def \@zerop #1{\ifnum #1 = 0\@true \else \@false \fi} -\def \@onep #1{\ifnum #1 = 1\@true \else \@false \fi} -\def \@posp #1{\ifnum #1 > 0\@true \else \@false \fi} -\def \@negp #1{\ifnum #1 < 0\@true \else \@false \fi} -\def \@oddp #1{\ifodd #1\@true \else \@false \fi} -\def \@evenp #1{\ifodd #1\@false \else \@true \fi} -\def \@rangep #1#2#3{\if \@orp{\@lssp{#1}{#2}}{\@gtrp{#1}{#3}}\@false \else - \@true \fi} -\def \@tensp #1{\@rangep{#1}{10}{19}} - -\def \@dimeqlp #1#2{\ifdim #1 = #2\@true \else \@false \fi} -\def \@dimneqlp #1#2{\ifdim #1 = #2\@false \else \@true \fi} -\def \@dimlssp #1#2{\ifdim #1 < #2\@true \else \@false \fi} -\def \@dimgtrp #1#2{\ifdim #1 > #2\@true \else \@false \fi} -\def \@dimzerop #1{\ifdim #1 = 0pt\@true \else \@false \fi} -\def \@dimposp #1{\ifdim #1 > 0pt\@true \else \@false \fi} -\def \@dimnegp #1{\ifdim #1 < 0pt\@true \else \@false \fi} - -\def \@vmodep {\ifvmode \@true \else \@false \fi} -\def \@hmodep {\ifhmode \@true \else \@false \fi} -\def \@mathmodep {\ifmmode \@true \else \@false \fi} -\def \@textmodep {\ifmmode \@false \else \@true \fi} -\def \@innermodep {\ifinner \@true \else \@false \fi} - -\long\def \@codeeqlp #1#2{\if #1#2\@true \else \@false \fi} - -\long\def \@cateqlp #1#2{\ifcat #1#2\@true \else \@false \fi} - -\long\def \@tokeqlp #1#2{\ifx #1#2\@true \else \@false \fi} -\long\def \@xtokeqlp #1#2{\expandafter\ifx #1#2\@true \else \@false \fi} - -\long\def \@definedp #1{% - \expandafter\ifx \csname \expandafter\@discardtok \string#1\endcsname - \relax \@false \else \@true \fi} - -\long\def \@undefinedp #1{% - \expandafter\ifx \csname \expandafter\@discardtok \string#1\endcsname - \relax \@true \else \@false \fi} - -\def \@emptydefp #1{\ifx #1\@empty \@true \else \@false \fi}% {\name} - -\let \@emptylistp = \@emptydefp - -\long\def \@emptyargp #1{% {#n} - \@empargp #1\@empargq\@mark} -\long\def \@empargp #1#2\@mark{% - \ifx #1\@empargq \@true \else \@false \fi} -\def \@empargq {\@empargq} - -\def \@emptytoksp #1{% {\tokenreg} - \expandafter\@emptoksp \the#1\@mark} - -\long\def \@emptoksp #1\@mark{\@emptyargp{#1}} - -\def \@voidboxp #1{\ifvoid #1\@true \else \@false \fi} -\def \@hboxp #1{\ifhbox #1\@true \else \@false \fi} -\def \@vboxp #1{\ifvbox #1\@true \else \@false \fi} - -\def \@eofp #1{\ifeof #1\@true \else \@false \fi} - - -% Flags can also be used as predicates, as in: -% -% \if \flaga \else \fi - - -% Now here we have predicates for the common logical operators. - -\def \@notp #1{\if #1\@false \else \@true \fi} - -\def \@andp #1#2{\if #1% - \if #2\@true \else \@false \fi - \else - \@false - \fi} - -\def \@orp #1#2{\if #1% - \@true - \else - \if #2\@true \else \@false \fi - \fi} - -\def \@xorp #1#2{\if #1% - \if #2\@false \else \@true \fi - \else - \if #2\@true \else \@false \fi - \fi} - -% Arithmetic -% ---------- - -\def \@increment #1{\advance #1 by 1\relax}% {\count} - -\def \@decrement #1{\advance #1 by -1\relax}% {\count} - -% Options -% ------- - - -\@setflag \@authoryear = \@false -\@setflag \@blockstyle = \@false -\@setflag \@copyrightwanted = \@true -\@setflag \@explicitsize = \@false -\@setflag \@mathtime = \@false -\@setflag \@natbib = \@true -\@setflag \@ninepoint = \@true -\newcount{\@numheaddepth} \@numheaddepth = 3 -\@setflag \@onecolumn = \@false -\@setflag \@preprint = \@false -\@setflag \@reprint = \@false -\@setflag \@tenpoint = \@false -\@setflag \@times = \@false - -% Note that all the dangerous article class options are trapped. - -\DeclareOption{9pt}{\@setflag \@ninepoint = \@true - \@setflag \@explicitsize = \@true} - -\DeclareOption{10pt}{\PassOptionsToClass{10pt}{article}% - \@setflag \@ninepoint = \@false - \@setflag \@tenpoint = \@true - \@setflag \@explicitsize = \@true} - -\DeclareOption{11pt}{\PassOptionsToClass{11pt}{article}% - \@setflag \@ninepoint = \@false - \@setflag \@explicitsize = \@true} - -\DeclareOption{12pt}{\@unsupportedoption{12pt}} - -\DeclareOption{a4paper}{\@unsupportedoption{a4paper}} - -\DeclareOption{a5paper}{\@unsupportedoption{a5paper}} - -\DeclareOption{authoryear}{\@setflag \@authoryear = \@true} - -\DeclareOption{b5paper}{\@unsupportedoption{b5paper}} - -\DeclareOption{blockstyle}{\@setflag \@blockstyle = \@true} - -\DeclareOption{cm}{\@setflag \@times = \@false} - -\DeclareOption{computermodern}{\@setflag \@times = \@false} - -\DeclareOption{executivepaper}{\@unsupportedoption{executivepaper}} - -\DeclareOption{indentedstyle}{\@setflag \@blockstyle = \@false} - -\DeclareOption{landscape}{\@unsupportedoption{landscape}} - -\DeclareOption{legalpaper}{\@unsupportedoption{legalpaper}} - -\DeclareOption{letterpaper}{\@unsupportedoption{letterpaper}} - -\DeclareOption{mathtime}{\@setflag \@mathtime = \@true} - -\DeclareOption{natbib}{\@setflag \@natbib = \@true} - -\DeclareOption{nonatbib}{\@setflag \@natbib = \@false} - -\DeclareOption{nocopyrightspace}{\@setflag \@copyrightwanted = \@false} - -\DeclareOption{notitlepage}{\@unsupportedoption{notitlepage}} - -\DeclareOption{numberedpars}{\@numheaddepth = 4} - -\DeclareOption{numbers}{\@setflag \@authoryear = \@false} - -\DeclareOption{onecolumn}{\@setflag \@onecolumn = \@true} - -\DeclareOption{preprint}{\@setflag \@preprint = \@true} - -\DeclareOption{reprint}{\@setflag \@reprint = \@true} - -\DeclareOption{times}{\@setflag \@times = \@true} - -\DeclareOption{titlepage}{\@unsupportedoption{titlepage}} - -\DeclareOption{twocolumn}{\@setflag \@onecolumn = \@false} - -\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} - -\ExecuteOptions{9pt,indentedstyle,times} -\@setflag \@explicitsize = \@false -\ProcessOptions - -\if \@onecolumn - \if \@notp{\@explicitsize}% - \@setflag \@ninepoint = \@false -% \PassOptionsToClass{11pt}{article}% - \fi - \PassOptionsToClass{twoside,onecolumn}{article} -\else - \PassOptionsToClass{twoside,twocolumn}{article} -\fi -\LoadClass{article} - -\def \@unsupportedoption #1{% - \ClassError{proc}{The standard '#1' option is not supported.}} - -% This can be used with the 'reprint' option to get the final folios. - -\def \setpagenumber #1{% - \setcounter{page}{#1}} - -\AtEndDocument{\label{sigplanconf@finalpage}} - -% Utilities -% --------- - - -\newcommand{\setvspace}[2]{% - #1 = #2 - \advance #1 by -1\parskip} - -% Document Parameters -% -------- ---------- - - -% Page: - -\setlength{\hoffset}{-1in} -\setlength{\voffset}{-1in} - -\setlength{\topmargin}{1in} -\setlength{\headheight}{0pt} -\setlength{\headsep}{0pt} - -\if \@onecolumn - \setlength{\evensidemargin}{.75in} - \setlength{\oddsidemargin}{.75in} -\else - \setlength{\evensidemargin}{.75in} - \setlength{\oddsidemargin}{.75in} -\fi - -% Text area: - -\newdimen{\standardtextwidth} -\setlength{\standardtextwidth}{42pc} - -\if \@onecolumn - \setlength{\textwidth}{20pc} -\else - \setlength{\textwidth}{\standardtextwidth} -\fi - -\setlength{\topskip}{8pt} -\setlength{\columnsep}{2pc} -\setlength{\textheight}{54.5pc} - -% Running foot: - -\setlength{\footskip}{30pt} - -% Paragraphs: - -\if \@blockstyle - \setlength{\parskip}{5pt plus .1pt minus .5pt} - \setlength{\parindent}{0pt} -\else - \setlength{\parskip}{0pt} - \setlength{\parindent}{12pt} -\fi - -\setlength{\lineskip}{.5pt} -\setlength{\lineskiplimit}{\lineskip} - -\frenchspacing -\pretolerance = 400 -\tolerance = \pretolerance -\setlength{\emergencystretch}{5pt} -\clubpenalty = 10000 -\widowpenalty = 10000 -\setlength{\hfuzz}{.5pt} - -% Standard vertical spaces: - -\newskip{\standardvspace} -\setvspace{\standardvspace}{5pt plus 1pt minus .5pt} - -% Margin paragraphs: - -\setlength{\marginparwidth}{36pt} -\setlength{\marginparsep}{2pt} -\setlength{\marginparpush}{8pt} - - -\setlength{\skip\footins}{8pt plus 3pt minus 1pt} -\setlength{\footnotesep}{9pt} - -\renewcommand{\footnoterule}{% - \hrule width .5\columnwidth height .33pt depth 0pt} - -\renewcommand{\@makefntext}[1]{% - \noindent \@makefnmark \hspace{1pt}#1} - -% Floats: - -\setcounter{topnumber}{4} -\setcounter{bottomnumber}{1} -\setcounter{totalnumber}{4} - -\renewcommand{\fps@figure}{tp} -\renewcommand{\fps@table}{tp} -\renewcommand{\topfraction}{0.90} -\renewcommand{\bottomfraction}{0.30} -\renewcommand{\textfraction}{0.10} -\renewcommand{\floatpagefraction}{0.75} - -\setcounter{dbltopnumber}{4} - -\renewcommand{\dbltopfraction}{\topfraction} -\renewcommand{\dblfloatpagefraction}{\floatpagefraction} - -\setlength{\floatsep}{18pt plus 4pt minus 2pt} -\setlength{\textfloatsep}{18pt plus 4pt minus 3pt} -\setlength{\intextsep}{10pt plus 4pt minus 3pt} - -\setlength{\dblfloatsep}{18pt plus 4pt minus 2pt} -\setlength{\dbltextfloatsep}{20pt plus 4pt minus 3pt} - -% Miscellaneous: - -\errorcontextlines = 5 - -% Fonts -% ----- - - -\if \@times - \renewcommand{\rmdefault}{ptm}% - \if \@mathtime - \usepackage[mtbold,noTS1]{mathtime}% - \else -%%% \usepackage{mathptm}% - \fi -\else - \relax -\fi - -\if \@ninepoint - -\renewcommand{\normalsize}{% - \@setfontsize{\normalsize}{9pt}{10pt}% - \setlength{\abovedisplayskip}{5pt plus 1pt minus .5pt}% - \setlength{\belowdisplayskip}{\abovedisplayskip}% - \setlength{\abovedisplayshortskip}{3pt plus 1pt minus 2pt}% - \setlength{\belowdisplayshortskip}{\abovedisplayshortskip}} - -\renewcommand{\tiny}{\@setfontsize{\tiny}{5pt}{6pt}} - -\renewcommand{\scriptsize}{\@setfontsize{\scriptsize}{7pt}{8pt}} - -\renewcommand{\small}{% - \@setfontsize{\small}{8pt}{9pt}% - \setlength{\abovedisplayskip}{4pt plus 1pt minus 1pt}% - \setlength{\belowdisplayskip}{\abovedisplayskip}% - \setlength{\abovedisplayshortskip}{2pt plus 1pt}% - \setlength{\belowdisplayshortskip}{\abovedisplayshortskip}} - -\renewcommand{\footnotesize}{% - \@setfontsize{\footnotesize}{8pt}{9pt}% - \setlength{\abovedisplayskip}{4pt plus 1pt minus .5pt}% - \setlength{\belowdisplayskip}{\abovedisplayskip}% - \setlength{\abovedisplayshortskip}{2pt plus 1pt}% - \setlength{\belowdisplayshortskip}{\abovedisplayshortskip}} - -\renewcommand{\large}{\@setfontsize{\large}{11pt}{13pt}} - -\renewcommand{\Large}{\@setfontsize{\Large}{14pt}{18pt}} - -\renewcommand{\LARGE}{\@setfontsize{\LARGE}{18pt}{20pt}} - -\renewcommand{\huge}{\@setfontsize{\huge}{20pt}{25pt}} - -\renewcommand{\Huge}{\@setfontsize{\Huge}{25pt}{30pt}} - -\else\if \@tenpoint - -\relax - -\else - -\relax - -\fi\fi - -% Abstract -% -------- - - -\renewenvironment{abstract}{% - \section*{Abstract}% - \normalsize}{% - } - -% Bibliography -% ------------ - - -\renewenvironment{thebibliography}[1] - {\section*{\refname - \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}}% - \list{\@biblabel{\@arabic\c@enumiv}}% - {\settowidth\labelwidth{\@biblabel{#1}}% - \leftmargin\labelwidth - \advance\leftmargin\labelsep - \@openbib@code - \usecounter{enumiv}% - \let\p@enumiv\@empty - \renewcommand\theenumiv{\@arabic\c@enumiv}}% - \bibfont - \clubpenalty4000 - \@clubpenalty \clubpenalty - \widowpenalty4000% - \sfcode`\.\@m} - {\def\@noitemerr - {\@latex@warning{Empty `thebibliography' environment}}% - \endlist} - -\if \@natbib - -\if \@authoryear - \typeout{Using natbib package with 'authoryear' citation style.} - \usepackage[authoryear,sort,square]{natbib} - \bibpunct{[}{]}{;}{a}{}{,} % Change citation separator to semicolon, - % eliminate comma between author and year. - \let \cite = \citep -\else - \typeout{Using natbib package with 'numbers' citation style.} - \usepackage[numbers,sort&compress,square]{natbib} -\fi -\setlength{\bibsep}{3pt plus .5pt minus .25pt} - -\fi - -\def \bibfont {\small} - -% Categories -% ---------- - - -\@setflag \@firstcategory = \@true - -\newcommand{\category}[3]{% - \if \@firstcategory - \paragraph*{Categories and Subject Descriptors}% - \@setflag \@firstcategory = \@false - \else - \unskip ;\hspace{.75em}% - \fi - \@ifnextchar [{\@category{#1}{#2}{#3}}{\@category{#1}{#2}{#3}[]}} - -\def \@category #1#2#3[#4]{% - {\let \and = \relax - #1 [\textit{#2}]% - \if \@emptyargp{#4}% - \if \@notp{\@emptyargp{#3}}: #3\fi - \else - :\space - \if \@notp{\@emptyargp{#3}}#3---\fi - \textrm{#4}% - \fi}} - -% Copyright Notice -% --------- ------ - - -\def \ftype@copyrightbox {8} -\def \@toappear {} -\def \@permission {} -\def \@reprintprice {} - -\def \@copyrightspace {% - \@float{copyrightbox}[b]% - \vbox to 1in{% - \vfill - \parbox[b]{20pc}{% - \scriptsize - \if \@preprint - [Copyright notice will appear here - once 'preprint' option is removed.]\par - \else - \@toappear - \fi - \if \@reprint - \noindent Reprinted from \@conferencename, - \@proceedings, - \@conferenceinfo, - pp.~\number\thepage--\pageref{sigplanconf@finalpage}.\par - \fi}}% - \end@float} - -\long\def \toappear #1{% - \def \@toappear {#1}} - -\toappear{% - \noindent \@permission \par - \vspace{2pt} - \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par - \noindent Copyright \copyright\ \@copyrightyear\ ACM \@copyrightdata - \dots \@reprintprice\par} - -\newcommand{\permission}[1]{% - \gdef \@permission {#1}} - -\permission{% - Permission to make digital or hard copies of all or - part of this work for personal or classroom use is granted without - fee provided that copies are not made or distributed for profit or - commercial advantage and that copies bear this notice and the full - citation on the first page. To copy otherwise, to republish, to - post on servers or to redistribute to lists, requires prior specific - permission and/or a fee.} - -% Here we have some alternate permission statements and copyright lines: - -\newcommand{\ACMCanadapermission}{% - \permission{% - Copyright \@copyrightyear\ Association for Computing Machinery. - ACM acknowledges that - this contribution was authored or co-authored by an affiliate of the - National Research Council of Canada (NRC). - As such, the Crown in Right of - Canada retains an equal interest in the copyright, however granting - nonexclusive, royalty-free right to publish or reproduce this article, - or to allow others to do so, provided that clear attribution - is also given to the authors and the NRC.}} - -\newcommand{\ACMUSpermission}{% - \permission{% - Copyright \@copyrightyear\ Association for - Computing Machinery. ACM acknowledges that - this contribution was authored or co-authored - by a contractor or affiliate - of the U.S. Government. As such, the Government retains a nonexclusive, - royalty-free right to publish or reproduce this article, - or to allow others to do so, for Government purposes only.}} - -\newcommand{\authorpermission}{% - \permission{% - Copyright is held by the author/owner(s).} - \toappear{% - \noindent \@permission \par - \vspace{2pt} - \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par - ACM \@copyrightdata.}} - -\newcommand{\Sunpermission}{% - \permission{% - Copyright is held by Sun Microsystems, Inc.}% - \toappear{% - \noindent \@permission \par - \vspace{2pt} - \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par - ACM \@copyrightdata.}} - -\newcommand{\USpublicpermission}{% - \permission{% - This paper is authored by an employee(s) of the United States - Government and is in the public domain.}% - \toappear{% - \noindent \@permission \par - \vspace{2pt} - \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par - ACM \@copyrightdata.}} - -\newcommand{\reprintprice}[1]{% - \gdef \@reprintprice {#1}} - -\reprintprice{\$10.00} - -% Enunciations -% ------------ - - -\def \@begintheorem #1#2{% {name}{number} - \trivlist - \item[\hskip \labelsep \textsc{#1 #2.}]% - \itshape\selectfont - \ignorespaces} - -\def \@opargbegintheorem #1#2#3{% {name}{number}{title} - \trivlist - \item[% - \hskip\labelsep \textsc{#1\ #2}% - \if \@notp{\@emptyargp{#3}}\nut (#3).\fi]% - \itshape\selectfont - \ignorespaces} - -% Figures -% ------- - - -\@setflag \@caprule = \@true - -\long\def \@makecaption #1#2{% - \addvspace{4pt} - \if \@caprule - \hrule width \hsize height .33pt - \vspace{4pt} - \fi - \setbox \@tempboxa = \hbox{\@setfigurenumber{#1.}\nut #2}% - \if \@dimgtrp{\wd\@tempboxa}{\hsize}% - \noindent \@setfigurenumber{#1.}\nut #2\par - \else - \centerline{\box\@tempboxa}% - \fi} - -\newcommand{\nocaptionrule}{% - \@setflag \@caprule = \@false} - -\def \@setfigurenumber #1{% - {\rmfamily \bfseries \selectfont #1}} - -% Hierarchy -% --------- - - -\setcounter{secnumdepth}{\@numheaddepth} - -\newskip{\@sectionaboveskip} -\setvspace{\@sectionaboveskip}{10pt plus 3pt minus 2pt} - -\newskip{\@sectionbelowskip} -\if \@blockstyle - \setlength{\@sectionbelowskip}{0.1pt}% -\else - \setlength{\@sectionbelowskip}{4pt}% -\fi - -\renewcommand{\section}{% - \@startsection - {section}% - {1}% - {0pt}% - {-\@sectionaboveskip}% - {\@sectionbelowskip}% - {\large \bfseries \raggedright}} - -\newskip{\@subsectionaboveskip} -\setvspace{\@subsectionaboveskip}{8pt plus 2pt minus 2pt} - -\newskip{\@subsectionbelowskip} -\if \@blockstyle - \setlength{\@subsectionbelowskip}{0.1pt}% -\else - \setlength{\@subsectionbelowskip}{4pt}% -\fi - -\renewcommand{\subsection}{% - \@startsection% - {subsection}% - {2}% - {0pt}% - {-\@subsectionaboveskip}% - {\@subsectionbelowskip}% - {\normalsize \bfseries \raggedright}} - -\renewcommand{\subsubsection}{% - \@startsection% - {subsubsection}% - {3}% - {0pt}% - {-\@subsectionaboveskip} - {\@subsectionbelowskip}% - {\normalsize \bfseries \raggedright}} - -\newskip{\@paragraphaboveskip} -\setvspace{\@paragraphaboveskip}{6pt plus 2pt minus 2pt} - -\renewcommand{\paragraph}{% - \@startsection% - {paragraph}% - {4}% - {0pt}% - {\@paragraphaboveskip} - {-1em}% - {\normalsize \bfseries \if \@times \itshape \fi}} - -\renewcommand{\subparagraph}{% - \@startsection% - {subparagraph}% - {4}% - {0pt}% - {\@paragraphaboveskip} - {-1em}% - {\normalsize \itshape}} - -% Standard headings: - -\newcommand{\acks}{\section*{Acknowledgments}} - -\newcommand{\keywords}{\paragraph*{Keywords}} - -\newcommand{\terms}{\paragraph*{General Terms}} - -% Identification -% -------------- - - -\def \@conferencename {} -\def \@conferenceinfo {} -\def \@copyrightyear {} -\def \@copyrightdata {[to be supplied]} -\def \@proceedings {[Unknown Proceedings]} - - -\newcommand{\conferenceinfo}[2]{% - \gdef \@conferencename {#1}% - \gdef \@conferenceinfo {#2}} - -\newcommand{\copyrightyear}[1]{% - \gdef \@copyrightyear {#1}} - -\let \CopyrightYear = \copyrightyear - -\newcommand{\copyrightdata}[1]{% - \gdef \@copyrightdata {#1}} - -\let \crdata = \copyrightdata - -\newcommand{\proceedings}[1]{% - \gdef \@proceedings {#1}} - -% Lists -% ----- - - -\setlength{\leftmargini}{13pt} -\setlength\leftmarginii{13pt} -\setlength\leftmarginiii{13pt} -\setlength\leftmarginiv{13pt} -\setlength{\labelsep}{3.5pt} - -\setlength{\topsep}{\standardvspace} -\if \@blockstyle - \setlength{\itemsep}{1pt} - \setlength{\parsep}{3pt} -\else - \setlength{\itemsep}{1pt} - \setlength{\parsep}{3pt} -\fi - -\renewcommand{\labelitemi}{{\small \centeroncapheight{\textbullet}}} -\renewcommand{\labelitemii}{\centeroncapheight{\rule{2.5pt}{2.5pt}}} -\renewcommand{\labelitemiii}{$-$} -\renewcommand{\labelitemiv}{{\Large \textperiodcentered}} - -\renewcommand{\@listi}{% - \leftmargin = \leftmargini - \listparindent = 0pt} -%%% \itemsep = 1pt -%%% \parsep = 3pt} -%%% \listparindent = \parindent} - -\let \@listI = \@listi - -\renewcommand{\@listii}{% - \leftmargin = \leftmarginii - \topsep = 1pt - \labelwidth = \leftmarginii - \advance \labelwidth by -\labelsep - \listparindent = \parindent} - -\renewcommand{\@listiii}{% - \leftmargin = \leftmarginiii - \labelwidth = \leftmarginiii - \advance \labelwidth by -\labelsep - \listparindent = \parindent} - -\renewcommand{\@listiv}{% - \leftmargin = \leftmarginiv - \labelwidth = \leftmarginiv - \advance \labelwidth by -\labelsep - \listparindent = \parindent} - -% Mathematics -% ----------- - - -\def \theequation {\arabic{equation}} - -% Miscellaneous -% ------------- - - -\newcommand{\balancecolumns}{% - \vfill\eject - \global\@colht = \textheight - \global\ht\@cclv = \textheight} - -\newcommand{\nut}{\hspace{.5em}} - -\newcommand{\softraggedright}{% - \let \\ = \@centercr - \leftskip = 0pt - \rightskip = 0pt plus 10pt} - -% Program Code -% ------- ---- - - -\newcommand{\mono}[1]{% - {\@tempdima = \fontdimen2\font - \texttt{\spaceskip = 1.1\@tempdima #1}}} - -% Running Heads and Feet -% ------- ----- --- ---- - - -\def \@preprintfooter {} - -\newcommand{\preprintfooter}[1]{% - \gdef \@preprintfooter {#1}} - -\if \@preprint - -\def \ps@plain {% - \let \@mkboth = \@gobbletwo - \let \@evenhead = \@empty - \def \@evenfoot {\scriptsize \textit{\@preprintfooter}\hfil \thepage \hfil - \textit{\@formatyear}}% - \let \@oddhead = \@empty - \let \@oddfoot = \@evenfoot} - -\else\if \@reprint - -\def \ps@plain {% - \let \@mkboth = \@gobbletwo - \let \@evenhead = \@empty - \def \@evenfoot {\scriptsize \hfil \thepage \hfil}% - \let \@oddhead = \@empty - \let \@oddfoot = \@evenfoot} - -\else - -\let \ps@plain = \ps@empty -\let \ps@headings = \ps@empty -\let \ps@myheadings = \ps@empty - -\fi\fi - -\def \@formatyear {% - \number\year/\number\month/\number\day} - -% Special Characters -% ------- ---------- - - -\DeclareRobustCommand{\euro}{% - \protect{\rlap{=}}{\sf \kern .1em C}} - -% Title Page -% ----- ---- - - -\@setflag \@addauthorsdone = \@false - -\def \@titletext {\@latex@error{No title was provided}{}} -\def \@subtitletext {} - -\newcount{\@authorcount} - -\newcount{\@titlenotecount} -\newtoks{\@titlenotetext} - -\def \@titlebanner {} - -\renewcommand{\title}[1]{% - \gdef \@titletext {#1}} - -\newcommand{\subtitle}[1]{% - \gdef \@subtitletext {#1}} - -\newcommand{\authorinfo}[3]{% {names}{affiliation}{email/URL} - \global\@increment \@authorcount - \@withname\gdef {\@authorname\romannumeral\@authorcount}{#1}% - \@withname\gdef {\@authoraffil\romannumeral\@authorcount}{#2}% - \@withname\gdef {\@authoremail\romannumeral\@authorcount}{#3}} - -\renewcommand{\author}[1]{% - \@latex@error{The \string\author\space command is obsolete; - use \string\authorinfo}{}} - -\newcommand{\titlebanner}[1]{% - \gdef \@titlebanner {#1}} - -\renewcommand{\maketitle}{% - \pagestyle{plain}% - \if \@onecolumn - {\hsize = \standardtextwidth - \@maketitle}% - \else - \twocolumn[\@maketitle]% - \fi - \@placetitlenotes - \if \@copyrightwanted \@copyrightspace \fi} - -\def \@maketitle {% - \begin{center} - \@settitlebanner - \let \thanks = \titlenote - {\leftskip = 0pt plus 0.25\linewidth - \rightskip = 0pt plus 0.25 \linewidth - \parfillskip = 0pt - \spaceskip = .7em - \noindent \LARGE \bfseries \@titletext \par} - \vskip 6pt - \noindent \Large \@subtitletext \par - \vskip 12pt - \ifcase \@authorcount - \@latex@error{No authors were specified for this paper}{}\or - \@titleauthors{i}{}{}\or - \@titleauthors{i}{ii}{}\or - \@titleauthors{i}{ii}{iii}\or - \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{}{}\or - \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{}\or - \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}\or - \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% - \@titleauthors{vii}{}{}\or - \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% - \@titleauthors{vii}{viii}{}\or - \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% - \@titleauthors{vii}{viii}{ix}\or - \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% - \@titleauthors{vii}{viii}{ix}\@titleauthors{x}{}{}\or - \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% - \@titleauthors{vii}{viii}{ix}\@titleauthors{x}{xi}{}\or - \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% - \@titleauthors{vii}{viii}{ix}\@titleauthors{x}{xi}{xii}% - \else - \@latex@error{Cannot handle more than 12 authors}{}% - \fi - \vspace{1.75pc} - \end{center}} - -\def \@settitlebanner {% - \if \@andp{\@preprint}{\@notp{\@emptydefp{\@titlebanner}}}% - \vbox to 0pt{% - \vskip -32pt - \noindent \textbf{\@titlebanner}\par - \vss}% - \nointerlineskip - \fi} - -\def \@titleauthors #1#2#3{% - \if \@andp{\@emptyargp{#2}}{\@emptyargp{#3}}% - \noindent \@setauthor{40pc}{#1}{\@false}\par - \else\if \@emptyargp{#3}% - \noindent \@setauthor{17pc}{#1}{\@false}\hspace{3pc}% - \@setauthor{17pc}{#2}{\@false}\par - \else - \noindent \@setauthor{12.5pc}{#1}{\@false}\hspace{2pc}% - \@setauthor{12.5pc}{#2}{\@false}\hspace{2pc}% - \@setauthor{12.5pc}{#3}{\@true}\par - \relax - \fi\fi - \vspace{20pt}} - -\def \@setauthor #1#2#3{% {width}{text}{unused} - \vtop{% - \def \and {% - \hspace{16pt}} - \hsize = #1 - \normalfont - \centering - \large \@name{\@authorname#2}\par - \vspace{5pt} - \normalsize \@name{\@authoraffil#2}\par - \vspace{2pt} - \textsf{\@name{\@authoremail#2}}\par}} - -\def \@maybetitlenote #1{% - \if \@andp{#1}{\@gtrp{\@authorcount}{3}}% - \titlenote{See page~\pageref{@addauthors} for additional authors.}% - \fi} - -\newtoks{\@fnmark} - -\newcommand{\titlenote}[1]{% - \global\@increment \@titlenotecount - \ifcase \@titlenotecount \relax \or - \@fnmark = {\ast}\or - \@fnmark = {\dagger}\or - \@fnmark = {\ddagger}\or - \@fnmark = {\S}\or - \@fnmark = {\P}\or - \@fnmark = {\ast\ast}% - \fi - \,$^{\the\@fnmark}$% - \edef \reserved@a {\noexpand\@appendtotext{% - \noexpand\@titlefootnote{\the\@fnmark}}}% - \reserved@a{#1}} - -\def \@appendtotext #1#2{% - \global\@titlenotetext = \expandafter{\the\@titlenotetext #1{#2}}} - -\newcount{\@authori} - -\iffalse -\def \additionalauthors {% - \if \@gtrp{\@authorcount}{3}% - \section{Additional Authors}% - \label{@addauthors}% - \noindent - \@authori = 4 - {\let \\ = ,% - \loop - \textbf{\@name{\@authorname\romannumeral\@authori}}, - \@name{\@authoraffil\romannumeral\@authori}, - email: \@name{\@authoremail\romannumeral\@authori}.% - \@increment \@authori - \if \@notp{\@gtrp{\@authori}{\@authorcount}} \repeat}% - \par - \fi - \global\@setflag \@addauthorsdone = \@true} -\fi - -\let \addauthorsection = \additionalauthors - -\def \@placetitlenotes { - \the\@titlenotetext} - -% Utilities -% --------- - - -\newcommand{\centeroncapheight}[1]{% - {\setbox\@tempboxa = \hbox{#1}% - \@measurecapheight{\@tempdima}% % Calculate ht(CAP) - ht(text) - \advance \@tempdima by -\ht\@tempboxa % ------------------ - \divide \@tempdima by 2 % 2 - \raise \@tempdima \box\@tempboxa}} - -\newbox{\@measbox} - -\def \@measurecapheight #1{% {\dimen} - \setbox\@measbox = \hbox{ABCDEFGHIJKLMNOPQRSTUVWXYZ}% - #1 = \ht\@measbox} - -\long\def \@titlefootnote #1#2{% - \insert\footins{% - \reset@font\footnotesize - \interlinepenalty\interfootnotelinepenalty - \splittopskip\footnotesep - \splitmaxdepth \dp\strutbox \floatingpenalty \@MM - \hsize\columnwidth \@parboxrestore -%%% \protected@edef\@currentlabel{% -%%% \csname p@footnote\endcsname\@thefnmark}% - \color@begingroup - \def \@makefnmark {$^{#1}$}% - \@makefntext{% - \rule\z@\footnotesep\ignorespaces#2\@finalstrut\strutbox}% - \color@endgroup}} - -% LaTeX Modifications -% ----- ------------- - -\def \@seccntformat #1{% - \@name{\the#1}% - \@expandaftertwice\@seccntformata \csname the#1\endcsname.\@mark - \quad} - -\def \@seccntformata #1.#2\@mark{% - \if \@emptyargp{#2}.\fi} - -% Revision History -% -------- ------- - - -% Date Person Ver. Change -% ---- ------ ---- ------ - -% 2004.09.12 PCA 0.1--5 Preliminary development. - -% 2004.11.18 PCA 0.5 Start beta testing. - -% 2004.11.19 PCA 0.6 Obsolete \author and replace with -% \authorinfo. -% Add 'nocopyrightspace' option. -% Compress article opener spacing. -% Add 'mathtime' option. -% Increase text height by 6 points. - -% 2004.11.28 PCA 0.7 Add 'cm/computermodern' options. -% Change default to Times text. - -% 2004.12.14 PCA 0.8 Remove use of mathptm.sty; it cannot -% coexist with latexsym or amssymb. - -% 2005.01.20 PCA 0.9 Rename class file to sigplanconf.cls. - -% 2005.03.05 PCA 0.91 Change default copyright data. - -% 2005.03.06 PCA 0.92 Add at-signs to some macro names. - -% 2005.03.07 PCA 0.93 The 'onecolumn' option defaults to '11pt', -% and it uses the full type width. - -% 2005.03.15 PCA 0.94 Add at-signs to more macro names. -% Allow margin paragraphs during review. - -% 2005.03.22 PCA 0.95 Implement \euro. -% Remove proof and newdef environments. - -% 2005.05.06 PCA 1.0 Eliminate 'onecolumn' option. -% Change footer to small italic and eliminate -% left portion if no \preprintfooter. -% Eliminate copyright notice if preprint. -% Clean up and shrink copyright box. - -% 2005.05.30 PCA 1.1 Add alternate permission statements. - -% 2005.06.29 PCA 1.1 Publish final first edition of guide. - -% 2005.07.14 PCA 1.2 Add \subparagraph. -% Use block paragraphs in lists, and adjust -% spacing between items and paragraphs. - -% 2006.06.22 PCA 1.3 Add 'reprint' option and associated -% commands. - -% 2006.08.24 PCA 1.4 Fix bug in \maketitle case command. - -% 2007.03.13 PCA 1.5 The title banner only displays with the -% 'preprint' option. - -% 2007.06.06 PCA 1.6 Use \bibfont in \thebibliography. -% Add 'natbib' option to load and configure -% the natbib package. - -% 2007.11.20 PCA 1.7 Balance line lengths in centered article -% title (thanks to Norman Ramsey). - -% 2009.01.26 PCA 1.8 Change natbib \bibpunct values. - -% 2009.03.24 PCA 1.9 Change natbib to use the 'numbers' option. -% Change templates to use 'natbib' option. - -% 2009.09.01 PCA 2.0 Add \reprintprice command (suggested by -% Stephen Chong). - -% 2009.09.08 PCA 2.1 Make 'natbib' the default; add 'nonatbib'. -% SB Add 'authoryear' and 'numbers' (default) to -% control citation style when using natbib. -% Add \bibpunct to change punctuation for -% 'authoryear' style. - -% 2009.09.21 PCA 2.2 Add \softraggedright to the thebibliography -% environment. Also add to template so it will -% happen with natbib. - -% 2009.09.30 PCA 2.3 Remove \softraggedright from thebibliography. -% Just include in the template. - -% 2010.05.24 PCA 2.4 Obfuscate author's email address. +\@latex@error{This sigplanconf.cls is a stub, please replace it.} From fd9b724abb6483c02339ac61092166d20bbeff38 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 14 Aug 2011 19:32:54 -0400 Subject: [PATCH 335/746] Remove this one too (should have been in the previous commit) --- collects/scribble/jfp/jfp.cls | 1095 +-------------------------------- 1 file changed, 2 insertions(+), 1093 deletions(-) diff --git a/collects/scribble/jfp/jfp.cls b/collects/scribble/jfp/jfp.cls index 916159314f..fe8310a0dc 100644 --- a/collects/scribble/jfp/jfp.cls +++ b/collects/scribble/jfp/jfp.cls @@ -1,1095 +1,4 @@ -%% -%% This is file `jfp.cls' -%% -%% CUP Journal of Functional Programming document class -%% Copyright 2001 Cambridge University Press -%% -%% by Mark A. Reed -%% based on JFP.STY v1.24. -%% -%% Incorporating parts of authordate.sty -%% by David Rhead, Cripps Computing Centre (Feb 1990). -%% -%% Bugs (in the case of unchanged files) should be reported to -%% texline@cambridge.org -%% -%% This software may only be used in the preparation of journal articles -%% or books or parts of books to be published by Cambridge University Press. -%% Any other use constitutes an infringement of copyright. -%% -%% \CharacterTable -%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z -%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z -%% Digits \0\1\2\3\4\5\6\7\8\9 -%% Exclamation \! Double quote \" Hash (number) \# -%% Dollar \$ Percent \% Ampersand \& -%% Acute accent \' Left paren \( Right paren \) -%% Asterisk \* Plus \+ Comma \, -%% Minus \- Point \. Solidus \/ -%% Colon \: Semicolon \; Less than \< -%% Equals \= Greater than \> Question mark \? -%% Commercial at \@ Left bracket \[ Backslash \\ -%% Right bracket \] Circumflex \^ Underscore \_ -%% Grave accent \` Left brace \{ Vertical bar \| -%% Right brace \} Tilde \~} -%% - \NeedsTeXFormat{LaTeX2e}[1997/12/01] -\ProvidesClass{jfp}[2001/09/27 v1.02 Journal of Functional Programming - ^^Jdocument class] +\ProvidesClass{jfp} -\newif\ifprodtf - -\DeclareOption{oneside}{\relax} -\DeclareOption{twoside}{\@twosidetrue \@mparswitchtrue} -\DeclareOption{draft}{\setlength\overfullrule{5\p@}} -\DeclareOption{final}{\setlength\overfullrule{\z@}} -\DeclareOption{onecolumn}{\@twocolumnfalse} -\DeclareOption{twocolumn}{\relax} -\DeclareOption{titlepage}{\relax} -\DeclareOption{notitlepage}{\relax} -\DeclareOption{leqno}{\relax} -\DeclareOption{fleqn}{\relax} -\DeclareOption{prodtf}{\prodtftrue} - -\ExecuteOptions{twoside,final,onecolumn} -\ProcessOptions\relax - -\newif\ifCUPmtlplainloaded -\ifprodtf - \CUPmtlplainloadedtrue - \RequirePackage{CUPTimes,jfp2esym} -\fi - -\setlength\lineskip{1\p@} -\setlength\normallineskip{1\p@} -\renewcommand\baselinestretch{} - -\renewcommand\normalsize{% - \@setfontsize\normalsize\@xpt{13}% - \abovedisplayskip 6.5\p@ \@plus 1\p@ \@minus 1\p@ - \belowdisplayskip \abovedisplayskip - \abovedisplayshortskip 3\p@ \@plus 1\p@ - \belowdisplayshortskip \abovedisplayshortskip - \let\@listi\@listI} - -\normalsize - -\newcommand\small{% - \@setfontsize\small\@ixpt{11}% - \abovedisplayskip 6\p@ \@plus 1\p@ \@minus 1\p@ - \belowdisplayskip \abovedisplayskip - \abovedisplayshortskip 3\p@ \@plus 1\p@ - \belowdisplayshortskip \abovedisplayshortskip - \def\@listi{\leftmargin\leftmargini - \topsep 6\p@ \@plus 1\p@ \@minus 1\p@ - \parsep \z@ \itemsep \parsep}% -} - -\newcommand\footnotesize{% - \@setfontsize\footnotesize\@viiipt\@ixpt - \abovedisplayskip 5\p@ \@plus 1\p@ \@minus 1\p@ - \belowdisplayskip \abovedisplayskip - \abovedisplayshortskip \z@ \@plus 1\p@ - \belowdisplayshortskip \abovedisplayshortskip - \def\@listi{\leftmargin\leftmargini - \topsep 4.5\p@ \@plus 1\p@ \@minus 1\p@ - \parsep \z@ \itemsep \parsep}% -} - -\newcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt} -\newcommand\tiny{\@setfontsize\tiny\@vpt\@vipt} -\newcommand\large{\@setfontsize\large\@xiipt{14}} -\newcommand\Large{\@setfontsize\Large\@xivpt{18}} -\ifprodtf - \newcommand\LARGE{\@setfontsize\LARGE{18}{21}}% -\else - \newcommand\LARGE{\@setfontsize\LARGE\@xviipt{21}}% -\fi -\newcommand\huge{\@setfontsize\huge\@xxpt{25}} -\newcommand\Huge{\@setfontsize\Huge\@xxvpt{30}} - -\newcommand\affilsize{\@setfontsize\affilsize\@viiipt\@xpt} -\let\authorsize\normalsize - -\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} -\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} -\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} -\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} -\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} -\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} -\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} -\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} -\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} - -\ifprodtf \else - \setlength\oddsidemargin{3.75pc} - \setlength\evensidemargin{3.75pc} - \setlength\topmargin{3.25pc} -\fi - -\setlength\marginparwidth{2.0cm} -\setlength\marginparsep{10\p@} - -\setlength\headheight{13\p@} -\setlength\headsep{11\p@} -\setlength\topskip{13\p@} -\setlength\footskip{26\p@} - -\setlength\textheight{44\baselineskip} -\addtolength\textheight{\topskip} -\setlength\textwidth{30pc} -\setlength\columnsep{10\p@} -\setlength\columnseprule{\z@} - -\setlength\footnotesep{\z@} -\setlength{\skip\footins}{19.5\p@ \@plus 12\p@ \@minus 1\p@} - -\setlength\floatsep{13\p@ \@plus 6.5\p@ \@minus 1\p@} -\setlength\textfloatsep{15\p@ \@plus 4.5\p@ \@minus 3\p@} -\setlength\intextsep{13\p@ \@plus 6.5\p@ \@minus 2\p@} -\setlength\dblfloatsep{13\p@ \@plus 6.5\p@ \@minus 2\p@} -\setlength\dbltextfloatsep{15\p@ \@plus 4.5\p@ \@minus 3\p@} -\setlength\@fptop{\z@ \@plus 0fil} -\setlength\@fpsep{13\p@ \@plus 0fil} -\setlength\@fpbot{\z@ \@plus 3fil} -\setlength\@dblfptop{\z@ \@plus 0fil} -\setlength\@dblfpsep{13\p@ \@plus 0fil} -\setlength\@dblfpbot{\z@ \@plus 3fil} -\setlength\marginparpush{5\p@} - -\setlength\parskip{\z@ \@plus .3\p@} -\setlength\parindent{1em} -\setlength\partopsep{\z@ \@plus 1\p@} -\@lowpenalty 51 -\@medpenalty 151 -\@highpenalty 301 -\@beginparpenalty -\@lowpenalty -\@endparpenalty -\@lowpenalty -\@itempenalty -\@lowpenalty -\clubpenalty\z@ -\widowpenalty\@M - -\newcommand\partname{Part} -\newcommand\part{\par\addvspace{4ex}\@afterindentfalse \secdef\@part\@spart} - -\def\@part[#1]#2{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{part}% - \addcontentsline{toc}{part}{\partname\ \thepart: #1}% - \else - \addcontentsline{toc}{part}{#1}% - \fi - {\parindent \z@ \centering - \ifnum \c@secnumdepth >\m@ne - \normalfont\large\rmfamily \MakeUppercase{\partname}\ % - \ifcase\thepart \or ONE \or TWO \or THREE \or FOUR \or FIVE - \or SIX \or SEVEN \or EIGHT \or NINE \or TEN \else \fi - \par \nobreak - \fi - \normalfont\LARGE\rmfamily #2 \markboth{}{}\par}% - \nobreak \vskip 3ex \@afterheading -} - -\def\@spart#1{% - {\parindent \z@ \centering\normalfont\LARGE\rmfamily #1\par}% - \nobreak \vskip 3ex \@afterheading -} - -\newcommand\section{% - \@startsection {section}{1}{\z@} - {-19.5\p@ \@plus -6.5\p@ \@minus -3.25\p@} - {6.5\p@ \@plus \z@ \@minus 1\p@} - {\normalfont\normalsize\bfseries\centering}% -} - -\newcommand\subsection{% - \@startsection{subsection}{2}{\z@} - {-19.5\p@ \@plus -3.25\p@ \@minus -3.25\p@} - {6.5\p@ \@plus \z@ \@minus 1\p@} - {\normalfont\normalsize\bfseries\itshape\centering}% -} - -\newcommand\subsubsection{% - \@startsection{subsubsection}{3}{\z@} - {-19.5\p@ \@plus -3.25\p@ \@minus -3.25\p@} - {6.5\p@ \@plus \z@ \@minus 1\p@} - {\normalfont\normalsize\itshape\centering}% -} - -\newcommand\paragraph{% - \@startsection{paragraph}{4}{\z@} - {-13\p@ \@plus -1.5\p@ \@minus -1.5\p@} - {-0.5em} - {\normalfont\normalsize\itshape\raggedright}% -} - -\newcommand\subparagraph{% - \@startsection{subparagraph}{4}{\parindent} - {-13\p@ \@plus -3.25\p@ \@minus -3.25\p@} - {-0.5em} - {\normalfont\normalsize\rmfamily\raggedright}% -} - -\def\@seccntformat#1{\csname the#1\endcsname\enskip}% FROM LATEX.LTX - -\newcommand\appendixname{Appendix} - -\newcommand\appendix{\par - \@addtoreset{equation}{section}% - \@addtoreset{figure}{section}% - \@addtoreset{table}{section}% - \setcounter{section}\z@ - \renewcommand\thesection{\@Alph\c@section}% - \renewcommand\theequation{\thesection\,\@arabic\c@equation}% - \renewcommand\thefigure{\thesection\,\@arabic\c@figure}% - \renewcommand\thetable{\thesection\,\@arabic\c@table}% -} - -\setcounter{secnumdepth}{3} - -\newcounter{part} -\newcounter{section} -\newcounter{subsection}[section] -\newcounter{subsubsection}[subsection] -\newcounter{paragraph}[subsubsection] -\newcounter{subparagraph}[paragraph] -\renewcommand\thepart {\@arabic\c@part} -\renewcommand\thesection {\@arabic\c@section} -\renewcommand\thesubsection {\thesection.\@arabic\c@subsection} -\renewcommand\thesubsubsection {\thesubsection.\@arabic\c@subsubsection} -\renewcommand\theparagraph {\thesubsubsection.\@arabic\c@paragraph} -\renewcommand\thesubparagraph {\theparagraph.\@arabic\c@subparagraph} - -\newskip\@leftskip \@leftskip=\z@ - -\setlength\leftmargini {2.5em} -\setlength\leftmarginii {1.5em} -\setlength\leftmarginiii {1.5em} -\setlength\leftmarginiv {1.5em} -\setlength\leftmarginv {1em} -\setlength\leftmarginvi {1em} -\setlength\leftmargin {\leftmargini} -\setlength\labelsep {5\p@} -\setlength\labelwidth {\leftmargini} -\addtolength\labelwidth {-\labelsep} - -\newcommand\makeRLlabel[1]{\rlap{#1}\hss} -\newcommand\makeRRlabel[1]{\hss\llap{#1}} - -\def\@listI{\leftmargin\leftmargini - \parsep \z@ \topsep 6.5\p@ \@plus 3\p@ \@minus 3\p@ - \itemsep \z@ \@plus 1\p@ \@minus 1\p@ - \let\makelabel\makeRLlabel} - -\def\@listii{\leftmargin\leftmarginii - \labelwidth\leftmarginii - \advance\labelwidth-\labelsep - \topsep 3\p@ \@plus 1\p@ \@minus 1\p@ - \parsep \z@ \itemsep \parsep - \let\makelabel\makeRLlabel} - -\def\@listiii{\leftmargin\leftmarginiii - \labelwidth\leftmarginiii - \advance\labelwidth-\labelsep - \topsep 3\p@ \@plus 1\p@ \@minus 1\p@ - \parsep \z@ \partopsep \z@ - \itemsep \topsep - \let\makelabel\makeRLlabel} - -\def\@listiv{\leftmargin\leftmarginiv - \labelwidth\leftmarginiv - \advance\labelwidth-\labelsep - \let\makelabel\makeRLlabel} - -\def\@listv{\leftmargin\leftmarginv - \labelwidth\leftmarginv - \advance\labelwidth-\labelsep - \let\makelabel\makeRLlabel} - -\def\@listvi{\leftmargin\leftmarginvi - \labelwidth\leftmarginvi - \advance\labelwidth-\labelsep - \let\makelabel\makeRLlabel} - -\let\@listi\@listI -\@listi - -\def\itemize{% FROM LATEX.LTX - \ifnum \@itemdepth >\thr@@ \@toodeep\else - \advance\@itemdepth \@ne - \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% - \expandafter - \list - \csname\@itemitem\endcsname - {\let\makelabel\makeRRlabel}% - \fi -} - -\newcommand\labelitemi{$\m@th\bullet$} -\newcommand\labelitemii{\normalfont\bfseries ---} -\newcommand\labelitemiii{\normalfont\bfseries --} -\newcommand\labelitemiv{$\m@th\cdot$} - -\def\enumerate{% FROM LATEX.LTX - \ifnum \@enumdepth >\thr@@ \@toodeep\else - \advance\@enumdepth \@ne - \edef\@enumctr{enum\romannumeral\the\@enumdepth}% - \fi - \@ifnextchar [{\@enumeratetwo}{\@enumerateone}% -} - -\def\@enumerateone{% - \expandafter - \list - \csname label\@enumctr\endcsname - {\usecounter{\@enumctr}% - \let\makelabel\makeRRlabel}% -} - -\def\@enumeratetwo[#1]{% - \expandafter - \list - \csname label\@enumctr\endcsname - {\usecounter{\@enumctr}% - \settowidth\labelwidth{\normalfont\rmfamily #1}% - \leftmargin\labelwidth \advance\leftmargin\labelsep - \let\makelabel\makeRRlabel}% -} - -\newcommand\labelenumi {{\normalfont\rmfamily\theenumi.}} -\newcommand\labelenumii {{\normalfont\rmfamily(\theenumii)}} -\newcommand\labelenumiii{{\normalfont\rmfamily\theenumiii}} -\newcommand\labelenumiv {{\normalfont\rmfamily\theenumiv}} - -\renewcommand\theenumi{\@arabic\c@enumi} -\renewcommand\theenumii{\@alph\c@enumii} -\renewcommand\theenumiii{\@roman\c@enumiii} -\renewcommand\theenumiv{\@Alph\c@enumiv} - -\renewcommand\p@enumii{\theenumi} -\renewcommand\p@enumiii{\theenumi(\theenumii)} -\renewcommand\p@enumiv{\p@enumiii\theenumiii} - -\newcommand*\descriptionlabel[1]{\hspace\labelsep \normalfont\bfseries #1} - -\newenvironment{description} - {\list{}{\leftmargin 1em \labelwidth\z@ \itemindent-\leftmargin - \let\makelabel\descriptionlabel}} - {\endlist} - -\newenvironment{verse} - {\let\\=\@centercr - \list{}{\itemsep\z@ - \itemindent -2.5em% - \listparindent \itemindent - \rightmargin\leftmargin - \advance\leftmargin 2.5em}\item[]} - {\endlist} - -\newenvironment{quotation} - {\list{}{\listparindent\parindent - \itemindent\listparindent - \leftmargin\z@ \rightmargin\leftmargin - \parsep \z@ \@plus 1\p@}\item[]% - \normalfont\small\rmfamily} - {\endlist} - -\let\quote\quotation -\let\endquote\endquotation - -\newif\ifrembrks -\newcommand\removebrackets{\rembrkstrue} - -\def\@begintheorem#1#2{% FROM LATEX.LTX - \normalfont\rmfamily - \trivlist - \item[\hskip \labelsep{\normalfont\itshape #1\ #2}]% - \item[]% -} - -\def\@opargbegintheorem#1#2#3{% FROM LATEX.LTX - \normalfont\rmfamily - \trivlist - \item[\hskip \labelsep{\normalfont\itshape #1\ #2\ % - \ifrembrks #3\/\global\rembrksfalse\else {\upshape(}#3\/{\upshape)}\fi}]% - \item[]% -} - -\newsavebox{\proofsavebox} - -\ifprodtf - \sbox{\proofsavebox}{$\CUPproofbox$} - \newcommand\proofbox{\hbox{$\CUPproofbox$}} -\else - \sbox{\proofsavebox} - {\unitlength 1pt\begin{picture}(6.5,6.5)% - \put(0,0){\framebox(6.5,6.5){}}\end{picture}} - \newcommand\proofbox{\usebox{\proofsavebox}\relax} -\fi - -\newcommand\mathproofbox{\rlap{\quad\proofbox}} - -\def\@nprf{\normalfont\rmfamily \trivlist - \item[\hskip \labelsep {\normalfont\itshape Proof}]% - \item[]} - -\def\@oprf[#1]{\normalfont\rmfamily \trivlist - \item[\hskip \labelsep {\normalfont\itshape #1\ }]% - \item[]} - -\newenvironment{proof} - {\@ifnextchar[{\@oprf}{\@nprf}} - {\hspace*{1em}\hbox{\proofbox}\endtrivlist} - -\newenvironment{proof*} - {\proof} - {\endtrivlist} - -\renewcommand\theequation{\@arabic\c@equation} - -\setlength\arraycolsep{5\p@} -\setlength\tabcolsep{3\p@} -\setlength\arrayrulewidth{.5\p@} -\setlength\doublerulesep{1.5\p@} -\setlength\tabbingsep{\labelsep} -\setlength{\skip\@mpfootins}{\skip\footins} -\setlength\fboxsep{3\p@} -\setlength\fboxrule{.5\p@} - -\newcommand\maketitle{\@ifnextchar [{\m@ketitleone}{\m@ketitleone[n]}} - -\def\m@ketitleone[#1]{\par - \begingroup - \newpage - \global\@topnum\z@ - \titlefntrue - \def\thefootnote{\@fnsymbol\c@footnote}% - \def\@makefnmark{\hbox{$\@thefnmark$}}% - \@maketitle{#1}% - \thispagestyle{titlepage}\@thanks - \endgroup - \global\let\@maketitle\relax - \global\let\@thanks\@empty - \global\let\@title\@empty - \global\let\@author\@empty - \global\let\maketitle\relax - \global\let\thanks\relax - \setcounter{footnote}\z@ -} - -\def\pe@rl#1{% - \if t#1 {\tpe@rl}\else - \if T#1 {\Tpe@rl}\else - \if f#1 {\fpe@rl}\else - \if F#1 {\Fpe@rl}\else - \if o#1 {\otherpearl}\else - \vspace*{32\p@}% - \fi - \fi - \fi - \fi - \fi -} - -\def\spe@rl{\vspace*{32\p@}\normalfont\LARGE\rmfamily} -\def\epe@rl#1{\par\vspace*{6.5\p@}\gdef\@shorttitle{#1}} - -\def\tpe@rl{\spe@rl T\ls H\ls E\ls O\ls R\ls E\ls T\ls - I\ls C\ls A\ls L\ns P\ls E\ls A\ls R\ls L\ls S% - \epe@rl{Theoretical pearls}% -} - -\def\Tpe@rl{\spe@rl T\ls H\ls E\ls O\ls R\ls E\ls T\ls - I\ls C\ls A\ls L\ns P\ls E\ls A\ls R\ls L% - \epe@rl{Theoretical pearl}% -} - -\def\fpe@rl{\spe@rl F\ls U\ls N\ls C\ls T\ls I\ls O\ls - N\ls A\ls L\ns P\ls E\ls A\ls R\ls L\ls S% - \epe@rl{Functional pearls}% -} - -\def\Fpe@rl{\spe@rl F\ls U\ls N\ls C\ls T\ls I\ls O\ls - N\ls A\ls L\ns P\ls E\ls A\ls R\ls L% - \epe@rl{Functional pearl}% -} - -\def\otherpearl{\spe@rl - \@ifundefined{othrpearl} - {Please define {\normalfont\ttfamily\char92 othrpearl} to obtain\\ the correct title!} - {\othrpearl}% - \epe@rl{Short title--please redefine with {\normalfont\ttfamily\char92 shorttitle}}% -} - -\def\b@at{\begin{author@tabular}[t]{@{}c@{}}} - -\renewcommand\and{and } -\newcommand\@nd{\end{author@tabular}\vskip 6\p@\par\b@at} - -\let\authorbreak\relax -\newcommand\auth@rbreak{\end{author@tabular}\\[0pt]\b@at} - -\def\@maketitle#1{% - \newpage - \vspace*{-15\p@}% - {\centering \sloppy - \pe@rl{#1}% - {\normalfont\LARGE\itshape \@title\par}% - \vskip 16\p@ - {\normalfont\normalsize\rmfamily - \let\authorbreak\auth@rbreak - \let\and\@nd - \b@at - \@author - \end{author@tabular}% - \par}% - }% - \vskip 18\p@ \@plus 2\p@ \@minus 1\p@ -} - -\def\abs@header#1{% - \vbox{\hrule \@width\hsize - \vskip 8\p@ \@plus 3\p@ \@minus 1\p@ - \centerline{\normalfont\normalsize\bfseries #1}}% -} - -\def\abs@body{% - \list{}{\leftmargin\z@ \rightmargin\leftmargin - \listparindent 1em \parsep \z@ \@plus 1\p@ - \topsep 6.5\p@ \@plus 3\p@ \@minus 1\p@}% - \item[]\normalfont\small\rmfamily -} - -\newcommand\abstractname{Abstract} -\newenvironment{abstract} - {\abs@header{\abstractname}\abs@body} - {\endlist\vbox{\hrule \@width \hsize}% - \gdef\abs@header##1{\vskip 2\p@ - \centerline{\normalfont\normalsize\bfseries ##1}}} - -\newcommand\capsulename{Capsule Review} -\newenvironment{capsule} - {\abs@header{\capsulename}\abs@body} - {\endabstract} - -\def\author@tabular{\normalfont\authorsize\rmfamily - \def\@halignto{}\@authortable} -\let\endauthor@tabular\endtabular - -\def\author@tabcrone{{\ifnum0=`}\fi\@xtabularcr\normalfont\affilsize\itshape - \let\\\author@tabcrtwo\ignorespaces} - -\def\author@tabcrtwo{{\ifnum0=`}\fi\@xtabularcr[-3\p@]\normalfont\affilsize\itshape - \let\\\author@tabcrtwo\ignorespaces} - -\def\@authortable{\leavevmode \hbox \bgroup $\let\@acol\@tabacol - \let\@classz\@tabclassz \let\@classiv\@tabclassiv - \let\\\author@tabcrone \ignorespaces \@tabarray} - -\mark{{}{}} -\renewcommand\author{\@ifnextchar [{\@authortwo}{\@authorone}} -\def\@authorone#1{\gdef\@author{#1}\gdef\@shortauthor{#1}} -\def\@authortwo[#1]#2{\gdef\@author{#2}\gdef\@shortauthor{#1}} -\gdef\@author{\mbox{}} - -\newcommand\shortauthor[1]{\gdef\@shortauthor{#1}} -\gdef\@shortauthor{} - -\renewcommand\title{\@ifnextchar [{\@titletwo}{\@titleone}} -\def\@titleone#1{\gdef\@title{#1}\gdef\@shorttitle{#1}} -\def\@titletwo[#1]#2{\gdef\@title{#2}\gdef\@shorttitle{#1}} -\gdef\@title{\mbox{}} - -\newcommand\shorttitle[1]{\gdef\@shorttitle{#1}} -\gdef\@shorttitle{} - -\newcommand\volume[1]{\gdef\@volume{#1}} -\gdef\@volume{{\normalfont\bfseries 1} (1):} - -\newcommand\pagerange[1]{\gdef\@pagerange{#1}} -\gdef\@pagerange{1--000} - -\newcommand\pubyear[1]{\gdef\@year{#1}} -\gdef\@year{19XX} - -\newcommand\jdate[1]{\gdef\@jdate{#1}} -\gdef\@jdate{January \@year} - -\newcommand\doi[1]{\gdef\@doi{10.1017/#1}} -\gdef\@doi{10.1017/S0000000000000000} - -\newcommand\journal[1]{\gdef\@journal{#1}} -\def\@journal{% - \vbox to 5.6\p@{\noindent\parbox[t]{4.8in}{\normalfont\affilsize\rmfamily - {\itshape JFP\/}\ \@volume\ \@pagerange, \@jdate.\quad \copyright\ - \@year\ Cambridge University Press\\[2.5\p@] - DOI: \@doi\quad {Printed in the United Kingdom}}% - \vss}% -} - -\def\@underjournal{% - \vbox to 5.6\p@{\noindent\parbox[t]{4.8in}{\normalfont\affilsize\rmfamily - {\itshape Under consideration for publication in - J.\ Functional Programming\/}\\[2.5\p@] - \ }% - \vss}% -} - -\def\ps@headings{\let\@mkboth\markboth - \def\@oddhead{\hfil{\itshape\@shorttitle}\hfil \llap{\thepage}}% - \def\@evenhead{\rlap{\thepage}\hfil\itshape\@shortauthor\hfil}% - \let\@oddfoot\@empty - \let\@evenfoot\@oddfoot - \def\sectionmark##1{\markboth{##1}{}}% - \def\subsectionmark##1{\markright{##1}}% -} - -\def\ps@myheadings{\let\@mkboth\@gobbletwo - \def\@oddhead{\hfil{\itshape\rightmark}\hfil \llap{\thepage}}% - \def\@evenhead{\rlap{\thepage}\hfil\itshape\leftmark\hfil}% - \let\@oddfoot\@empty - \let\@evenfoot\@oddfoot - \let\sectionmark\@gobble - \let\subsectionmark\@gobble -} - -\ifprodtf - \let\@j@urnal\@journal -\else - \let\@j@urnal\@underjournal -\fi - -\def\ps@titlepage{\leftskip\z@ \let\@mkboth\@gobbletwo - \def\@oddhead{\@j@urnal \hfil\llap{\thepage}}% - \let\@evenhead\@oddhead - \let\@oddfoot\@empty - \let\@evenfoot\@oddfoot - \let\sectionmark\@gobble - \let\subsectionmark\@gobble -} - -\def\@pnumwidth{1.55em} -\def\@tocrmarg {2.55em} -\def\@dotsep{4.5} -\setcounter{tocdepth}{2} - -\def\@dottedtocline#1#2#3#4#5{% FROM LATEX.LTX - \ifnum #1>\c@tocdepth \else - \vskip \z@ \@plus.2\p@ - {\leftskip #2\relax \rightskip \@tocrmarg \parfillskip -\rightskip - \parindent #2\relax\@afterindenttrue - \interlinepenalty\@M - \leavevmode - \@tempdima #3\relax - \advance\leftskip \@tempdima \null\hskip -\leftskip - {#4}\nobreak - \leaders\hbox{$\m@th - \mkern \@dotsep mu\hbox{\phantom{.}}\mkern \@dotsep - mu$}\hfill - \nobreak - \hb@xt@\@pnumwidth{\hfil\normalfont \normalcolor #5}% - \par}% - \fi} - -\newcommand\contentsname{Contents} - -\newcommand\tableofcontents{% - \section*{\contentsname}% - \@starttoc{toc}\par - \vspace{13\p@}% -} - -\newcommand*\l@part[2]{% - \ifnum \c@tocdepth >-2\relax - \addpenalty{-\@highpenalty}% - \addvspace{.5\baselineskip \@plus 1\p@}% - \begingroup - \parindent \z@ \rightskip \@pnumwidth - \parfillskip -\@pnumwidth - {\leavevmode - \normalfont\rmfamily - #1\hfil \hb@xt@\@pnumwidth{\hfil}}\par - \nobreak - \if@compatibility - \global\@nobreaktrue - \everypar{\global\@nobreakfalse\everypar{}}% - \fi - \endgroup - \vskip .25\baselineskip \@plus 1\p@ - \fi -} - -\newcommand*\l@section[2]{% - \ifnum \c@tocdepth >\z@ - \addpenalty\@secpenalty - \setlength\@tempdima{1.5em}% - \begingroup - \parindent \z@ \rightskip \@pnumwidth - \parfillskip -\@pnumwidth - \leavevmode \normalfont\rmfamily - \advance\leftskip\@tempdima - \hskip -\leftskip - {\bfseries #1}\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par - \endgroup - \fi} - -\newcommand*\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} -\newcommand*\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} -\newcommand*\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}} -\newcommand*\l@subparagraph{\@dottedtocline{5}{10em}{5em}} - -\newcommand\listfigurename{List of Figures} -\newcommand\listoffigures{% - \section*{\listfigurename}% - \@starttoc{lof}\par - \vskip 13\p@ -} - -\newcommand*\l@figure{\@dottedtocline{1}{1.5em}{2.3em}} - -\newcommand\listtablename{List of Tables} -\newcommand\listoftables{% - \section*{\listtablename}% - \@starttoc{lot}\par - \vskip 13\p@ -} - -\let\l@table\l@figure - -\renewcommand\footnoterule{% - \kern-3\p@ - \hrule \@width .4\columnwidth height \z@ - \kern 3\p@} - -\newif\iftitlefn -\newcommand\@makefntext[1]{% - \@setpar{\@@par\@tempdima \hsize - \advance\@tempdima-1em - \parshape \@ne 1em \@tempdima}\par - \noindent \hb@xt@ \z@{\hss$\iftitlefn\else^\fi{\@thefnmark}$\ }#1} - -\ifprodtf \else \let\highast\ast\fi - -\def\@fnsymbol#1{\ensuremath{% FROM LATEX.LTX - \ifcase#1\or \hbox{$\highast$}\or \dagger\or \ddagger\or - \mathchar "278\or \mathchar "27B\or \|\or \hbox{$\highast\highast$}\or - \dagger\dagger\or \ddagger\ddagger\or \mathchar "278\mathchar "278\or - \mathchar "27B\mathchar "27B\or \|\|\or \else\@ctrerr\fi}% -} - -\renewcommand\@makefnmark{\hbox{$^{\@thefnmark}$}}% FROM LATEX.LTX -\renewcommand\thefootnote{\@arabic\c@footnote}% FROM LATEX.LTX -\renewcommand\thempfootnote{\mathit{\@alph\c@mpfootnote}}% FROM LATEX.LTX - -\setcounter{topnumber}{2} -\renewcommand\topfraction{.9} -\setcounter{bottomnumber}{1} -\renewcommand\bottomfraction{.9} -\setcounter{totalnumber}{3} -\renewcommand\textfraction{.1} -\renewcommand\floatpagefraction{.9} -\setcounter{dbltopnumber}{2} -\renewcommand\dbltopfraction{.9} -\renewcommand\dblfloatpagefraction{.5} - -\newcounter{table} -\renewcommand\thetable{\@arabic\c@table} -\def\fps@table{tbp} -\def\ftype@table{1} -\def\ext@table{lot} -\newcommand\tablename{Table} -\def\fnum@table{\tablename~\thetable} - -\newenvironment{table} - {\@float{table}} - {\end@float} - -\newenvironment{table*} - {\@dblfloat{table}} - {\end@dblfloat} - -\def\fstyle@table{\normalfont\small\rmfamily} -\def\fjust@table{\centering} -\def\fcapjust@table{\centering} -\def\fcapsize@table{\normalfont\normalsize\rmfamily} -\def\fcapstyle@table{\normalfont\normalsize\itshape} - -\newcommand\contname{(cont.)} -\newcommand\continuedfigure{% - \addtocounter{figure}\m@ne - \let\curr@thefigure\thefigure - \def\thefigure{\curr@thefigure\ \contname}% -} - -\newcommand\continuedtable{% - \addtocounter{table}\m@ne - \let\curr@thetable\thetable - \def\thetable{\curr@thetable\ \contname}% -} - -\newif\ifrem@fullpt -\newcommand\removefullpoint{\global\rem@fullpttrue} - -\newif\ifbot@fig -\newenvironment{bottomfigure}{\def\fps@figure{b}% - \setcounter{bottomnumber}{1}% - \global\bot@figtrue - \@float{figure}\fstyle@figure} - {\end@float} - -\newbox\@tempboxb - -\long\def\@makecaption#1#2{% - \ifbot@fig \rule{\textwidth}{.25\p@}\fi - \vskip 6.5\p@ \@plus .4\p@ \@minus .4\p@ - \begingroup - \setbox\@tempboxb\hbox{#2}% - \def\@xtra{\ifdim\wd\@tempboxb>\z@ \ifrem@fullpt\else .\enskip\fi\fi}% - \setbox\@tempboxa\hbox{#1\@xtra #2}% - \ifdim\wd\@tempboxa>\tw@\textwidth - {\let\centering\relax #1\@xtra #2\par}% - \else - #1\@xtra #2\par - \fi - \endgroup - \global\bot@figfalse - \global\rem@fullptfalse -} - -\newcounter{figure} -\renewcommand\thefigure{\@arabic\c@figure} -\def\fps@figure{tbp} -\def\ftype@figure{2} -\def\ext@figure{lof} -\newcommand\figurename{Fig.} -\def\fnum@figure{\figurename~\thefigure} - -\newenvironment{figure} - {\@float{figure}} - {\end@float} - -\newenvironment{figure*} - {\@dblfloat{figure}} - {\end@dblfloat} - -\def\fstyle@figure{\normalfont\small\rmfamily} -\def\fjust@figure{\centering} -\def\fcapjust@figure{\centering} -\def\fcapsize@figure{\normalfont\small\rmfamily} -\def\fcapstyle@figure{\normalfont\small\rmfamily} - -\long\def\@caption#1[#2]#3{% FROM LATEX.LTX - \par - \addcontentsline{\csname ext@#1\endcsname}{#1}% - {\protect\numberline{\csname the#1\endcsname}{\ignorespaces #2}}% - \begingroup - \@parboxrestore - \if@minipage - \@setminipage - \fi - \normalsize - \@makecaption{\csname fcapjust@#1\endcsname - \csname fcapsize@#1\endcsname - \csname fnum@#1\endcsname}% - {\csname fcapstyle@#1\endcsname \ignorespaces #3}\par - \endgroup -} - -\def\@xfloat #1[#2]{% FROM LATEX.LTX - \@nodocument - \def\@captype {#1}% - \def\@fps {#2}% - \@onelevel@sanitize \@fps - \def \reserved@b {!}% - \ifx \reserved@b \@fps - \@fpsadddefault - \else - \ifx \@fps \@empty - \@fpsadddefault - \fi - \fi - \ifhmode - \@bsphack - \@floatpenalty-\@Mii - \else - \@floatpenalty-\@Miii - \fi - \ifinner - \@parmoderr\@floatpenalty\z@ - \else - \@next\@currbox\@freelist - {% - \@tempcnta \sixt@@n - \expandafter \@tfor \expandafter \reserved@a - \expandafter :\expandafter =\@fps - \do - {% - \if \reserved@a h% - \ifodd \@tempcnta - \else - \advance \@tempcnta \@ne - \fi - \fi - \if \reserved@a t% - \@setfpsbit \tw@ - \fi - \if \reserved@a b% - \@setfpsbit 4% - \fi - \if \reserved@a p% - \@setfpsbit 8% - \fi - \if \reserved@a !% - \ifnum \@tempcnta>15 - \advance\@tempcnta -\sixt@@n\relax - \fi - \fi - }% - \@tempcntb \csname ftype@\@captype \endcsname - \multiply \@tempcntb \@xxxii - \advance \@tempcnta \@tempcntb - \global \count\@currbox \@tempcnta - }% - \@fltovf - \fi - \global \setbox\@currbox - \color@vbox - \normalcolor - \vbox \bgroup - \hsize\columnwidth - \@parboxrestore - \@floatboxreset - \csname fstyle@\@captype\endcsname - \csname fjust@\@captype\endcsname -} - -\let\oldtabular\tabular -\let\endoldtabular\endtabular - -\def\tabular{% FROM LATEX.LTX - \def\@halignto{to \textwidth}\tabskip\tabcolsep \@plus 1fil\@ttabular -} - -\def\@ttabular{\leavevmode \hbox \bgroup $\let\@acol\@tabacol - \let\@classz\@tabclassz - \let\@classiv\@tabclassiv \let\\\@tabularcr\@ttabarray} - -\def\@ttabarray{\m@th\@ifnextchar[\@tarray{\@ttarray}} - -\def\@tarray[#1]#2{\t@barray[#1]{@{\tabskip\tw@\tabcolsep \@plus 3\p@}#2}} -\def\@ttarray#1{\t@barray[c]{@{\tabskip\tw@\tabcolsep \@plus 3\p@}#1}} - -\def\t@barray[#1]#2{% - \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi - \bgroup - \setbox\@arstrutbox\hbox{% - \vrule \@height\arraystretch\ht\strutbox - \@depth\arraystretch \dp\strutbox - \@width\z@}% - \@mkpream{#2}% - \edef\@preamble{% - \halign \noexpand\@halignto - \bgroup \tabskip\z@skip \@arstrut \@preamble \tabskip\tabcolsep \@plus 1fil\cr}% - \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox - \let\tabularnewline\\% - \let\par\@empty - \let\@sharp##% - \set@typeset@protect - \lineskip\z@skip\baselineskip\z@skip - \@preamble} - -\newcommand\ls{\kern.15em\relax} -\newcommand\ns{\kern.55em\relax} - -\def\hline{% FROM LATEX.LTX - \noalign{\ifnum0=`}\fi \vskip 6\p@ - \hrule \@height \arrayrulewidth \vskip 6\p@ - \futurelet \reserved@a\@xhline} - -\def\@xhline{% FROM LATEX.LTX - \ifx\reserved@a\hline - \vskip -12\p@ - \vskip\doublerulesep - \fi - \ifnum0=`{\fi}} - -\newcommand\today{} -\edef\today{\number\day\ \ifcase\month\or - January\or February\or March\or April\or May\or June\or - July\or August\or September\or October\or November\or December - \fi \ \number\year} - -\renewcommand\@biblabel[1]{}% FROM LATEX.LTX -\newcommand\newblock{\hskip .11em \@plus .33em \@minus .07em} - -\newcommand\refname{References} -\newenvironment{thebibliography}[1] - {\section*{\refname}% - \normalfont\small\rmfamily - \addcontentsline{toc}{section}{\refname}% - \list{}{\labelwidth\z@ \leftmargin 1em \itemindent -1em}% - \parindent\z@ - \parskip 2\p@ \@plus .1\p@ - \sloppy\clubpenalty\z@ \widowpenalty\@M - \sfcode`\.\@m\relax} - {\def\@noitemerr - {\@latex@warning{Empty `thebibliography' environment}}% - \endlist} - -\def\@citex[#1]#2{% FROM LATEX.LTX - \let\@citea\@empty - \@cite{\@for\@citeb:=#2\do - {\@citea\def\@citea{; }% - \edef\@citeb{\expandafter\@firstofone\@citeb}% - \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi - \@ifundefined{b@\@citeb}{\mbox{\reset@font\bfseries ?}% - \G@refundefinedtrue - \@latex@warning - {Citation `\@citeb' on page \thepage \space undefined}}% - {\csname b@\@citeb\endcsname}}}{#1}} - -\def\@cite#1#2{{\if@tempswa #2\else (#1)\fi}}% FROM LATEX.LTX - -\let\@internalcite\cite -\def\cite{\def\citename##1{##1}\@internalcite} -\DeclareRobustCommand\shortcite{\def\citename##1{}\@internalcite} - -\newif\iffontfound -\newcommand\checkfont[1]{% - \batchmode - \font\test=#1\relax - \errorstopmode - \fontfoundfalse - \ifx\test\nullfont \else \fontfoundtrue\fi -} - -\newcommand\email[1]{{\normalfont\rmfamily - \itshape\textup{(}e-mail: \textup{\texttt{#1})}}} - -\edef\r@{\ifprodtf mtr\else cmr\fi} - -\let\real@font@warning\@font@warning -\DeclareMathVersion{program} -\let\@font@warning\@gobble -\SetSymbolFont{letters}{program}{OT1}{\r@}{m}{sl} -\let\@font@warning\real@font@warning -\SetMathAlphabet{\mathnormal}{program}{OT1}{\r@}{m}{sl} - -\newcommand{\programmath}{\mathversion{program}} -\newcommand{\unprogrammath}{\mathversion{normal}} -\newcommand{\figrule}{\begin{center}\hrule\end{center}} - -\DeclareRobustCommand\dplus{\mathbin{+\!\!+}} -\DeclareRobustCommand\dequals{\mathbin{==}} -\DeclareRobustCommand\dcolon{\mathbin{::}} -\DeclareRobustCommand\dcolonequals{\mathbin{::=}} - -\pagestyle{headings} -\pagenumbering{arabic} -\frenchspacing -\flushbottom - -\endinput - -% end of file jfp.cls +\@latex@error{This jfp.cls is a stub, please replace it.} From 76809b92fb7f26c7102dc31522e65a96666f1c76 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 16 Aug 2011 03:41:22 -0400 Subject: [PATCH 336/746] v5.1.3 stuff (Cherry picked from ae80150) --- collects/meta/web/download/installers.txt | 296 ++++++++++++---------- 1 file changed, 162 insertions(+), 134 deletions(-) diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index 44fbbf3aae..be8d1c7853 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -1,134 +1,162 @@ -8.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-debian.sh -8.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-f12.sh -8.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-ubuntu-jaunty.sh -9.2M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-osx-mac.dmg -6.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-win32.exe -8.9M 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-darwin.sh -9.2M 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-osx-mac.dmg -9.0M 5.0.1/racket-textual/racket-textual-5.0.1-bin-x86_64-linux-f7.sh -5.6M 5.0.1/racket-textual/racket-textual-5.0.1-src-mac.dmg -5.5M 5.0.1/racket-textual/racket-textual-5.0.1-src-unix.tgz -6.8M 5.0.1/racket-textual/racket-textual-5.0.1-src-win.zip -47M 5.0.1/racket/racket-5.0.1-bin-i386-linux-debian.sh -47M 5.0.1/racket/racket-5.0.1-bin-i386-linux-f12.sh -47M 5.0.1/racket/racket-5.0.1-bin-i386-linux-ubuntu-jaunty.sh -48M 5.0.1/racket/racket-5.0.1-bin-i386-osx-mac.dmg -29M 5.0.1/racket/racket-5.0.1-bin-i386-win32.exe -46M 5.0.1/racket/racket-5.0.1-bin-ppc-darwin.sh -48M 5.0.1/racket/racket-5.0.1-bin-ppc-osx-mac.dmg -47M 5.0.1/racket/racket-5.0.1-bin-x86_64-linux-f7.sh -17M 5.0.1/racket/racket-5.0.1-src-mac.dmg -17M 5.0.1/racket/racket-5.0.1-src-unix.tgz -20M 5.0.1/racket/racket-5.0.1-src-win.zip -9.4M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-debian.sh -9.4M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-f12.sh -9.4M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-ubuntu-jaunty.sh -9.6M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-osx-mac.dmg -7.2M 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-win32.exe -9.3M 5.0.2/racket-textual/racket-textual-5.0.2-bin-ppc-darwin.sh -9.6M 5.0.2/racket-textual/racket-textual-5.0.2-bin-ppc-osx-mac.dmg -9.5M 5.0.2/racket-textual/racket-textual-5.0.2-bin-x86_64-linux-f7.sh -5.7M 5.0.2/racket-textual/racket-textual-5.0.2-src-mac.dmg -5.6M 5.0.2/racket-textual/racket-textual-5.0.2-src-unix.tgz -7.0M 5.0.2/racket-textual/racket-textual-5.0.2-src-win.zip -48M 5.0.2/racket/racket-5.0.2-bin-i386-linux-debian.sh -48M 5.0.2/racket/racket-5.0.2-bin-i386-linux-f12.sh -48M 5.0.2/racket/racket-5.0.2-bin-i386-linux-ubuntu-jaunty.sh -50M 5.0.2/racket/racket-5.0.2-bin-i386-osx-mac.dmg -30M 5.0.2/racket/racket-5.0.2-bin-i386-win32.exe -48M 5.0.2/racket/racket-5.0.2-bin-ppc-darwin.sh -50M 5.0.2/racket/racket-5.0.2-bin-ppc-osx-mac.dmg -49M 5.0.2/racket/racket-5.0.2-bin-x86_64-linux-f7.sh -17M 5.0.2/racket/racket-5.0.2-src-mac.dmg -17M 5.0.2/racket/racket-5.0.2-src-unix.tgz -21M 5.0.2/racket/racket-5.0.2-src-win.zip -8.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-debian.sh -8.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-f12.sh -8.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-ubuntu-jaunty.sh -8.9M 5.0/racket-textual/racket-textual-5.0-bin-i386-osx-mac.dmg -6.7M 5.0/racket-textual/racket-textual-5.0-bin-i386-win32.exe -8.6M 5.0/racket-textual/racket-textual-5.0-bin-ppc-darwin.sh -8.9M 5.0/racket-textual/racket-textual-5.0-bin-ppc-osx-mac.dmg -8.8M 5.0/racket-textual/racket-textual-5.0-bin-x86_64-linux-f7.sh -5.3M 5.0/racket-textual/racket-textual-5.0-src-mac.dmg -5.2M 5.0/racket-textual/racket-textual-5.0-src-unix.tgz -6.8M 5.0/racket-textual/racket-textual-5.0-src-win.zip -45M 5.0/racket/racket-5.0-bin-i386-linux-debian.sh -45M 5.0/racket/racket-5.0-bin-i386-linux-f12.sh -45M 5.0/racket/racket-5.0-bin-i386-linux-ubuntu-jaunty.sh -46M 5.0/racket/racket-5.0-bin-i386-osx-mac.dmg -28M 5.0/racket/racket-5.0-bin-i386-win32.exe -45M 5.0/racket/racket-5.0-bin-ppc-darwin.sh -46M 5.0/racket/racket-5.0-bin-ppc-osx-mac.dmg -45M 5.0/racket/racket-5.0-bin-x86_64-linux-f7.sh -16M 5.0/racket/racket-5.0-src-mac.dmg -16M 5.0/racket/racket-5.0-src-unix.tgz -20M 5.0/racket/racket-5.0-src-win.zip -11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-linux-f12.sh -11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-linux-ubuntu-jaunty.sh -11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-osx-mac.dmg -7.6M 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-win32.exe -11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-ppc-darwin.sh -11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-ppc-osx-mac.dmg -11M 5.1.1/racket-textual/racket-textual-5.1.1-bin-x86_64-linux-f14.sh -5.9M 5.1.1/racket-textual/racket-textual-5.1.1-src-mac.dmg -5.7M 5.1.1/racket-textual/racket-textual-5.1.1-src-unix.tgz -6.8M 5.1.1/racket-textual/racket-textual-5.1.1-src-win.zip -50M 5.1.1/racket/racket-5.1.1-bin-i386-linux-f12.sh -50M 5.1.1/racket/racket-5.1.1-bin-i386-linux-ubuntu-jaunty.sh -51M 5.1.1/racket/racket-5.1.1-bin-i386-osx-mac.dmg -32M 5.1.1/racket/racket-5.1.1-bin-i386-win32.exe -49M 5.1.1/racket/racket-5.1.1-bin-ppc-darwin.sh -52M 5.1.1/racket/racket-5.1.1-bin-ppc-osx-mac.dmg -50M 5.1.1/racket/racket-5.1.1-bin-x86_64-linux-f14.sh -16M 5.1.1/racket/racket-5.1.1-src-mac.dmg -16M 5.1.1/racket/racket-5.1.1-src-unix.tgz -19M 5.1.1/racket/racket-5.1.1-src-win.zip -9.9M 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-linux-f12.sh -9.9M 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-linux-ubuntu-jaunty.sh -11M 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-osx-mac.dmg -7.4M 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-win32.exe -9.8M 5.1.2/racket-textual/racket-textual-5.1.2-bin-ppc-darwin.sh -11M 5.1.2/racket-textual/racket-textual-5.1.2-bin-ppc-osx-mac.dmg -10M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-debian-lenny.sh -10M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-debian-squeeze.sh -10M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-f14.sh -11M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-osx-mac.dmg -7.7M 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-win32.exe -5.7M 5.1.2/racket-textual/racket-textual-5.1.2-src-mac.dmg -5.6M 5.1.2/racket-textual/racket-textual-5.1.2-src-unix.tgz -6.6M 5.1.2/racket-textual/racket-textual-5.1.2-src-win.zip -48M 5.1.2/racket/racket-5.1.2-bin-i386-linux-f12.sh -48M 5.1.2/racket/racket-5.1.2-bin-i386-linux-ubuntu-jaunty.sh -50M 5.1.2/racket/racket-5.1.2-bin-i386-osx-mac.dmg -32M 5.1.2/racket/racket-5.1.2-bin-i386-win32.exe -48M 5.1.2/racket/racket-5.1.2-bin-ppc-darwin.sh -51M 5.1.2/racket/racket-5.1.2-bin-ppc-osx-mac.dmg -49M 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-debian-lenny.sh -49M 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-debian-squeeze.sh -49M 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-f14.sh -50M 5.1.2/racket/racket-5.1.2-bin-x86_64-osx-mac.dmg -32M 5.1.2/racket/racket-5.1.2-bin-x86_64-win32.exe -16M 5.1.2/racket/racket-5.1.2-src-mac.dmg -16M 5.1.2/racket/racket-5.1.2-src-unix.tgz -19M 5.1.2/racket/racket-5.1.2-src-win.zip -11M 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-f12.sh -11M 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-ubuntu-jaunty.sh -11M 5.1/racket-textual/racket-textual-5.1-bin-i386-osx-mac.dmg -7.6M 5.1/racket-textual/racket-textual-5.1-bin-i386-win32.exe -11M 5.1/racket-textual/racket-textual-5.1-bin-ppc-darwin.sh -11M 5.1/racket-textual/racket-textual-5.1-bin-ppc-osx-mac.dmg -11M 5.1/racket-textual/racket-textual-5.1-bin-x86_64-linux-f14.sh -5.8M 5.1/racket-textual/racket-textual-5.1-src-mac.dmg -5.7M 5.1/racket-textual/racket-textual-5.1-src-unix.tgz -5.8M 5.1/racket-textual/racket-textual-5.1-src-win.zip -50M 5.1/racket/racket-5.1-bin-i386-linux-f12.sh -50M 5.1/racket/racket-5.1-bin-i386-linux-ubuntu-jaunty.sh -51M 5.1/racket/racket-5.1-bin-i386-osx-mac.dmg -32M 5.1/racket/racket-5.1-bin-i386-win32.exe -49M 5.1/racket/racket-5.1-bin-ppc-darwin.sh -52M 5.1/racket/racket-5.1-bin-ppc-osx-mac.dmg -50M 5.1/racket/racket-5.1-bin-x86_64-linux-f14.sh -16M 5.1/racket/racket-5.1-src-mac.dmg -16M 5.1/racket/racket-5.1-src-unix.tgz -18M 5.1/racket/racket-5.1-src-win.zip +9300697 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-debian.sh +9304219 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-f12.sh +9313351 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-linux-ubuntu-jaunty.sh +9598271 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-osx-mac.dmg +7195260 5.0.1/racket-textual/racket-textual-5.0.1-bin-i386-win32.exe +9275500 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-darwin.sh +9590434 5.0.1/racket-textual/racket-textual-5.0.1-bin-ppc-osx-mac.dmg +9428494 5.0.1/racket-textual/racket-textual-5.0.1-bin-x86_64-linux-f7.sh +5832011 5.0.1/racket-textual/racket-textual-5.0.1-src-mac.dmg +5714125 5.0.1/racket-textual/racket-textual-5.0.1-src-unix.tgz +7115859 5.0.1/racket-textual/racket-textual-5.0.1-src-win.zip +48280952 5.0.1/racket/racket-5.0.1-bin-i386-linux-debian.sh +48274719 5.0.1/racket/racket-5.0.1-bin-i386-linux-f12.sh +48321280 5.0.1/racket/racket-5.0.1-bin-i386-linux-ubuntu-jaunty.sh +49529404 5.0.1/racket/racket-5.0.1-bin-i386-osx-mac.dmg +29974852 5.0.1/racket/racket-5.0.1-bin-i386-win32.exe +48227579 5.0.1/racket/racket-5.0.1-bin-ppc-darwin.sh +49553958 5.0.1/racket/racket-5.0.1-bin-ppc-osx-mac.dmg +48582065 5.0.1/racket/racket-5.0.1-bin-x86_64-linux-f7.sh +17343846 5.0.1/racket/racket-5.0.1-src-mac.dmg +17272590 5.0.1/racket/racket-5.0.1-src-unix.tgz +20625477 5.0.1/racket/racket-5.0.1-src-win.zip +9753004 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-debian.sh +9759330 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-f12.sh +9769701 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-linux-ubuntu-jaunty.sh +10061865 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-osx-mac.dmg +7483846 5.0.2/racket-textual/racket-textual-5.0.2-bin-i386-win32.exe +9723983 5.0.2/racket-textual/racket-textual-5.0.2-bin-ppc-darwin.sh +10054183 5.0.2/racket-textual/racket-textual-5.0.2-bin-ppc-osx-mac.dmg +9889541 5.0.2/racket-textual/racket-textual-5.0.2-bin-x86_64-linux-f7.sh +5939776 5.0.2/racket-textual/racket-textual-5.0.2-src-mac.dmg +5815219 5.0.2/racket-textual/racket-textual-5.0.2-src-unix.tgz +7283576 5.0.2/racket-textual/racket-textual-5.0.2-src-win.zip +50263773 5.0.2/racket/racket-5.0.2-bin-i386-linux-debian.sh +50264748 5.0.2/racket/racket-5.0.2-bin-i386-linux-f12.sh +50304157 5.0.2/racket/racket-5.0.2-bin-i386-linux-ubuntu-jaunty.sh +51514800 5.0.2/racket/racket-5.0.2-bin-i386-osx-mac.dmg +31130193 5.0.2/racket/racket-5.0.2-bin-i386-win32.exe +50204906 5.0.2/racket/racket-5.0.2-bin-ppc-darwin.sh +51567239 5.0.2/racket/racket-5.0.2-bin-ppc-osx-mac.dmg +50579715 5.0.2/racket/racket-5.0.2-bin-x86_64-linux-f7.sh +17699549 5.0.2/racket/racket-5.0.2-src-mac.dmg +17622692 5.0.2/racket/racket-5.0.2-src-unix.tgz +21092427 5.0.2/racket/racket-5.0.2-src-win.zip +9015818 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-debian.sh +9025266 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-f12.sh +9039169 5.0/racket-textual/racket-textual-5.0-bin-i386-linux-ubuntu-jaunty.sh +9324539 5.0/racket-textual/racket-textual-5.0-bin-i386-osx-mac.dmg +7023498 5.0/racket-textual/racket-textual-5.0-bin-i386-win32.exe +8999839 5.0/racket-textual/racket-textual-5.0-bin-ppc-darwin.sh +9330306 5.0/racket-textual/racket-textual-5.0-bin-ppc-osx-mac.dmg +9159233 5.0/racket-textual/racket-textual-5.0-bin-x86_64-linux-f7.sh +5539138 5.0/racket-textual/racket-textual-5.0-src-mac.dmg +5408767 5.0/racket-textual/racket-textual-5.0-src-unix.tgz +7041524 5.0/racket-textual/racket-textual-5.0-src-win.zip +46469932 5.0/racket/racket-5.0-bin-i386-linux-debian.sh +46483844 5.0/racket/racket-5.0-bin-i386-linux-f12.sh +46515740 5.0/racket/racket-5.0-bin-i386-linux-ubuntu-jaunty.sh +47637362 5.0/racket/racket-5.0-bin-i386-osx-mac.dmg +28973247 5.0/racket/racket-5.0-bin-i386-win32.exe +46418573 5.0/racket/racket-5.0-bin-ppc-darwin.sh +47693225 5.0/racket/racket-5.0-bin-ppc-osx-mac.dmg +46784914 5.0/racket/racket-5.0-bin-x86_64-linux-f7.sh +16727955 5.0/racket/racket-5.0-src-mac.dmg +16661627 5.0/racket/racket-5.0-src-unix.tgz +20043612 5.0/racket/racket-5.0-src-win.zip +10608594 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-linux-f12.sh +10617031 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-linux-ubuntu-jaunty.sh +10944378 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-osx-mac.dmg +7871781 5.1.1/racket-textual/racket-textual-5.1.1-bin-i386-win32.exe +10563612 5.1.1/racket-textual/racket-textual-5.1.1-bin-ppc-darwin.sh +10925675 5.1.1/racket-textual/racket-textual-5.1.1-bin-ppc-osx-mac.dmg +10777466 5.1.1/racket-textual/racket-textual-5.1.1-bin-x86_64-linux-f14.sh +6088017 5.1.1/racket-textual/racket-textual-5.1.1-src-mac.dmg +5972450 5.1.1/racket-textual/racket-textual-5.1.1-src-unix.tgz +7072928 5.1.1/racket-textual/racket-textual-5.1.1-src-win.zip +51562160 5.1.1/racket/racket-5.1.1-bin-i386-linux-f12.sh +51583365 5.1.1/racket/racket-5.1.1-bin-i386-linux-ubuntu-jaunty.sh +53227597 5.1.1/racket/racket-5.1.1-bin-i386-osx-mac.dmg +33299725 5.1.1/racket/racket-5.1.1-bin-i386-win32.exe +51319041 5.1.1/racket/racket-5.1.1-bin-ppc-darwin.sh +54275107 5.1.1/racket/racket-5.1.1-bin-ppc-osx-mac.dmg +51928808 5.1.1/racket/racket-5.1.1-bin-x86_64-linux-f14.sh +16221515 5.1.1/racket/racket-5.1.1-src-mac.dmg +15884853 5.1.1/racket/racket-5.1.1-src-unix.tgz +19117693 5.1.1/racket/racket-5.1.1-src-win.zip +10294418 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-linux-f12.sh +10305056 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-linux-ubuntu-jaunty.sh +10649433 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-osx-mac.dmg +7735142 5.1.2/racket-textual/racket-textual-5.1.2-bin-i386-win32.exe +10229144 5.1.2/racket-textual/racket-textual-5.1.2-bin-ppc-darwin.sh +10600014 5.1.2/racket-textual/racket-textual-5.1.2-bin-ppc-osx-mac.dmg +10465204 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-debian-lenny.sh +10476031 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-debian-squeeze.sh +10474930 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-linux-f14.sh +10849704 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-osx-mac.dmg +8035589 5.1.2/racket-textual/racket-textual-5.1.2-bin-x86_64-win32.exe +5927007 5.1.2/racket-textual/racket-textual-5.1.2-src-mac.dmg +5814309 5.1.2/racket-textual/racket-textual-5.1.2-src-unix.tgz +6858089 5.1.2/racket-textual/racket-textual-5.1.2-src-win.zip +50068153 5.1.2/racket/racket-5.1.2-bin-i386-linux-f12.sh +50101512 5.1.2/racket/racket-5.1.2-bin-i386-linux-ubuntu-jaunty.sh +51665644 5.1.2/racket/racket-5.1.2-bin-i386-osx-mac.dmg +32577645 5.1.2/racket/racket-5.1.2-bin-i386-win32.exe +49784628 5.1.2/racket/racket-5.1.2-bin-ppc-darwin.sh +52725371 5.1.2/racket/racket-5.1.2-bin-ppc-osx-mac.dmg +50416939 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-debian-lenny.sh +50437726 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-debian-squeeze.sh +50446330 5.1.2/racket/racket-5.1.2-bin-x86_64-linux-f14.sh +51976069 5.1.2/racket/racket-5.1.2-bin-x86_64-osx-mac.dmg +33226602 5.1.2/racket/racket-5.1.2-bin-x86_64-win32.exe +16293184 5.1.2/racket/racket-5.1.2-src-mac.dmg +15960181 5.1.2/racket/racket-5.1.2-src-unix.tgz +19203148 5.1.2/racket/racket-5.1.2-src-win.zip +10277328 5.1.3/racket-textual/racket-textual-5.1.3-bin-i386-linux-f12.sh +10286517 5.1.3/racket-textual/racket-textual-5.1.3-bin-i386-linux-ubuntu-jaunty.sh +10646200 5.1.3/racket-textual/racket-textual-5.1.3-bin-i386-osx-mac.dmg +7721338 5.1.3/racket-textual/racket-textual-5.1.3-bin-i386-win32.exe +10209882 5.1.3/racket-textual/racket-textual-5.1.3-bin-ppc-darwin.sh +10578888 5.1.3/racket-textual/racket-textual-5.1.3-bin-ppc-osx-mac.dmg +10445665 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-linux-debian-lenny.sh +10458130 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-linux-debian-squeeze.sh +10458009 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-linux-f14.sh +10844242 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-osx-mac.dmg +8024578 5.1.3/racket-textual/racket-textual-5.1.3-bin-x86_64-win32.exe +5909369 5.1.3/racket-textual/racket-textual-5.1.3-src-mac.dmg +5795883 5.1.3/racket-textual/racket-textual-5.1.3-src-unix.tgz +6840314 5.1.3/racket-textual/racket-textual-5.1.3-src-win.zip +50047413 5.1.3/racket/racket-5.1.3-bin-i386-linux-f12.sh +50082199 5.1.3/racket/racket-5.1.3-bin-i386-linux-ubuntu-jaunty.sh +51638634 5.1.3/racket/racket-5.1.3-bin-i386-osx-mac.dmg +32548344 5.1.3/racket/racket-5.1.3-bin-i386-win32.exe +49765546 5.1.3/racket/racket-5.1.3-bin-ppc-darwin.sh +52694190 5.1.3/racket/racket-5.1.3-bin-ppc-osx-mac.dmg +50391225 5.1.3/racket/racket-5.1.3-bin-x86_64-linux-debian-lenny.sh +50405579 5.1.3/racket/racket-5.1.3-bin-x86_64-linux-debian-squeeze.sh +50431407 5.1.3/racket/racket-5.1.3-bin-x86_64-linux-f14.sh +51949468 5.1.3/racket/racket-5.1.3-bin-x86_64-osx-mac.dmg +33194397 5.1.3/racket/racket-5.1.3-bin-x86_64-win32.exe +16270003 5.1.3/racket/racket-5.1.3-src-mac.dmg +15939654 5.1.3/racket/racket-5.1.3-src-unix.tgz +19185643 5.1.3/racket/racket-5.1.3-src-win.zip +10661589 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-f12.sh +10674322 5.1/racket-textual/racket-textual-5.1-bin-i386-linux-ubuntu-jaunty.sh +11019666 5.1/racket-textual/racket-textual-5.1-bin-i386-osx-mac.dmg +7899916 5.1/racket-textual/racket-textual-5.1-bin-i386-win32.exe +10627504 5.1/racket-textual/racket-textual-5.1-bin-ppc-darwin.sh +11009730 5.1/racket-textual/racket-textual-5.1-bin-ppc-osx-mac.dmg +10835079 5.1/racket-textual/racket-textual-5.1-bin-x86_64-linux-f14.sh +6064958 5.1/racket-textual/racket-textual-5.1-src-mac.dmg +5945844 5.1/racket-textual/racket-textual-5.1-src-unix.tgz +6071742 5.1/racket-textual/racket-textual-5.1-src-win.zip +51529968 5.1/racket/racket-5.1-bin-i386-linux-f12.sh +51560486 5.1/racket/racket-5.1-bin-i386-linux-ubuntu-jaunty.sh +53300468 5.1/racket/racket-5.1-bin-i386-osx-mac.dmg +33200268 5.1/racket/racket-5.1-bin-i386-win32.exe +51306060 5.1/racket/racket-5.1-bin-ppc-darwin.sh +54367850 5.1/racket/racket-5.1-bin-ppc-osx-mac.dmg +51892721 5.1/racket/racket-5.1-bin-x86_64-linux-f14.sh +16095941 5.1/racket/racket-5.1-src-mac.dmg +15759982 5.1/racket/racket-5.1-src-unix.tgz +17987080 5.1/racket/racket-5.1-src-win.zip From 1012b8a37b3a645d08b41d64f69f397101995e3f Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 7 Oct 2011 22:09:53 -0600 Subject: [PATCH 337/746] Alpha version number for the v5.2 release --- src/racket/src/schvers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 29428f27d5..10ff176ecb 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.1.3.12" +#define MZSCHEME_VERSION "5.1.90" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 1 -#define MZSCHEME_VERSION_Z 3 -#define MZSCHEME_VERSION_W 12 +#define MZSCHEME_VERSION_Z 90 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From c056791190501ff7d2f07f3582a5d11349613773 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 8 Oct 2011 00:32:23 -0400 Subject: [PATCH 338/746] New Racket version 5.1.90. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index aa1f327b41..d15ace1e25 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index e64320e802..ae692839f7 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,3,12 - PRODUCTVERSION 5,1,3,12 + FILEVERSION 5,1,90,0 + PRODUCTVERSION 5,1,90,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 1, 3, 12\0" + VALUE "FileVersion", "5, 1, 90, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 3, 12\0" + VALUE "ProductVersion", "5, 1, 90, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 7bf9a4469a..25e833e816 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,3,12 - PRODUCTVERSION 5,1,3,12 + FILEVERSION 5,1,90,0 + PRODUCTVERSION 5,1,90,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 1, 3, 12" + VALUE "FileVersion", "5, 1, 90, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 1, 3, 12" + VALUE "ProductVersion", "5, 1, 90, 0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index f8cee1c81f..cfd5cff31e 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.1.3.12 = s 'MzObj Class' + MzCOM.MzObj.5.1.90.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.1.3.12' + CurVer = s 'MzCOM.MzObj.5.1.90.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.1.3.12' + ProgID = s 'MzCOM.MzObj.5.1.90.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index d625ba26cb..debfb6c8ab 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index de63e9e121..c9d8703ebf 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,3,12 - PRODUCTVERSION 5,1,3,12 + FILEVERSION 5,1,90,0 + PRODUCTVERSION 5,1,90,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 1, 3, 12\0" + VALUE "FileVersion", "5, 1, 90, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 3, 12\0" + VALUE "ProductVersion", "5, 1, 90, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 6acde57ee1..da58548d78 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,3,12 - PRODUCTVERSION 5,1,3,12 + FILEVERSION 5,1,90,0 + PRODUCTVERSION 5,1,90,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 1, 3, 12\0" + VALUE "FileVersion", "5, 1, 90, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 3, 12\0" + VALUE "ProductVersion", "5, 1, 90, 0\0" END END BLOCK "VarFileInfo" From 82b0237cd1bba10548b5c1855fedbd4971527062 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 8 Oct 2011 04:29:53 -0400 Subject: [PATCH 339/746] Fix version number --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 10ff176ecb..4110525107 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,11 +13,11 @@ consistently.) */ -#define MZSCHEME_VERSION "5.1.90" +#define MZSCHEME_VERSION "5.1.900" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 1 -#define MZSCHEME_VERSION_Z 90 +#define MZSCHEME_VERSION_Z 900 #define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) From 3fefe33c2ce908cf1dc4fb7b17ea332d402ea258 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 8 Oct 2011 03:02:20 -0400 Subject: [PATCH 340/746] Typo in error message detection (cherry picked from commit 7d1b00ff697eda9309f29195fb65723320a86ebd) --- collects/meta/web/download/mirror-link.rkt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/meta/web/download/mirror-link.rkt b/collects/meta/web/download/mirror-link.rkt index b5a8e5cfb3..245240e647 100644 --- a/collects/meta/web/download/mirror-link.rkt +++ b/collects/meta/web/download/mirror-link.rkt @@ -147,10 +147,10 @@ Polling a URL can result in one of four options: (define r (with-handlers ([exn:fail? exn-message]) (call/input-url (string->url url) head-impure-port check-contents))) - (if (boolean? r) - r + (if (string? r) (begin (eprintf "WARNING: failure getting http info for ~a (~a)\n" url r) - #f))) + #f) + r)) (define (verify-ftp url) (define-values [host port? path] From a4ad7349990cb170c4a83377f350a4f455ab07c0 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 8 Oct 2011 04:35:55 -0400 Subject: [PATCH 341/746] New Racket version 5.1.900. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index d15ace1e25..c239f9586a 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index ae692839f7..74e0007f73 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,90,0 - PRODUCTVERSION 5,1,90,0 + FILEVERSION 5,1,900,0 + PRODUCTVERSION 5,1,900,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 1, 90, 0\0" + VALUE "FileVersion", "5, 1, 900, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 90, 0\0" + VALUE "ProductVersion", "5, 1, 900, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 25e833e816..b8c2e370c4 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,90,0 - PRODUCTVERSION 5,1,90,0 + FILEVERSION 5,1,900,0 + PRODUCTVERSION 5,1,900,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 1, 90, 0" + VALUE "FileVersion", "5, 1, 900, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 1, 90, 0" + VALUE "ProductVersion", "5, 1, 900, 0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index cfd5cff31e..2aba2e1ecb 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.1.90.0 = s 'MzObj Class' + MzCOM.MzObj.5.1.900.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.1.90.0' + CurVer = s 'MzCOM.MzObj.5.1.900.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.1.90.0' + ProgID = s 'MzCOM.MzObj.5.1.900.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index debfb6c8ab..578c3d3385 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index c9d8703ebf..a793e85717 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,90,0 - PRODUCTVERSION 5,1,90,0 + FILEVERSION 5,1,900,0 + PRODUCTVERSION 5,1,900,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 1, 90, 0\0" + VALUE "FileVersion", "5, 1, 900, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 90, 0\0" + VALUE "ProductVersion", "5, 1, 900, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index da58548d78..5aec589925 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,90,0 - PRODUCTVERSION 5,1,90,0 + FILEVERSION 5,1,900,0 + PRODUCTVERSION 5,1,900,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 1, 90, 0\0" + VALUE "FileVersion", "5, 1, 900, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 90, 0\0" + VALUE "ProductVersion", "5, 1, 900, 0\0" END END BLOCK "VarFileInfo" From c414f057f76c8ba7de2f5caa75595ccc776c07e3 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 8 Oct 2011 05:16:46 -0400 Subject: [PATCH 342/746] Re-fix version number --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 4110525107..288eb5b9a2 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.1.900" +#define MZSCHEME_VERSION "5.1.900.1" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 1 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 0 +#define MZSCHEME_VERSION_W 1 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From d91cb717327fe41f759a4faece7b4b6f12a2b2e9 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 8 Oct 2011 05:17:24 -0400 Subject: [PATCH 343/746] New Racket version 5.1.900.1. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index c239f9586a..03c5ce0eaa 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 74e0007f73..6236d8fc68 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,900,0 - PRODUCTVERSION 5,1,900,0 + FILEVERSION 5,1,900,1 + PRODUCTVERSION 5,1,900,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 1, 900, 0\0" + VALUE "FileVersion", "5, 1, 900, 1\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 900, 0\0" + VALUE "ProductVersion", "5, 1, 900, 1\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index b8c2e370c4..531fdf55db 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,900,0 - PRODUCTVERSION 5,1,900,0 + FILEVERSION 5,1,900,1 + PRODUCTVERSION 5,1,900,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 1, 900, 0" + VALUE "FileVersion", "5, 1, 900, 1" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 1, 900, 0" + VALUE "ProductVersion", "5, 1, 900, 1" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index 2aba2e1ecb..c9eb625c8c 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.1.900.0 = s 'MzObj Class' + MzCOM.MzObj.5.1.900.1 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.1.900.0' + CurVer = s 'MzCOM.MzObj.5.1.900.1' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.1.900.0' + ProgID = s 'MzCOM.MzObj.5.1.900.1' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 578c3d3385..f9180cc43b 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index a793e85717..75b9dfe52f 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,900,0 - PRODUCTVERSION 5,1,900,0 + FILEVERSION 5,1,900,1 + PRODUCTVERSION 5,1,900,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 1, 900, 0\0" + VALUE "FileVersion", "5, 1, 900, 1\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 900, 0\0" + VALUE "ProductVersion", "5, 1, 900, 1\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 5aec589925..9c7e5f6182 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,900,0 - PRODUCTVERSION 5,1,900,0 + FILEVERSION 5,1,900,1 + PRODUCTVERSION 5,1,900,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 1, 900, 0\0" + VALUE "FileVersion", "5, 1, 900, 1\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 900, 0\0" + VALUE "ProductVersion", "5, 1, 900, 1\0" END END BLOCK "VarFileInfo" From 239ce3eec043ba86a1ae808dee37065d9592af74 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 8 Oct 2011 06:09:14 -0600 Subject: [PATCH 344/746] another attempt to fix the 64-bit Lion hidden-window problem This fix uses the same`run'-vs-`finishLaunch' technique as before, but patches up the modal-dialog problem by calling `run' again with a callback to start a modal loop. Merge to 5.2. (cherry picked from commit f6e5468dbb85c2ed48178ac43fb25084430413ef) --- collects/mred/private/wx/cocoa/filedialog.rkt | 18 +++++---- collects/mred/private/wx/cocoa/printer-dc.rkt | 9 +++-- collects/mred/private/wx/cocoa/queue.rkt | 40 +++++++++++++++++-- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/collects/mred/private/wx/cocoa/filedialog.rkt b/collects/mred/private/wx/cocoa/filedialog.rkt index 904acd7fbe..2afb278171 100644 --- a/collects/mred/private/wx/cocoa/filedialog.rkt +++ b/collects/mred/private/wx/cocoa/filedialog.rkt @@ -91,14 +91,16 @@ (let ([front (get-front)] [parent (and (version-10.6-or-later?) parent)]) - (when parent - (tellv ns beginSheetModalForWindow: (send parent get-cocoa-window) - completionHandler: #f)) - (begin0 - (tell #:type _NSInteger ns runModal) - (when parent (tell app endSheet: ns)) - (when front (tellv (send front get-cocoa-window) - makeKeyAndOrderFront: #f)))))]) + (call-in-run-loop + (lambda () + (when parent + (tellv ns beginSheetModalForWindow: (send parent get-cocoa-window) + completionHandler: #f)) + (begin0 + (tell #:type _NSInteger ns runModal) + (when parent (tell app endSheet: ns)) + (when front (tellv (send front get-cocoa-window) + makeKeyAndOrderFront: #f)))))))]) (begin0 (if (zero? result) #f diff --git a/collects/mred/private/wx/cocoa/printer-dc.rkt b/collects/mred/private/wx/cocoa/printer-dc.rkt index 2df653c5cc..10879424c5 100644 --- a/collects/mred/private/wx/cocoa/printer-dc.rkt +++ b/collects/mred/private/wx/cocoa/printer-dc.rkt @@ -16,7 +16,8 @@ "bitmap.rkt" "cg.rkt" "utils.rkt" - "types.rkt") + "types.rkt" + "queue.rkt") (provide (protect-out printer-dc% @@ -105,8 +106,10 @@ (if (atomically (let ([front (get-front)]) (begin0 - (= (tell #:type _NSInteger (tell NSPageLayout pageLayout) runModalWithPrintInfo: print-info) - NSOkButton) + (call-in-run-loop + (lambda () + (= (tell #:type _NSInteger (tell NSPageLayout pageLayout) runModalWithPrintInfo: print-info) + NSOkButton))) (when front (tellv (send front get-cocoa-window) makeKeyAndOrderFront: #f))))) (begin diff --git a/collects/mred/private/wx/cocoa/queue.rkt b/collects/mred/private/wx/cocoa/queue.rkt index d0ac5d21a3..e455b988af 100644 --- a/collects/mred/private/wx/cocoa/queue.rkt +++ b/collects/mred/private/wx/cocoa/queue.rkt @@ -21,6 +21,7 @@ set-menu-bar-hooks! set-fixup-window-locations! post-dummy-event + call-in-run-loop try-to-sync-refresh sync-cocoa-events) @@ -30,7 +31,8 @@ queue-event yield) -(import-class NSApplication NSAutoreleasePool NSColor NSProcessInfo NSArray) +(import-class NSApplication NSAutoreleasePool NSColor NSProcessInfo NSArray + NSRunLoop) (import-protocol NSApplicationDelegate) ;; Extreme hackery to hide original arguments from @@ -78,7 +80,11 @@ (queue-file-event (string->path filename))] [-a _void (applicationDidFinishLaunching: [_id notification]) (unless got-file? - (queue-start-empty-event))] + (queue-start-empty-event)) + (tellv app stop: self)] + [-a _void (callbackAndStopLoop) + (run-loop-callback) + (tellv app stop: self)] [-a _BOOL (applicationShouldHandleReopen: [_id app] hasVisibleWindows: [_BOOL has-visible?]) ;; If we have any visible windows, return #t to do the default thing. ;; Otherwise return #f, because we don't want any invisible windows resurrected. @@ -132,7 +138,34 @@ (unless (zero? v) (log-error (format "error from CGDisplayRegisterReconfigurationCallback: ~a" v)))) -(tellv app finishLaunching) +;; To make sure that `finishLaunching' is called, call `run' +;; and have `applicationDidFinishLaunching' quit the run loop. +;; This seems to work better than calling `finishLaunching' +;; directly undet 64-bt Lion, where calling just `finishLaunching' +;; somehow doesn't get the start-up AppleEvents. +(tellv app run) + +;; Use `call-in-run-loop' to run something that needs to be +;; within `run', such as a modal-dialog run loop. It starts +;; a `run' with a high-priority callback to run `thunk', and +;; the run loop is stopped immediately after `thunk' returns. +(define (call-in-run-loop thunk) + (define result #f) + (set! run-loop-callback + (lambda () + (set! run-loop-callback void) + (set! result (thunk)))) + (tellv (tell NSRunLoop currentRunLoop) + performSelector: #:type _SEL (selector callbackAndStopLoop) + target: app-delegate + argument: #f + order: #:type _NSUInteger 0 + modes: (tell NSArray + arrayWithObjects: #:type (_vector i _id) (vector NSDefaultRunLoopMode) + count: #:type _NSUInteger 1)) + (tellv app run) + result) +(define run-loop-callback void) ;; ------------------------------------------------------------ ;; Create an event to post when MzScheme has been sleeping but is @@ -221,7 +254,6 @@ (define kCFSocketReadCallBack 1) -(import-class NSRunLoop) (let* ([rl (tell #:type _CFRunLoopRef (tell NSRunLoop currentRunLoop) getCFRunLoop)] [cfs (CFSocketCreateWithNative (CFAllocatorGetDefault) ready_sock kCFSocketReadCallBack socket_callback sock-context)] From 1d6f193f3178e910f1b563153edc039520020f16 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 8 Oct 2011 06:56:14 -0600 Subject: [PATCH 345/746] windows: add sqlite3.dll Merge to 5.2 (cherry picked from commit 41b18e3608912c68cf9056dc9872937634e15e30) --- collects/meta/build/build | 3 ++- src/get-libs.rkt | 8 +++++++- src/worksp/build.bat | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index 5727a29d19..39400647f1 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -1427,8 +1427,9 @@ DO_WINDOWS_BUILD() { win_build_step VSNET "mrstart" _cd "$PLTHOME/lib" - win_build_step RKT "get-libs (gui)" ../src/get-libs.rkt core + win_build_step RKT "get-libs (core)" ../src/get-libs.rkt core win_build_step RKT "get-libs (gui)" ../src/get-libs.rkt gui + win_build_step RKT "get-libs (db)" ../src/get-libs.rkt db separator "Windows: Building libraries" _cd "$PLTHOME" diff --git a/src/get-libs.rkt b/src/get-libs.rkt index a59042cee6..37db6e9c1f 100644 --- a/src/get-libs.rkt +++ b/src/get-libs.rkt @@ -111,7 +111,13 @@ ["libpangocairo-1.0-0.dll" 185168] ["libpangowin32-1.0-0.dll" 192656] ["libpangoft2-1.0-0.dll" 1188615] - ["libfit.dll" 69120]]])) + ["libfit.dll" 69120]]] + ;; Databse libraries + [db + [win32/i386 + ["sqlite3.dll" 570947]] + [win32/x86_64 + ["sqlite3.dll" 617472]]])) (define-values [package dest-dir] (command-line #:args [package [dest-dir (current-directory)]] diff --git a/src/worksp/build.bat b/src/worksp/build.bat index 054933225b..0c7be9b7c6 100644 --- a/src/worksp/build.bat +++ b/src/worksp/build.bat @@ -21,6 +21,8 @@ cd .. if errorlevel 1 exit /B 1 ..\..\racket -cu ..\get-libs.rkt gui ..\..\lib if errorlevel 1 exit /B 1 +..\..\racket -cu ..\get-libs.rkt db ..\..\lib +if errorlevel 1 exit /B 1 cd mzstart devenv mzstart.sln /Build "Release|%BUILDMODE%" From 941f18a562c33c4402e79e9c868ae607a1db5632 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 8 Oct 2011 08:51:02 -0500 Subject: [PATCH 346/746] adjust the way languages are chosen when opening a file. Specifically, in the case that we're inheriting a language setting from some earlier preference or something and the language we're inheriting is one that saves prefixes, and the current file being opened does not match any of the possible prefixes, then revert to the not-a-language language, instead of using the value from the preference Also: finish the removal of the EoPL language level from the DrRacket langauge dialog, and clean up the 'get guidance' dialog Please cherrypick this commit to the 5.2 release branch (cherry picked from commit d362bda6d3dbc404d33e46d939369b1c213e5141) --- .../private/language-configuration.rkt | 61 ++++++++++--------- collects/drracket/private/unit.rkt | 18 ++++-- collects/eopl/info.rkt | 5 -- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/collects/drracket/private/language-configuration.rkt b/collects/drracket/private/language-configuration.rkt index 67a6a00177..468fddb43a 100644 --- a/collects/drracket/private/language-configuration.rkt +++ b/collects/drracket/private/language-configuration.rkt @@ -560,7 +560,10 @@ (= (length positions) (length numbers)) ((length numbers) . >= . 1)) (error 'drracket:language - "languages position and numbers must be lists of strings and numbers, respectively, must have the same length, and must each contain at least one element, got: ~e ~e" + (string-append + "languages position and numbers must be lists of strings and numbers," + " respectively, must have the same length, and must each contain at" + " least one element, got: ~e ~e") positions numbers)) (when (null? (cdr positions)) @@ -1825,26 +1828,14 @@ [else (string<=? (cadr x) (cadr y))]))))) - (define plt-logo-shiny - (make-object bitmap% (collection-file-path "plt-logo-red-shiny.png" "icons") - 'png/mask)) - (define (display-racketeer) (new canvas-message% (parent racketeer-panel) (label (string-constant racketeer?))) - (new canvas% + (new canvas-message% + [label (read-bitmap (collection-file-path "plt-logo-red-shiny.png" "icons"))] [parent racketeer-panel] - [stretchable-width #f] - [paint-callback - (λ (c dc) - (send dc set-scale 1/2 1/2) - (send dc draw-bitmap plt-logo-shiny 0 0 - 'solid (send the-color-database find-color "black") - (send plt-logo-shiny get-loaded-mask)))] - [style '(transparent)] - [min-width (floor (/ (send plt-logo-shiny get-width) 2))] - [min-height (floor (/ (send plt-logo-shiny get-height) 2))]) + [callback (λ () (change-current-lang-to (λ (x) (is-a? x drracket:module-language:module-language<%>))))]) (new canvas-message% (parent racketeer-panel) (label (string-constant use-language-in-source)) @@ -1907,23 +1898,32 @@ (super on-event evt)])) (define/override (on-paint) - (let* ([dc (get-dc)] - [old-font (send dc get-font)] - [old-tf (send dc get-text-foreground)]) - (send dc set-text-foreground color) - (send dc set-font font) - (send dc draw-text label 0 0 #t) - (send dc set-font old-font) - (send dc set-text-foreground old-tf))) + (define dc (get-dc)) + (cond + [(string? label) + (define old-font (send dc get-font)) + (define old-tf (send dc get-text-foreground)) + (send dc set-text-foreground color) + (send dc set-font font) + (send dc draw-text label 0 0 #t) + (send dc set-font old-font) + (send dc set-text-foreground old-tf)] + [(is-a? label bitmap%) + (send dc draw-bitmap label 0 0)])) (super-new [stretchable-width #f] [stretchable-height #f] [style '(transparent)]) (inherit min-width min-height get-dc) - (let-values ([(w h _1 _2) (send (get-dc) get-text-extent label font #t)]) - (min-width (inexact->exact (floor w))) - (min-height (inexact->exact (floor h)))))) + (cond + [(string? label) + (define-values (w h _1 _2) (send (get-dc) get-text-extent label font #t)) + (min-width (inexact->exact (ceiling w))) + (min-height (inexact->exact (ceiling h)))] + [(is-a? label bitmap%) + (min-width (inexact->exact (ceiling (send label get-width)))) + (min-height (inexact->exact (ceiling (send label get-height))))]))) (define (question/answer line1 line2 icon-lst) (display-two-line-choice @@ -1947,7 +1947,7 @@ (define (get-text-pls info-filename) (let ([proc (get-info/full info-filename)]) (if proc - (let ([qs (proc 'textbook-pls)]) + (let ([qs (proc 'textbook-pls (λ () '()))]) (unless (list? qs) (error 'splash-questions "expected a list, got ~e" qs)) (for-each @@ -1963,7 +1963,10 @@ (andmap string? (cdr pr))) (error 'splash-questions - "expected a list of lists, with each inner list being at least three elements long and the first element of the inner list being a list of strings and the rest of the elements being strings, got ~e" + (string-append + "expected a list of lists, with each inner list being at least three elements long" + " and the first element of the inner list being a list of strings and the rest of" + " the elements being strings, got ~e") pr))) qs) qs) diff --git a/collects/drracket/private/unit.rkt b/collects/drracket/private/unit.rkt index 77eecc548e..0cce7e97c9 100644 --- a/collects/drracket/private/unit.rkt +++ b/collects/drracket/private/unit.rkt @@ -609,12 +609,18 @@ module browser threading seems wrong. (drracket:language-configuration:get-languages) module-language module-language-settings)]) - (when matching-language - (set-next-settings - (drracket:language-configuration:language-settings - matching-language - settings) - #f)))) + (cond + [matching-language + (set-next-settings + (drracket:language-configuration:language-settings + matching-language + settings) + #f)] + [else + (when (send (drracket:language-configuration:language-settings-language (get-next-settings)) get-reader-module) + (set-next-settings + (drracket:language-configuration:get-default-language-settings) + #f))]))) (set-modified #f)) (end-edit-sequence) diff --git a/collects/eopl/info.rkt b/collects/eopl/info.rkt index 0857a54814..957181140a 100644 --- a/collects/eopl/info.rkt +++ b/collects/eopl/info.rkt @@ -4,8 +4,3 @@ (define scribblings '(("eopl.scrbl" () (teaching -20)))) -(define textbook-pls - (list (list '("eopl-small.png" "eopl") - "Essentials of Programming Languages" - (string-constant teaching-languages) - "Essentials of Programming Languages (3rd ed.)"))) From 52e1e8458d2a6fea5a533c60fc2bc8382c43d2e1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 8 Oct 2011 08:37:09 -0600 Subject: [PATCH 347/746] fix text% `get-paragraph-{start,end}-position' bug and doc bugs Merge to 5.2 (cherry picked from commit 379991c5bbd170085d1abfb7d766efa4f63e7a3c) --- collects/mred/private/wxme/text.rkt | 40 ++++++++++--------- .../scribblings/gui/editor-overview.scrbl | 10 ++--- collects/scribblings/gui/snip-class.scrbl | 4 +- collects/scribblings/gui/text-class.scrbl | 37 ++++++++--------- collects/tests/gracket/wxme.rkt | 16 ++++++++ 5 files changed, 63 insertions(+), 44 deletions(-) diff --git a/collects/mred/private/wxme/text.rkt b/collects/mred/private/wxme/text.rkt index bf1cb2c866..b2fc7ceba7 100644 --- a/collects/mred/private/wxme/text.rkt +++ b/collects/mred/private/wxme/text.rkt @@ -3343,25 +3343,27 @@ [any? [visible-only? #t]]) (if (not (check-recalc #f #f #t)) 0 - (let* ([i (max 0 i)] - [l (mline-find-paragraph (unbox line-root-box) i)] - [l (if l - (let loop ([l l]) - (if (and (mline-next l) - (zero? (mline-starts-paragraph (mline-next l)))) - (loop (mline-next l)) - l)) - (if extra-line? - len - last-line))]) - (if (mline? l) - (let ([p (+ (mline-get-position l) (mline-len l))]) - (if visible-only? - (let-boxes ([p p]) - (find-last-visible-position l p) - p) - p)) - l)))) + (if (i . > . (+ (last-paragraph) (if extra-line? -1 0))) + len + (let* ([i (max 0 i)] + [l (mline-find-paragraph (unbox line-root-box) i)] + [l (if l + (let loop ([l l]) + (if (and (mline-next l) + (zero? (mline-starts-paragraph (mline-next l)))) + (loop (mline-next l)) + l)) + (if extra-line? + len + last-line))]) + (if (mline? l) + (let ([p (+ (mline-get-position l) (mline-len l))]) + (if visible-only? + (let-boxes ([p p]) + (find-last-visible-position l p) + p) + p)) + l))))) (def/public (line-paragraph [exact-nonnegative-integer? i]) (cond diff --git a/collects/scribblings/gui/editor-overview.scrbl b/collects/scribblings/gui/editor-overview.scrbl index 8378d16266..644645480d 100644 --- a/collects/scribblings/gui/editor-overview.scrbl +++ b/collects/scribblings/gui/editor-overview.scrbl @@ -537,10 +537,10 @@ See also @method[editor<%> write-headers-to-file] and @section[#:tag "editoreol"]{End of Line Ambiguity} Because an editor can force a line break even when there is no - carriage return item, a @techlink{position} alone does not always + newline item, a @techlink{position} alone does not always specify a @techlink{location} for the caret. Consider the last - @techlink{position} of a line that is soft-broken (i.e., no carriage - return is present): there is no @techlink{item} between the last + @techlink{position} of a line that is soft-broken (i.e., no newline + is present): there is no @techlink{item} between the last @techlink{item} of the line and the first @techlink{item} of the next line, so two @techlink{location}s (one end-of-line and one start-of-line) map to the same @techlink{position}. @@ -570,8 +570,8 @@ Text can be extracted from an editor in either of two forms: @item{@deftech{Simple text}, where there is one character per @techlink{item}. @techlink{Item}s that are characters are mapped to themselves, and all other @techlink{item}s are mapped to a - period. Line breaks are represented by carriage-return characters - (ASCII 13).} + period. Line breaks are represented by newline characters + (ASCII 10).} @item{@deftech{Flattened text}, where each @techlink{item} can map to an arbitrary string. @techlink{Item}s that are characters are still diff --git a/collects/scribblings/gui/snip-class.scrbl b/collects/scribblings/gui/snip-class.scrbl index 7df8f280bb..b139382a00 100644 --- a/collects/scribblings/gui/snip-class.scrbl +++ b/collects/scribblings/gui/snip-class.scrbl @@ -362,8 +362,8 @@ following symbols: @item{@indexed-racket['can-append] --- this snip can be merged with another snip of the same type} - @item{@indexed-racket['invisible] --- the user doesn't ``see'' this snip; - e.g.: a carriage return} + @item{@indexed-racket['invisible] --- an @deftech{invisible} snip + that the user doesn't see, such as a newline} @item{@indexed-racket['hard-newline] --- a newline must follow the snip} diff --git a/collects/scribblings/gui/text-class.scrbl b/collects/scribblings/gui/text-class.scrbl index cf3dcfb5f1..482d3a3072 100644 --- a/collects/scribblings/gui/text-class.scrbl +++ b/collects/scribblings/gui/text-class.scrbl @@ -163,7 +163,7 @@ Called after the editor's maximum or minimum height or width is after-set-size-constraint] modifies the editor). (This callback method is provided because setting an editor's maximum - width may cause lines to be re-flowed with soft carriage returns.) + width may cause lines to be re-flowed with soft newlines.) See also @method[text% can-set-size-constraint?] and @method[editor<%> on-edit-sequence]. @@ -299,7 +299,7 @@ is changed. If the return value is @racket[#f], then the change will be aborted. (This callback method is provided because setting an editor's maximum -width may cause lines to be re-flowed with soft carriage returns.) +width may cause lines to be re-flowed with soft newlines.) See also @method[text% on-set-size-constraint], @method[text% after-set-size-constraint], and @method[editor<%> on-edit-sequence]. @@ -996,8 +996,8 @@ If @racket[flattened?] is not @racket[#f], then flattened text is returned. text. If @racket[force-cr?] is not @racket[#f] and @racket[flattened?] is not - @racket[#f], then automatic carriage returns (from word-wrapping) are - written into the return string as real carriage returns. + @racket[#f], then automatic newlines (from word-wrapping) are + written into the return string as real newlines. } @@ -1214,9 +1214,9 @@ If there are fewer than @math{@racket[line]-1} lines, the end of the last line is returned. If @racket[line] is less than 0, then the end of the first line is returned. -If the line ends with invisible @techlink{item}s (such as a carriage - return) and @racket[visible?] is not @racket[#f], the first - @techlink{position} before the invisible @techlink{item}s is +If the line ends with @tech{invisible} @techlink{item}s (such as a + newline) and @racket[visible?] is not @racket[#f], the first + @techlink{position} before the @tech{invisible} @techlink{item}s is returned. @LineToPara[@racket[paragraph-end-position]] @@ -1273,8 +1273,8 @@ If there are fewer than @math{@racket[line]-1} lines, the start of the last line is returned. If @racket[line] is less than 0, then the start of the first line is returned. -If the line starts with invisible @techlink{item}s and @racket[visible?] is not - @racket[#f], the first @techlink{position} past the invisible @techlink{item}s is +If the line starts with @tech{invisible} @techlink{item}s and @racket[visible?] is not + @racket[#f], the first @techlink{position} past the @tech{invisible} @techlink{item}s is returned. @LineToPara[@racket[paragraph-start-position]] @@ -1537,7 +1537,7 @@ Called before the editor's maximum or minimum height or width is the change has completed. (This callback method is provided because setting an editor's maximum - width may cause lines to be re-flowed with soft carriage returns.) + width may cause lines to be re-flowed with soft newlines.) See also @method[editor<%> on-edit-sequence]. @@ -1560,7 +1560,7 @@ Returns the ending line of a given paragraph. @|ParagraphNumbering| @|LineNumber @defmethod[(paragraph-end-position [paragraph exact-nonnegative-integer?] - [visible? any/c #f]) + [visible? any/c #t]) exact-nonnegative-integer?]{ Returns the ending @techlink{position} of a given paragraph. @|ParagraphNumbering| @@ -1569,9 +1569,9 @@ If there are fewer than @math{@racket[paragraph]-1} paragraphs, the end of the last paragraph is returned. If @racket[paragraph] is less than 0, then the end of the first paragraph is returned. -If the paragraph ends with invisible @techlink{item}s (such as a carriage - return) and @racket[visible?] is not @racket[#f], the first @techlink{position} - before the invisible @techlink{item}s is returned. +If the paragraph ends with @tech{invisible} @techlink{item}s (such as a newline) + and @racket[visible?] is not @racket[#f], the first @techlink{position} + before the @tech{invisible} @techlink{item}s is returned. } @@ -1589,7 +1589,7 @@ is greater than the highest-numbered paragraph, then the editor's end @defmethod[(paragraph-start-position [paragraph exact-nonnegative-integer?] - [visible? any/c #f]) + [visible? any/c #t]) exact-nonnegative-integer?]{ Returns the starting @techlink{position} of a given paragraph. @|ParagraphNumbering| @@ -1597,8 +1597,8 @@ Returns the starting @techlink{position} of a given paragraph. @|ParagraphNumber If there are fewer than @math{@racket[paragraph]-1} paragraphs, the start of the last paragraph is returned. -If the paragraph starts with invisible @techlink{item}s and @racket[visible?] is - not @racket[#f], the first @techlink{position} past the invisible @techlink{item}s is +If the paragraph starts with @tech{invisible} @techlink{item}s and @racket[visible?] is + not @racket[#f], the first @techlink{position} past the @tech{invisible} @techlink{item}s is returned. } @@ -1887,7 +1887,8 @@ The legal formats are: @itemize[ @item{@racket['standard] --- a standard editor file} @item{@racket['text] --- a text file} -@item{@racket['text-force-cr] --- a text file; when writing, change automatic newlines (from word-wrapping) into real carriage returns} +@item{@racket['text-force-cr] --- a text file; when writing, change +automatic newlines (from word-wrapping) into real newlines} ] @MonitorMethod[@elem{The file format of an editor} @elem{the diff --git a/collects/tests/gracket/wxme.rkt b/collects/tests/gracket/wxme.rkt index 47c2ad3348..2315916b51 100644 --- a/collects/tests/gracket/wxme.rkt +++ b/collects/tests/gracket/wxme.rkt @@ -1400,4 +1400,20 @@ ;; ---------------------------------------- +(let () + (define t (new text%)) + (send t insert "1\n12\n123\n") + (expect (send t paragraph-start-position 3) 9) + (expect (send t paragraph-end-position 3) 9) + (expect (send t line-end-position 3) 9)) + +(let () + (define t (new text%)) + (send t insert "1\n12\n123\n\n") + (expect (send t paragraph-start-position 3) 9) + (expect (send t paragraph-end-position 3) 9) + (expect (send t line-end-position 3) 9)) + +;; ---------------------------------------- + (done) From c993d856d504b493e8f9fc63c8058029e842768a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 8 Oct 2011 09:08:01 -0600 Subject: [PATCH 348/746] editor<%> doc fixes (cherry picked from commit ed38297c971b7e5de07e32b1d82e827ce6a8f58f) --- collects/scribblings/gui/editor-intf.scrbl | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/collects/scribblings/gui/editor-intf.scrbl b/collects/scribblings/gui/editor-intf.scrbl index f70f8ccf2e..4555fda0fd 100644 --- a/collects/scribblings/gui/editor-intf.scrbl +++ b/collects/scribblings/gui/editor-intf.scrbl @@ -121,11 +121,9 @@ Does nothing. @methspec{ -Called just after the editor is loaded from a file. - -The argument to the method originally specified whether the save was -successful, but failures now trigger exceptions such that the method is -not even called. Consequently, the argument is always @racket[#t]. +Called just after the editor is loaded from a file or during the +exception escape when an attempt to load fails. The @racket[success?] +argument indicates whether the load succeeded. See also @method[editor<%> can-load-file?] and @@ -146,11 +144,9 @@ Does nothing. @methspec{ -Called just after the editor is saved to a file. - -The argument to the method originally specified whether the save was -successful, but failures now trigger exceptions such that the method is -not even called. Consequently, the argument is always @racket[#t]. +Called just after the editor is saved to a file or during the +exception escape when a save fails. The @racket[success?] argument +indicates whether the save succeeded. See also @method[editor<%> can-save-file?] and From fcd5fb9d746bd77def26cd8e92faa219d18c5616 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 8 Oct 2011 10:42:32 -0500 Subject: [PATCH 349/746] adjust uses of after-load-file to use the success? flag (cherry picked from commit fcc720f43e7f92063637af65b8c087327908e2ca) --- collects/drracket/private/module-language.rkt | 2 +- collects/framework/private/text.rkt | 34 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/collects/drracket/private/module-language.rkt b/collects/drracket/private/module-language.rkt index 70d7c70354..e3cb18b8f3 100644 --- a/collects/drracket/private/module-language.rkt +++ b/collects/drracket/private/module-language.rkt @@ -1519,7 +1519,7 @@ (inner (void) after-delete start end)) (define/augment (after-load-file success?) - (buffer-modified) + (when success? (buffer-modified)) (inner (void) after-load-file success?)) (super-new))) diff --git a/collects/framework/private/text.rkt b/collects/framework/private/text.rkt index 5a1adf88d8..4cfe9f0f12 100644 --- a/collects/framework/private/text.rkt +++ b/collects/framework/private/text.rkt @@ -295,10 +295,11 @@ (define/augment (after-load-file success?) (inner (void) after-load-file success?) - (set! ranges (make-hash)) - (set! ranges-low 0) - (set! ranges-high 0) - (set! ranges-list #f)) + (when success? + (set! ranges (make-hash)) + (set! ranges-low 0) + (set! ranges-high 0) + (set! ranges-list #f))) (define/public (highlight-range start end color [caret-space? #f] [priority 'low] [style 'rectangle]) (unless (let ([exact-pos-int? @@ -1816,18 +1817,19 @@ (mixin ((class->interface text%)) (crlf-line-endings<%>) (inherit get-filename use-file-text-mode) (define/augment (after-load-file success?) - (cond - [(preferences:get 'framework:always-use-platform-specific-linefeed-convention) - (use-file-text-mode #t)] - [else - (define unix-endings? - (with-handlers ((exn:fail:filesystem? (λ (x) #t))) - (call-with-input-file (get-filename) - (λ (port) - (regexp-match? unix-line-endings-regexp port))))) - (use-file-text-mode - (and (eq? (system-type) 'windows) - (not unix-endings?)))]) + (when success? + (cond + [(preferences:get 'framework:always-use-platform-specific-linefeed-convention) + (use-file-text-mode #t)] + [else + (define unix-endings? + (with-handlers ((exn:fail:filesystem? (λ (x) #t))) + (call-with-input-file (get-filename) + (λ (port) + (regexp-match? unix-line-endings-regexp port))))) + (use-file-text-mode + (and (eq? (system-type) 'windows) + (not unix-endings?)))])) (inner (void) after-load-file success?)) (super-new) From d2204bfd17bc2ec7efd9a1a790c919d9a913f59d Mon Sep 17 00:00:00 2001 From: Stephen Chang Date: Sat, 8 Oct 2011 15:54:09 -0400 Subject: [PATCH 350/746] fix lazy stepper bug: annota of non-identifier fns - fix lazy stepper bug where delaying of non-identifier fns wasnt being properly hidden - add test case for this bug include in 5.2 (cherry picked from commit 79dd7df9451627b206f97ede04ea223516a75088) --- collects/lazy/lazy.rkt | 5 ++++- collects/tests/stepper/automatic-tests.rkt | 2 +- collects/tests/stepper/test-cases.rkt | 12 ++++++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/collects/lazy/lazy.rkt b/collects/lazy/lazy.rkt index 006a984928..e302b9a034 100644 --- a/collects/lazy/lazy.rkt +++ b/collects/lazy/lazy.rkt @@ -78,7 +78,10 @@ (define-syntax (mark-as-lazy-op stx) (syntax-case stx () - [(_ arg) (stepper-add-lazy-op-prop (syntax/loc stx arg))])) + [(_ arg) + (identifier? #'arg) + (stepper-add-lazy-op-prop (syntax/loc stx arg))] + [(_ arg) #'arg])) (define-syntax (hidden-~ stx) (syntax-case stx () diff --git a/collects/tests/stepper/automatic-tests.rkt b/collects/tests/stepper/automatic-tests.rkt index c5d23c8c4f..dc7a7a750a 100644 --- a/collects/tests/stepper/automatic-tests.rkt +++ b/collects/tests/stepper/automatic-tests.rkt @@ -23,7 +23,7 @@ lazy-length lazy-list-ref lazy-list-tail lazy-append lazy-reverse lazy-empty? lazy-assoc lazy-assq lazy-assv lazy-cons? lazy-remove lazy-remq lazy-remv lazy-member lazy-memq lazy-memv lazy-filter1 lazy-filter2 lazy-fold - lazy-cyclic1)) + lazy-cyclic1 lazy-fn-app)) (let ((outer-namespace (current-namespace))) (parameterize ([display-only-errors #t] diff --git a/collects/tests/stepper/test-cases.rkt b/collects/tests/stepper/test-cases.rkt index 7eb7984ff7..be305019b3 100644 --- a/collects/tests/stepper/test-cases.rkt +++ b/collects/tests/stepper/test-cases.rkt @@ -2132,8 +2132,16 @@ -> ,def (+ 1 {1}) :: ,def {(+ 1 1)} -> ,def {2})) - - + ; application in function position -- checks bug fix + (let* ([lxx '(lambda (x) x)] + [def `(define I ,lxx)]) + (t 'lazy-fn-app m:lazy + ,def ((I I) I) + :: ,def (({I} I) I) -> ,def (({,lxx} I) I) + :: ,def ((,lxx {I}) I) -> ,def ((,lxx {,lxx}) I) + :: ,def ({(,lxx ,lxx)} I) -> ,def ({,lxx} I) + :: ,def (,lxx {I}) -> ,def (,lxx {,lxx}) + :: ,def {(,lxx ,lxx)} -> ,def {,lxx})) #; From a4a7b80c978a1dfe462009017d1a91961938a895 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 8 Oct 2011 16:49:25 -0500 Subject: [PATCH 351/746] avoid calling the show method for tooltips unless the frame is shown. please include in 5.2 (cherry picked from commit 5db48b3e7379e35d84fadb02db0fddd5a3743e90) --- collects/drracket/private/syncheck/gui.rkt | 8 ++++++-- collects/drracket/private/tooltip.rkt | 16 +++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/collects/drracket/private/syncheck/gui.rkt b/collects/drracket/private/syncheck/gui.rkt index eeb105b19b..eb30b0c0b8 100644 --- a/collects/drracket/private/syncheck/gui.rkt +++ b/collects/drracket/private/syncheck/gui.rkt @@ -1048,13 +1048,17 @@ If the namespace does not, they are colored the unbound color. ;; and on-paint gets called each time the cursor blinks...) (cond [(not eles) - (when tooltip-frame (send tooltip-frame show #f)) + (when tooltip-frame + (when (send tooltip-frame is-shown?) + (send tooltip-frame show #f))) (set! tooltips-in-sync-with-cursor-eles? #t)] [else (define tooltip-infos (filter tooltip-info? eles)) (cond [(null? tooltip-infos) - (when tooltip-frame (send tooltip-frame show #f)) + (when tooltip-frame + (when (send tooltip-frame is-shown?) + (send tooltip-frame show #f))) (set! tooltips-in-sync-with-cursor-eles? #t)] [else (unless tooltip-frame (set! tooltip-frame (new tooltip-frame%))) diff --git a/collects/drracket/private/tooltip.rkt b/collects/drracket/private/tooltip.rkt index 8b2efd4744..2dc05e1d06 100644 --- a/collects/drracket/private/tooltip.rkt +++ b/collects/drracket/private/tooltip.rkt @@ -6,14 +6,16 @@ (define tooltip-frame% (class frame% - (inherit show reflow-container move get-width get-height) + (inherit show reflow-container move get-width get-height is-shown?) + (define/override (on-subwindow-event r evt) - (cond - [(or (send evt entering?) - (send evt button-down?)) - (show #f) - #t] - [else #f])) + (and (is-shown?) + (cond + [(or (send evt entering?) + (send evt button-down?)) + (show #f) + #t] + [else #f]))) (define/public (set-tooltip ls) (send yellow-message set-lab ls)) From e1dfd37f75a5af4262df229bfd9067af0aa8e418 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 8 Oct 2011 16:39:00 -0600 Subject: [PATCH 352/746] fix compiler bug that could cause infinite inlining loop The bug was that a procedure could be incorrectly marked as a "leaf" procedure, which could in turn cause the compiler to keep inlining a very small procedure that calls itself. Closes PR 12270 Merge to 5.2 (cherry picked from commit 1bc80310e3ae54963568238a0595935b2f558708) --- collects/tests/racket/optimize.rktl | 10 ++++++++++ src/racket/src/optimize.c | 20 +++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/collects/tests/racket/optimize.rktl b/collects/tests/racket/optimize.rktl index 4cfebc7c41..b7bf2a4028 100644 --- a/collects/tests/racket/optimize.rktl +++ b/collects/tests/racket/optimize.rktl @@ -1654,6 +1654,16 @@ (begin (f) #f)) #f)) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Make sure the compiler doesn't end up in an infinite inling loop: + +(module unc-small-self-call racket/base + (define unc1 + (let ([x 1]) + (lambda () + (unc1)))) + (unc1)) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/src/racket/src/optimize.c b/src/racket/src/optimize.c index 86eaacfcff..f46924be71 100644 --- a/src/racket/src/optimize.c +++ b/src/racket/src/optimize.c @@ -914,9 +914,9 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a int offset = 0, single_use = 0, psize = 0; Scheme_Object *bad_app = NULL, *prev = NULL, *orig_le = le; intptr_t prev_offset = 0; - int nested_count = 0, outside_nested = 0, already_opt = optimized_rator; + int nested_count = 0, outside_nested = 0, already_opt = optimized_rator, nonleaf; - if (info->inline_fuel < 0) + if ((info->inline_fuel < 0) && info->has_nonleaf) return NULL; /* Move inside `let' bindings, so we can convert ((let (....) proc) arg ...) @@ -996,7 +996,9 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a bad_app = le; } - if (le && SAME_TYPE(SCHEME_TYPE(le), scheme_compiled_unclosed_procedure_type)) { + nonleaf = 1; + + if (le && SAME_TYPE(SCHEME_TYPE(le), scheme_compiled_unclosed_procedure_type) && (info->inline_fuel >= 0)) { Scheme_Closure_Data *data = (Scheme_Closure_Data *)le; int sz; @@ -1048,25 +1050,28 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a return le; } else { LOG_INLINE(fprintf(stderr, "No inline %s\n", scheme_write_to_string(data->name ? data->name : scheme_false, NULL))); - info->has_nonleaf = 1; } } else { LOG_INLINE(fprintf(stderr, "No fuel %s %d[%d]>%d@%d %d\n", scheme_write_to_string(data->name ? data->name : scheme_false, NULL), sz, is_leaf, threshold, info->inline_fuel, info->use_psize)); - info->has_nonleaf = 1; } } else { /* Issue warning below */ bad_app = (Scheme_Object *)data; + nonleaf = 0; } } if (le && SCHEME_PRIMP(le)) { int opt; opt = ((Scheme_Prim_Proc_Header *)le)->flags & SCHEME_PRIM_OPT_MASK; - if (opt >= SCHEME_PRIM_OPT_NONCM) + if (opt >= SCHEME_PRIM_OPT_NONCM) { *_flags = (CLOS_PRESERVES_MARKS | CLOS_SINGLE_RESULT); + if (opt >= SCHEME_PRIM_OPT_IMMEDIATE) { + nonleaf = 0; + } + } } if (le && SCHEME_PROCP(le) && (app || app2 || app3)) { @@ -1074,6 +1079,7 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a a[0] = le; if (!scheme_check_proc_arity(NULL, argc, 0, 1, a)) { bad_app = le; + nonleaf = 0; } } @@ -1083,7 +1089,7 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a info->psize += psize; } - if (!le) + if (nonleaf) info->has_nonleaf = 1; if (bad_app) { From bdddffaa9b175339a005a8fdc894d9787d64c341 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 8 Oct 2011 16:47:19 -0600 Subject: [PATCH 353/746] cocoa: fix `show #f' on already unshown frame shows it briefly Merge to 5.2 (cherry picked from commit bf3f09a3c18637b8ebf719f235813c2390ac331e) --- collects/mred/private/wx/cocoa/frame.rkt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/collects/mred/private/wx/cocoa/frame.rkt b/collects/mred/private/wx/cocoa/frame.rkt index ef26252a88..f16baaf030 100644 --- a/collects/mred/private/wx/cocoa/frame.rkt +++ b/collects/mred/private/wx/cocoa/frame.rkt @@ -324,8 +324,9 @@ (send p set-sheet #f) (tell (tell NSApplication sharedApplication) endSheet: cocoa)))) - (tellv cocoa deminiaturize: #f) - (tellv cocoa orderOut: #f) + (when (is-shown?) ; otherwise, `deminiaturize' can show the window + (tellv cocoa deminiaturize: #f) + (tellv cocoa orderOut: #f)) (force-window-focus))) (register-frame-shown this on?) (let ([num (tell #:type _NSInteger cocoa windowNumber)]) From fd03fb8575990b3a7c31fd5a4c50e7d46c60f72e Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Sun, 9 Oct 2011 15:21:00 +0200 Subject: [PATCH 354/746] Synch German string constants with latest. (cherry picked from commit 334bf53bb99472ad62cd52ca36f218f505ab8f9b) --- .../string-constants/private/german-string-constants.rkt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/collects/string-constants/private/german-string-constants.rkt b/collects/string-constants/private/german-string-constants.rkt index b901e45303..edec0f2aae 100644 --- a/collects/string-constants/private/german-string-constants.rkt +++ b/collects/string-constants/private/german-string-constants.rkt @@ -709,6 +709,11 @@ (clear-current "Dieses löschen") (new-window "Neues Fenster") + ;; popup menu when right-clicking in the gap between + ;; the definitions and interactions window + (change-to-vertical-alignment "Auf vertikal umschalten") + (change-to-horizontal-alignment "Auf horizontal umschalten") + ;;; exiting and quitting ``are you sure'' dialog ;;; exit is used on windows, quit on macos, in English. Other ;;; languages probably use the same word on both platforms. @@ -822,6 +827,7 @@ ;;; edit menu (split-menu-item-label "&Splitten") (collapse-menu-item-label "Einfalten") + (find-longest-line "Längste Zeile finden") ;;; language menu (language-menu-name "&Sprache") From 6fe0b3362521075417ca8df3480e7bf2bc4ad050 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 9 Oct 2011 08:51:37 -0600 Subject: [PATCH 355/746] fix ffi retain of callbacks The FFI's weak table of callback procedures (to map Racket procedures to FFI callback objects) suffered from the classic key-in-value problem. Closes PR 12228, probably Merge to 5.2 (cherry picked from commit 8bd81f48062ef2295d95f01422d8c73aef355053) --- collects/ffi/unsafe.rkt | 2 +- collects/ffi/unsafe/try-atomic.rkt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/ffi/unsafe.rkt b/collects/ffi/unsafe.rkt index 5852cf7c8f..93bb391f85 100644 --- a/collects/ffi/unsafe.rkt +++ b/collects/ffi/unsafe.rkt @@ -446,7 +446,7 @@ (lambda (x) (and x (let ([cb (ffi-callback (wrap x) itypes otype abi atomic? async-apply)]) - (cond [(eq? keep #t) (hash-set! held-callbacks x cb)] + (cond [(eq? keep #t) (hash-set! held-callbacks x (make-ephemeron x cb))] [(box? keep) (let ([x (unbox keep)]) (set-box! keep diff --git a/collects/ffi/unsafe/try-atomic.rkt b/collects/ffi/unsafe/try-atomic.rkt index 68f2f09043..c0c860e45d 100644 --- a/collects/ffi/unsafe/try-atomic.rkt +++ b/collects/ffi/unsafe/try-atomic.rkt @@ -67,7 +67,7 @@ (define (can-try-atomic?) (and (freezer-box) (not (in-try-atomic?)))) ;; prevent GC of handler while it's installed: -(define saved-ptrs (make-hash)) +(define saved-ptrs (make-hasheq)) (define (try-atomic thunk default #:should-give-up? [should-give-up? From 74846d068498690ba7ebd195f3ab2b6d555faa4b Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sat, 1 Oct 2011 11:20:27 -0400 Subject: [PATCH 356/746] Change basic-top-level-window% to support `set-icon', and use to set icon for splash screen. Closes 12241 Merge to 5.2 (cherry picked from commit 1b69d742bd7b895ce44c8ed21ffcbaa7caeebf93) --- collects/framework/splash.rkt | 7 +++---- collects/mred/private/mrtop.rkt | 10 +++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/collects/framework/splash.rkt b/collects/framework/splash.rkt index 42bd77178e..9d47d09078 100644 --- a/collects/framework/splash.rkt +++ b/collects/framework/splash.rkt @@ -155,14 +155,13 @@ (send (get-gauge) set-range splash-max-width) (send splash-tlw set-label splash-title) - #; ;; commented out because dialogs don't accept set-icon (when frame-icon (if (pair? frame-icon) - (let ([small (car icon)] - [large (cdr icon)]) + (let ([small (car frame-icon)] + [large (cdr frame-icon)]) (send splash-tlw set-icon small (send small get-loaded-mask) 'small) (send splash-tlw set-icon large (send large get-loaded-mask) 'large)) - (send splash-tlw set-icon frame-icon (send icon get-loaded-mask) 'both))) + (send splash-tlw set-icon frame-icon (send frame-icon get-loaded-mask) 'both))) (cond [(or (path? splash-draw-spec) diff --git a/collects/mred/private/mrtop.rkt b/collects/mred/private/mrtop.rkt index 4fb5a7f78b..92664d7030 100644 --- a/collects/mred/private/mrtop.rkt +++ b/collects/mred/private/mrtop.rkt @@ -85,6 +85,10 @@ [can-exit? (lambda () (can-close?))] [on-exit (lambda () (on-close) (show #f))] [on-activate (lambda (x) (void))] + [set-icon (case-lambda + [(i) (send wx set-icon i)] + [(i b) (send wx set-icon i b)] + [(i b l?) (send wx set-icon i b l?)])] [center (entry-point (case-lambda [() (send wx center 'both)] @@ -185,11 +189,7 @@ [set-status-text (lambda (s) (do-set-status-text s))] [has-status-line? (lambda () status-line?)] [iconize (entry-point (lambda (on?) (send wx iconize on?)))] - [is-iconized? (entry-point (lambda () (send wx iconized?)))] - [set-icon (case-lambda - [(i) (send wx set-icon i)] - [(i b) (send wx set-icon i b)] - [(i b l?) (send wx set-icon i b l?)])] + [is-iconized? (entry-point (lambda () (send wx iconized?)))] [maximize (entry-point (lambda (on?) (send wx position-for-initial-show) (send wx maximize on?)))] [is-maximized? (entry-point (lambda () (send wx is-maximized?)))] [get-menu-bar (entry-point (lambda () (let ([mb (send wx get-the-menu-bar)]) From 78c38d42b650e635115db1ef637f5327749b6015 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 9 Oct 2011 09:45:42 -0600 Subject: [PATCH 357/746] docs and release notes for `set-icon' change Merge to 5.2 (cherry picked from commit 8f0fa96d699fd304b32e9cb00db8cc18220f58ee) --- collects/scribblings/gui/frame-class.scrbl | 38 ------------------- .../gui/top-level-window-intf.scrbl | 38 +++++++++++++++++++ doc/release-notes/racket/HISTORY.txt | 2 + 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/collects/scribblings/gui/frame-class.scrbl b/collects/scribblings/gui/frame-class.scrbl index ce2eaec33d..515305f9be 100644 --- a/collects/scribblings/gui/frame-class.scrbl +++ b/collects/scribblings/gui/frame-class.scrbl @@ -227,44 +227,6 @@ On Mac OS X, called when the user clicks the toolbar button on a } -@defmethod[(set-icon [icon (is-a?/c bitmap%)] - [mask (is-a?/c bitmap%) #f] - [which (one-of/c 'small 'large 'both) 'both]) - void?]{ - -Sets the large or small icon bitmap for this frame. Future changes to - the bitmap do not affect the frame's icon. - -The icon is used in a platform-specific way: - -@itemize[ - - @item{Windows --- the small icon is used for the frame's icon (in the - top-left) and in the task bar, and the large icon is used for - the Alt-Tab task switcher.} - - @item{Mac OS X --- both icons are ignored.} - - @item{Unix --- many window managers use the small icon in the same way - as Windows, and others use the small icon when iconifying the - frame; the large icon is ignored.} - -] - -The bitmap for either icon can be any size, but most platforms scale - the small bitmap to 16 by 16 pixels and the large bitmap to 32 by 32 - pixels. - -If a mask bitmap is not provided, then the entire (rectangular) bitmap - is used as an icon. - -If a mask bitmap is provided, the mask must be monochrome. In the mask - bitmap, use black pixels to indicate the icon's region and use white - pixels outside the icon's region. In the icon bitmap, use black - pixels for the region outside the icon. - -} - @defmethod[(set-status-text [text string?]) void?]{ diff --git a/collects/scribblings/gui/top-level-window-intf.scrbl b/collects/scribblings/gui/top-level-window-intf.scrbl index 8825ced005..d097f85a43 100644 --- a/collects/scribblings/gui/top-level-window-intf.scrbl +++ b/collects/scribblings/gui/top-level-window-intf.scrbl @@ -312,6 +312,44 @@ Sets the size of the window (in pixels), but only if the given size is } + +@defmethod[(set-icon [icon (is-a?/c bitmap%)] + [mask (is-a?/c bitmap%) #f] + [which (one-of/c 'small 'large 'both) 'both]) + void?]{ + +Sets the large or small icon bitmap for the window. Future changes to + the bitmap do not affect the window's icon. + +The icon is used in a platform-specific way: + +@itemize[ + + @item{Windows --- the small icon is used for the window's icon (in the + top-left) and in the task bar, and the large icon is used for + the Alt-Tab task switcher.} + + @item{Mac OS X --- both icons are ignored.} + + @item{Unix --- many window managers use the small icon in the same way + as Windows, and others use the small icon when iconifying the + frame; the large icon is ignored.} + +] + +The bitmap for either icon can be any size, but most platforms scale + the small bitmap to 16 by 16 pixels and the large bitmap to 32 by 32 + pixels. + +If a mask bitmap is not provided, then the entire (rectangular) bitmap + is used as an icon. + +If a mask bitmap is provided, the mask must be monochrome. In the mask + bitmap, use black pixels to indicate the icon's region and use white + pixels outside the icon's region. In the icon bitmap, use black + pixels for the region outside the icon.} + + @defmethod[(show [show any/c]) void?]{ diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index cbbc486823..cc8550b0c0 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,5 +1,7 @@ Version 5.1.3.12 Removed built-in support for Honu reading and printing +racket/gui: moved set-icon method from frame% to + top-level-window<%> Version 5.1.3.11 Added exn:fail:syntax:unbound From 187c9a18b7b352bacc6f1bd292c3b47e809353db Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 9 Oct 2011 10:34:40 -0600 Subject: [PATCH 358/746] fix QNX sconfig entry Merge to 5.2 (cherry picked from commit e2bcbb0dfbfc05d759874318710285a08e9b13dc) --- src/racket/sconfig.h | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/racket/sconfig.h b/src/racket/sconfig.h index bf110ef2e4..917ea70455 100644 --- a/src/racket/sconfig.h +++ b/src/racket/sconfig.h @@ -931,19 +931,31 @@ # define FLAGS_ALREADY_SET +#endif + + /************ QNX *************/ + +#if defined(__QNX__) + +# define SCHEME_PLATFORM_LIBRARY_SUBPATH "i386-qnx" + +# include "uconfig.h" +# define SIGSET_IS_SIGNAL +# define SIGSET_NEEDS_REINSTALL + +# define USE_FCNTL_O_NONBLOCK + +# define ASSUME_FIXED_STACK_SIZE +# define FIXED_STACK_SIZE 524288 + +# define FLAGS_ALREADY_SET + #endif /***************************************************/ #endif /* end not OSKit */ -#if defined(__QNX__) -# define USE_FCNTL_O_NONBLOCK -# define SCHEME_PLATFORM_LIBRARY_SUBPATH "i386-QNX" -# define ASSUME_FIXED_STACK_SIZE -# define FIXED_STACK_SIZE 524288 -#endif - /************** (END KNOWN ARCHITECTURE/SYSTEMS) ****************/ From 2fec3dd8f6d64fcd70ddbab73912d5c8a6b6f759 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 9 Oct 2011 10:34:56 -0600 Subject: [PATCH 359/746] mark OS jmpbuf as GC-ignored This change is intended to make the QNX port work, but it should also future-proof Racket a little for other platforms. (cherry picked from commit b377cafdac9a4496e443275d4fb9ed91c4c6f4e0) --- collects/compiler/private/xform.rkt | 1 + src/racket/include/scheme.h | 35 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/collects/compiler/private/xform.rkt b/collects/compiler/private/xform.rkt index 5f9890135f..a7b131a535 100644 --- a/collects/compiler/private/xform.rkt +++ b/collects/compiler/private/xform.rkt @@ -719,6 +719,7 @@ (printf "#define NULL_OUT_ARRAY(a) memset(a, 0, sizeof(a))\n") ;; Annotation that normally disappears: (printf "#define GC_CAN_IGNORE /**/\n") + (printf "#define XFORM_CAN_IGNORE /**/\n") (printf "#define __xform_nongcing__ /**/\n") ;; Another annotation to protect against GC conversion: (printf "#define HIDE_FROM_XFORM(x) x\n") diff --git a/src/racket/include/scheme.h b/src/racket/include/scheme.h index 27b01cee45..3aa17d4497 100644 --- a/src/racket/include/scheme.h +++ b/src/racket/include/scheme.h @@ -181,6 +181,25 @@ typedef struct FSSpec mzFSSpec; # endif #endif +#ifdef MZ_PRECISE_GC +# ifndef MZ_XFORM +# define XFORM_SKIP_PROC /* empty */ +# define XFORM_CAN_IGNORE /**/ +# endif +#else +# define XFORM_HIDE_EXPR(x) x +# define XFORM_START_SKIP /**/ +# define XFORM_END_SKIP /**/ +# define XFORM_START_SUSPEND /**/ +# define XFORM_END_SUSPEND /**/ +# define XFORM_SKIP_PROC /**/ +# define XFORM_START_TRUST_ARITH /**/ +# define XFORM_END_TRUST_ARITH /**/ +# define XFORM_CAN_IGNORE /**/ +# define XFORM_TRUST_PLUS + +# define XFORM_TRUST_MINUS - +#endif + /* PPC Linux plays a slimy trick: it defines strcpy() as a macro that uses __extension__. This breaks the 3m xform. */ #if defined(MZ_XFORM) && defined(strcpy) @@ -875,7 +894,7 @@ typedef mz_one_jit_jmp_buf mz_jit_jmp_buf[1]; #ifdef MZ_PRECISE_GC typedef struct { - mz_jit_jmp_buf jb; + XFORM_CAN_IGNORE mz_jit_jmp_buf jb; intptr_t gcvs; /* declared as `intptr_t' to hide pointer from 3m xform */ intptr_t gcvs_cnt; } mz_jmp_buf; @@ -1696,9 +1715,6 @@ extern void *scheme_malloc_envunbox(size_t); # define MZ_GC_REG() (__gc_var_stack__[0] = GC_variable_stack, \ GC_variable_stack = __gc_var_stack__) # define MZ_GC_UNREG() (GC_variable_stack = (void **)__gc_var_stack__[0]) -# ifndef MZ_XFORM -# define XFORM_SKIP_PROC /* empty */ -# endif #else # define MZ_GC_DECL_REG(size) /* empty */ # define MZ_GC_VAR_IN_REG(x, v) /* empty */ @@ -1706,17 +1722,6 @@ extern void *scheme_malloc_envunbox(size_t); # define MZ_GC_NO_VAR_IN_REG(x) /* empty */ # define MZ_GC_REG() /* empty */ # define MZ_GC_UNREG() /* empty */ -# define XFORM_HIDE_EXPR(x) x -# define XFORM_START_SKIP /**/ -# define XFORM_END_SKIP /**/ -# define XFORM_START_SUSPEND /**/ -# define XFORM_END_SUSPEND /**/ -# define XFORM_SKIP_PROC /**/ -# define XFORM_START_TRUST_ARITH /**/ -# define XFORM_END_TRUST_ARITH /**/ -# define XFORM_CAN_IGNORE /**/ -# define XFORM_TRUST_PLUS + -# define XFORM_TRUST_MINUS - #endif /*========================================================================*/ From 09e236caafbfc44901ad3a575253ce08646ca563 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Sun, 9 Oct 2011 20:16:17 -0400 Subject: [PATCH 360/746] history for release (cherry picked from commit 051649fc13e92d114b6dbb25e08eddc5e2e44697) --- doc/release-notes/teachpack/HISTORY.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes/teachpack/HISTORY.txt b/doc/release-notes/teachpack/HISTORY.txt index 4954df644d..6b3dd4925d 100644 --- a/doc/release-notes/teachpack/HISTORY.txt +++ b/doc/release-notes/teachpack/HISTORY.txt @@ -43,7 +43,7 @@ Version 5.0 [Fri May 28 13:43:21 EDT 2010] * added to-draw to universe to prepare the switch to the new terminoloy ------------------------------------------------------------------------ -Versin 4.2.5 [Fri Mar 26 10:02:11 EDT 2010] +Version 4.2.5 [Fri Mar 26 10:02:11 EDT 2010] * "release" is no longer a key event; use "release" handler instead From 0aa9f436afd8511f464791ee93645c172788fd92 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 9 Oct 2011 19:29:21 -0600 Subject: [PATCH 361/746] fix compiler confusion: non-mutating vs reorderable unsafe ops Reordering `unsafe-vector-ref' past an `unsafe-vector-set!' was particularly bad. Meanwhile, some non-mutating operations like `unsafe-mcar' were treated too conservatively. Merge to 5.2 (cherry picked from commit c805728d3e603cd71865e886baf5bcbdeb0a1dbe) --- collects/tests/racket/optimize.rktl | 61 +++++++++++++++++++++++++++++ src/racket/include/scheme.h | 14 +++---- src/racket/src/jit.c | 11 ++++-- src/racket/src/jitcommon.c | 14 +++---- src/racket/src/jitinline.c | 14 +++---- src/racket/src/list.c | 12 ++++-- src/racket/src/number.c | 10 ++--- src/racket/src/optimize.c | 24 ++++++------ src/racket/src/print.c | 12 +++++- src/racket/src/struct.c | 45 ++++++++++++--------- src/racket/src/vector.c | 14 +++---- 11 files changed, 158 insertions(+), 73 deletions(-) diff --git a/collects/tests/racket/optimize.rktl b/collects/tests/racket/optimize.rktl index b7bf2a4028..97e1730007 100644 --- a/collects/tests/racket/optimize.rktl +++ b/collects/tests/racket/optimize.rktl @@ -1372,6 +1372,67 @@ (require racket/bool) (list #t))) +;; check omit & reorder possibilities for unsafe +;; operations on mutable values: +(let () + (define (check-omit-ok expr [yes? #t]) + ;; can omit: + (test-comp `(module m racket/base + (require racket/unsafe/ops) + (define (f x) + (f x))) + `(module m racket/base + (require racket/unsafe/ops) + (define (f x) + ,expr + (f x))) + yes?) + ;; cannot reorder: + (test-comp `(module m racket/base + (require racket/unsafe/ops) + (define (f x) + (let ([y ,expr]) + (vector-ref x x) + (f x y)))) + `(module m racket/base + (require racket/unsafe/ops) + (define (f x) + (vector-ref x x) + (f x ,expr))) + #f)) + (map check-omit-ok + '((unsafe-vector-ref x x) + (unsafe-vector*-ref x x) + (unsafe-struct-ref x x) + (unsafe-struct*-ref x x) + (unsafe-mcar x) + (unsafe-mcdr x) + (unsafe-unbox x) + (unsafe-unbox* x) + (unsafe-bytes-ref x x) + (unsafe-string-ref x x) + (unsafe-flvector-ref x x) + (unsafe-fxvector-ref x x) + (unsafe-f64vector-ref x x) + (unsafe-s16vector-ref x x) + (unsafe-u16vector-ref x x))) + (map (lambda (x) (check-omit-ok x #f)) + '((unsafe-vector-set! x x x) + (unsafe-vector*-set! x x x) + (unsafe-struct-set! x x x) + (unsafe-struct*-set! x x x) + (unsafe-set-mcar! x x) + (unsafe-set-mcdr! x x) + (unsafe-set-box! x x) + (unsafe-set-box*! x x) + (unsafe-bytes-set! x x x) + (unsafe-string-set! x x x) + (unsafe-flvector-set! x x x) + (unsafe-fxvector-set! x x x) + (unsafe-f64vector-set! x x x) + (unsafe-s16vector-set! x x x) + (unsafe-u16vector-set! x x x)))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check bytecode verification of lifted functions diff --git a/src/racket/include/scheme.h b/src/racket/include/scheme.h index 3aa17d4497..2f7d45efc3 100644 --- a/src/racket/include/scheme.h +++ b/src/racket/include/scheme.h @@ -657,10 +657,9 @@ typedef struct Scheme_Offset_Cptr Do not use them directly. */ #define SCHEME_PRIM_OPT_MASK (1 | 2) #define SCHEME_PRIM_IS_PRIMITIVE 4 -#define SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER 8 -#define SCHEME_PRIM_IS_STRUCT_PRED 16 -#define SCHEME_PRIM_IS_STRUCT_OTHER 32 -#define SCHEME_PRIM_OTHER_TYPE_MASK (64 | 128 | 256) +#define SCHEME_PRIM_IS_UNSAFE_OMITABLE 8 +#define SCHEME_PRIM_IS_STRUCT_OTHER 16 +#define SCHEME_PRIM_OTHER_TYPE_MASK (32 | 64 | 128 | 256) #define SCHEME_PRIM_IS_MULTI_RESULT 512 #define SCHEME_PRIM_IS_BINARY_INLINED 1024 #define SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL 2048 @@ -682,9 +681,9 @@ typedef struct Scheme_Offset_Cptr #define SCHEME_PRIM_TYPE_PARAMETER 64 #define SCHEME_PRIM_TYPE_STRUCT_PROP_GETTER (64 | 128) #define SCHEME_PRIM_SOMETIMES_INLINED (64 | 256) -#define SCHEME_PRIM_TYPE_STRUCT_PROP_PRED (64 | 128 | 256) - -#define SCHEME_PRIM_IS_STRUCT_PROC (SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER | SCHEME_PRIM_IS_STRUCT_PRED | SCHEME_PRIM_IS_STRUCT_OTHER) +#define SCHEME_PRIM_STRUCT_TYPE_STRUCT_PROP_PRED (64 | 128 | 256) +#define SCHEME_PRIM_STRUCT_TYPE_INDEXED_GETTER 32 +#define SCHEME_PRIM_STRUCT_TYPE_PRED (32 | 64) #define SCHEME_PRIM_PROC_FLAGS(x) (((Scheme_Prim_Proc_Header *)x)->flags) @@ -811,7 +810,6 @@ typedef struct { #define SCHEME_ECONTP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_escaping_cont_type) #define SCHEME_CONT_MARK_SETP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_cont_mark_set_type) #define SCHEME_PROC_STRUCTP(obj) SAME_TYPE(SCHEME_TYPE(obj), scheme_proc_struct_type) -#define SCHEME_STRUCT_PROCP(obj) (SCHEME_PRIMP(obj) && (((Scheme_Primitive_Proc *)(obj))->pp.flags & SCHEME_PRIM_IS_STRUCT_PROC)) #define SCHEME_CLOSUREP(obj) (SAME_TYPE(SCHEME_TYPE(obj), scheme_closure_type) || SAME_TYPE(SCHEME_TYPE(obj), scheme_case_closure_type)) #define SCHEME_PRIM(obj) (((Scheme_Primitive_Proc *)(obj))->prim_val) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index 3354e60be7..7554ef39bf 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -495,10 +495,15 @@ int scheme_is_noncm(Scheme_Object *a, mz_jit_state *jitter, int depth, int stack if (SCHEME_PRIMP(a)) { int opts; opts = ((Scheme_Prim_Proc_Header *)a)->flags & SCHEME_PRIM_OPT_MASK; - if (opts >= SCHEME_PRIM_OPT_NONCM) + if (opts >= SCHEME_PRIM_OPT_NONCM) { /* Structure-type predicates are handled specially, so don't claim NONCM: */ - if (!(((Scheme_Prim_Proc_Header *)a)->flags & SCHEME_PRIM_IS_STRUCT_PRED)) - return 1; + if (((Scheme_Prim_Proc_Header *)a)->flags & SCHEME_PRIM_IS_STRUCT_OTHER) { + if ((((Scheme_Prim_Proc_Header *)a)->flags & SCHEME_PRIM_OTHER_TYPE_MASK) + == SCHEME_PRIM_STRUCT_TYPE_PRED) + return 0; + } + return 1; + } } if (depth diff --git a/src/racket/src/jitcommon.c b/src/racket/src/jitcommon.c index 53b2dd61e9..55722efadb 100644 --- a/src/racket/src/jitcommon.c +++ b/src/racket/src/jitcommon.c @@ -1552,14 +1552,12 @@ static int common4(mz_jit_state *jitter, void *_data) mz_patch_branch(ref); (void)mz_bnei_t(refslow, JIT_R0, scheme_prim_type, JIT_R2); jit_ldxi_s(JIT_R2, JIT_R0, &((Scheme_Primitive_Proc *)0x0)->pp.flags); - if (kind == 3) { - jit_andi_i(JIT_R2, JIT_R2, SCHEME_PRIM_OTHER_TYPE_MASK); - (void)jit_bnei_i(refslow, JIT_R2, SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER); - } else { - (void)jit_bmci_i(refslow, JIT_R2, ((kind == 1) - ? SCHEME_PRIM_IS_STRUCT_PRED - : SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER)); - } + jit_andi_i(JIT_R2, JIT_R2, SCHEME_PRIM_OTHER_TYPE_MASK); + (void)jit_bnei_i(refslow, JIT_R2, ((kind == 3) + ? SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER + : ((kind == 1) + ? SCHEME_PRIM_STRUCT_TYPE_PRED + : SCHEME_PRIM_STRUCT_TYPE_INDEXED_GETTER))); CHECK_LIMIT(); /* Check argument: */ if (kind == 1) { diff --git a/src/racket/src/jitinline.c b/src/racket/src/jitinline.c index 55754bfaf3..e0ab079d2f 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -109,15 +109,15 @@ static int check_val_struct_prim(Scheme_Object *p, int arity) { if (p && SCHEME_PRIMP(p)) { if (arity == 1) { - if (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_IS_STRUCT_PRED) - return 1; - else if (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER) - return 2; - else if (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_IS_STRUCT_OTHER) { + if (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_IS_STRUCT_OTHER) { int t = (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_OTHER_TYPE_MASK); - if (t == SCHEME_PRIM_TYPE_STRUCT_PROP_GETTER) + if (t == SCHEME_PRIM_STRUCT_TYPE_PRED) + return 1; + if (t == SCHEME_PRIM_STRUCT_TYPE_INDEXED_GETTER) + return 2; + else if (t == SCHEME_PRIM_TYPE_STRUCT_PROP_GETTER) return 4; - else if (t == SCHEME_PRIM_TYPE_STRUCT_PROP_PRED) + else if (t == SCHEME_PRIM_STRUCT_TYPE_STRUCT_PROP_PRED) return 6; } } else if (arity == 2) { diff --git a/src/racket/src/list.c b/src/racket/src/list.c index be7e3cd2dd..e404edd450 100644 --- a/src/racket/src/list.c +++ b/src/racket/src/list.c @@ -746,11 +746,13 @@ scheme_init_unsafe_list (Scheme_Env *env) scheme_add_global_constant ("unsafe-list-tail", p, env); p = scheme_make_immed_prim(unsafe_mcar, "unsafe-mcar", 1, 1); - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_UNARY_INLINED + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant ("unsafe-mcar", p, env); p = scheme_make_immed_prim(unsafe_mcdr, "unsafe-mcdr", 1, 1); - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_UNARY_INLINED + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant ("unsafe-mcdr", p, env); p = scheme_make_immed_prim(unsafe_set_mcar, "unsafe-set-mcar!", 2, 2); @@ -762,11 +764,13 @@ scheme_init_unsafe_list (Scheme_Env *env) scheme_add_global_constant ("unsafe-set-mcdr!", p, env); p = scheme_make_immed_prim(unsafe_unbox, "unsafe-unbox", 1, 1); - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_UNARY_INLINED + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant("unsafe-unbox", p, env); p = scheme_make_immed_prim(unsafe_unbox_star, "unsafe-unbox*", 1, 1); - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_UNARY_INLINED + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant("unsafe-unbox*", p, env); p = scheme_make_immed_prim(unsafe_set_box, "unsafe-set-box!", 2, 2); diff --git a/src/racket/src/number.c b/src/racket/src/number.c index fb934b182f..368cb0f7e3 100644 --- a/src/racket/src/number.c +++ b/src/racket/src/number.c @@ -864,7 +864,7 @@ void scheme_init_unsafe_number(Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; else SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_SOMETIMES_INLINED; - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_OMITABLE; scheme_add_global_constant("unsafe-f64vector-ref", p, env); p = scheme_make_immed_prim(fl_set, "unsafe-f64vector-set!", @@ -887,7 +887,7 @@ void scheme_init_unsafe_number(Scheme_Env *env) SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; else SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_SOMETIMES_INLINED; - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_OMITABLE; scheme_add_global_constant("unsafe-flvector-ref", p, env); p = scheme_make_immed_prim(unsafe_flvector_set, "unsafe-flvector-set!", @@ -904,7 +904,7 @@ void scheme_init_unsafe_number(Scheme_Env *env) p = scheme_make_immed_prim(unsafe_fxvector_ref, "unsafe-fxvector-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant("unsafe-fxvector-ref", p, env); p = scheme_make_immed_prim(unsafe_fxvector_set, "unsafe-fxvector-set!", @@ -915,7 +915,7 @@ void scheme_init_unsafe_number(Scheme_Env *env) p = scheme_make_immed_prim(s16_ref, "unsafe-s16vector-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_OMITABLE; scheme_add_global_constant("unsafe-s16vector-ref", p, env); p = scheme_make_immed_prim(s16_set, "unsafe-s16vector-set!", @@ -926,7 +926,7 @@ void scheme_init_unsafe_number(Scheme_Env *env) p = scheme_make_immed_prim(u16_ref, "unsafe-u16vector-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED; - SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL; + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNSAFE_OMITABLE; scheme_add_global_constant("unsafe-u16vector-ref", p, env); p = scheme_make_immed_prim(u16_set, "unsafe-u16vector-set!", diff --git a/src/racket/src/optimize.c b/src/racket/src/optimize.c index f46924be71..5fcffdece9 100644 --- a/src/racket/src/optimize.c +++ b/src/racket/src/optimize.c @@ -42,6 +42,8 @@ #define MAX_PROC_INLINE_SIZE 256 +#define SCHEME_PRIM_IS_UNSAFE_NONMUTATING (SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL | SCHEME_PRIM_IS_UNSAFE_OMITABLE) + struct Optimize_Info { MZTAG_IF_REQUIRED @@ -385,7 +387,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved, } } if (SCHEME_PRIMP(app->args[0]) - && (SCHEME_PRIM_PROC_FLAGS(app->args[0]) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL) + && (SCHEME_PRIM_PROC_FLAGS(app->args[0]) & SCHEME_PRIM_IS_UNSAFE_NONMUTATING) && (app->num_args >= ((Scheme_Primitive_Proc *)app->args[0])->mina) && (app->num_args <= ((Scheme_Primitive_Proc *)app->args[0])->mu.maxa)) { note_match(1, vals, warn_info); @@ -421,7 +423,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved, } } if (SCHEME_PRIMP(app->rator) - && (SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL) + && (SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_UNSAFE_NONMUTATING) && (1 >= ((Scheme_Primitive_Proc *)app->rator)->mina) && (1 <= ((Scheme_Primitive_Proc *)app->rator)->mu.maxa)) { note_match(1, vals, warn_info); @@ -465,7 +467,7 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved, } } if (SCHEME_PRIMP(app->rator) - && (SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL) + && (SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_UNSAFE_NONMUTATING) && (2 >= ((Scheme_Primitive_Proc *)app->rator)->mina) && (2 <= ((Scheme_Primitive_Proc *)app->rator)->mu.maxa)) { note_match(1, vals, warn_info); @@ -1337,10 +1339,10 @@ static Scheme_Object *check_app_let_rator(Scheme_Object *app, Scheme_Object *rat return NULL; } -static int purely_functional_primitive(Scheme_Object *rator, int n) +static int is_nonmutating_primitive(Scheme_Object *rator, int n) { if (SCHEME_PRIMP(rator) - && (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL) + && (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNSAFE_NONMUTATING) && (n >= ((Scheme_Primitive_Proc *)rator)->mina) && (n <= ((Scheme_Primitive_Proc *)rator)->mu.maxa)) return 1; @@ -1363,7 +1365,7 @@ int scheme_wants_flonum_arguments(Scheme_Object *rator, int argpos, int rotate_m /* In rotate mode, we really want to know whether any argument wants to be lifted out. */ { if (SCHEME_PRIMP(rator)) { - if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL) { + if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNSAFE_NONMUTATING) { if (IS_NAMED_PRIM(rator, "unsafe-flabs") || IS_NAMED_PRIM(rator, "unsafe-flsqrt") || IS_NAMED_PRIM(rator, "unsafe-fl+") @@ -1424,7 +1426,7 @@ int scheme_wants_flonum_arguments(Scheme_Object *rator, int argpos, int rotate_m static int produces_unboxed(Scheme_Object *rator, int *non_fl_args, int argc, int for_args) { if (SCHEME_PRIMP(rator)) { - if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL) { + if (SCHEME_PRIM_PROC_FLAGS(rator) & SCHEME_PRIM_IS_UNSAFE_NONMUTATING) { if (((argc == 1) && (IS_NAMED_PRIM(rator, "unsafe-flabs") || IS_NAMED_PRIM(rator, "unsafe-flsqrt") @@ -1880,7 +1882,7 @@ static Scheme_Object *finish_optimize_application(Scheme_App_Rec *app, Optimize_ } info->size += 1; - if (!purely_functional_primitive(app->args[0], app->num_args)) + if (!is_nonmutating_primitive(app->args[0], app->num_args)) info->vclock += 1; if (all_vals) { @@ -2027,7 +2029,7 @@ static Scheme_Object *finish_optimize_application2(Scheme_App2_Rec *app, Optimiz return app->rand; } - if (!purely_functional_primitive(app->rator, 1)) + if (!is_nonmutating_primitive(app->rator, 1)) info->vclock += 1; info->preserves_marks = !!(rator_flags & CLOS_PRESERVES_MARKS); @@ -2196,7 +2198,7 @@ static Scheme_Object *finish_optimize_application3(Scheme_App3_Rec *app, Optimiz return le; } - if (!purely_functional_primitive(app->rator, 2)) + if (!is_nonmutating_primitive(app->rator, 2)) info->vclock += 1; /* Check for (call-with-values (lambda () M) N): */ @@ -2272,7 +2274,7 @@ static Scheme_Object *finish_optimize_application3(Scheme_App3_Rec *app, Optimiz /* Ad hoc optimization of (unsafe-fx+ 0), etc. */ if (SCHEME_PRIMP(app->rator) - && (SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL)) { + && (SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_UNSAFE_NONMUTATING)) { int z1, z2; z1 = SAME_OBJ(app->rand1, scheme_make_integer(0)); diff --git a/src/racket/src/print.c b/src/racket/src/print.c index 433de3415b..2445279439 100644 --- a/src/racket/src/print.c +++ b/src/racket/src/print.c @@ -2382,7 +2382,17 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, if (compact || !pp->print_unreadable) cannot_print(pp, notdisplay, obj, ht, compact); else { - if (SCHEME_STRUCT_PROCP(obj)) { + int kind; + if (((Scheme_Primitive_Proc *)(obj))->pp.flags & SCHEME_PRIM_IS_STRUCT_OTHER) + kind = (((Scheme_Primitive_Proc *)(obj))->pp.flags & SCHEME_PRIM_OTHER_TYPE_MASK); + else + kind = -1; + if ((kind == SCHEME_PRIM_STRUCT_TYPE_INDEXLESS_GETTER) + || (kind == SCHEME_PRIM_STRUCT_TYPE_CONSTR) + || (kind == SCHEME_PRIM_STRUCT_TYPE_INDEXLESS_SETTER) + || (kind == SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER) + || (kind == SCHEME_PRIM_STRUCT_TYPE_INDEXED_GETTER) + || (kind == SCHEME_PRIM_STRUCT_TYPE_PRED)) { print_named(obj, "struct-procedure", ((Scheme_Closed_Primitive_Proc *)obj)->name, -1, pp); diff --git a/src/racket/src/struct.c b/src/racket/src/struct.c index 0055ccfb4a..5d330a3822 100644 --- a/src/racket/src/struct.c +++ b/src/racket/src/struct.c @@ -1156,7 +1156,7 @@ static Scheme_Object *make_struct_type_property_from_c(int argc, Scheme_Object * v = scheme_make_folding_prim_closure(prop_pred, 1, a, name, 1, 1, 0); ((Scheme_Closed_Primitive_Proc *)v)->pp.flags |= (SCHEME_PRIM_IS_STRUCT_OTHER - | SCHEME_PRIM_TYPE_STRUCT_PROP_PRED); + | SCHEME_PRIM_STRUCT_TYPE_STRUCT_PROP_PRED); *predout = v; name = MALLOC_N_ATOMIC(char, len + 10); @@ -3035,8 +3035,10 @@ struct_getter_p(int argc, Scheme_Object *argv[]) { Scheme_Object *v = argv[0]; if (SCHEME_CHAPERONEP(v)) v = SCHEME_CHAPERONE_VAL(v); - return ((STRUCT_PROCP(v, SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER) - || STRUCT_mPROCP(v, + return ((STRUCT_mPROCP(v, + SCHEME_PRIM_IS_STRUCT_OTHER | SCHEME_PRIM_OTHER_TYPE_MASK, + SCHEME_PRIM_IS_STRUCT_OTHER | SCHEME_PRIM_STRUCT_TYPE_INDEXED_GETTER) + || STRUCT_mPROCP(v, SCHEME_PRIM_IS_STRUCT_OTHER | SCHEME_PRIM_OTHER_TYPE_MASK, SCHEME_PRIM_IS_STRUCT_OTHER | SCHEME_PRIM_STRUCT_TYPE_INDEXLESS_GETTER)) ? scheme_true : scheme_false); @@ -3047,7 +3049,9 @@ struct_pred_p(int argc, Scheme_Object *argv[]) { Scheme_Object *v = argv[0]; if (SCHEME_CHAPERONEP(v)) v = SCHEME_CHAPERONE_VAL(v); - return (STRUCT_PROCP(v, SCHEME_PRIM_IS_STRUCT_PRED) + return (STRUCT_mPROCP(v, + SCHEME_PRIM_IS_STRUCT_OTHER | SCHEME_PRIM_OTHER_TYPE_MASK, + SCHEME_PRIM_IS_STRUCT_OTHER | SCHEME_PRIM_STRUCT_TYPE_PRED) ? scheme_true : scheme_false); } @@ -3783,7 +3787,7 @@ make_struct_proc(Scheme_Struct_Type *struct_type, 1, a, func_name, 1, 1, 1); - flags |= SCHEME_PRIM_IS_STRUCT_PRED; + flags |= SCHEME_PRIM_STRUCT_TYPE_PRED | SCHEME_PRIM_IS_STRUCT_OTHER; } else { Struct_Proc_Info *i; int need_pos; @@ -3812,7 +3816,7 @@ make_struct_proc(Scheme_Struct_Type *struct_type, if (need_pos) flags |= SCHEME_PRIM_STRUCT_TYPE_INDEXLESS_GETTER | SCHEME_PRIM_IS_STRUCT_OTHER; else - flags |= SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER; + flags |= SCHEME_PRIM_STRUCT_TYPE_INDEXED_GETTER | SCHEME_PRIM_IS_STRUCT_OTHER; /* Cache the accessor only if `struct_info' is used. This avoids keep lots of useless accessors. if (need_pos) struct_type->accessor = p; */ @@ -3838,20 +3842,23 @@ make_struct_proc(Scheme_Struct_Type *struct_type, Scheme_Object *scheme_rename_struct_proc(Scheme_Object *p, Scheme_Object *sym) { if (SCHEME_PRIMP(p)) { - int is_getter = (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER); - int is_setter = (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_IS_STRUCT_INDEXED_GETTER); - - if (is_getter || is_setter) { - const char *func_name; - Struct_Proc_Info *i; - - func_name = scheme_symbol_name(sym); + unsigned short flags = ((Scheme_Primitive_Proc *)p)->pp.flags; + if (flags & SCHEME_PRIM_IS_STRUCT_OTHER) { + int is_getter = ((flags & SCHEME_PRIM_OTHER_TYPE_MASK) == SCHEME_PRIM_STRUCT_TYPE_INDEXED_GETTER); + int is_setter = ((flags & SCHEME_PRIM_OTHER_TYPE_MASK) == SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER); - i = (Struct_Proc_Info *)SCHEME_PRIM_CLOSURE_ELS(p)[0]; - - return make_struct_proc(i->struct_type, (char *)func_name, - is_getter ? SCHEME_GETTER : SCHEME_SETTER, - i->field); + if (is_getter || is_setter) { + const char *func_name; + Struct_Proc_Info *i; + + func_name = scheme_symbol_name(sym); + + i = (Struct_Proc_Info *)SCHEME_PRIM_CLOSURE_ELS(p)[0]; + + return make_struct_proc(i->struct_type, (char *)func_name, + is_getter ? SCHEME_GETTER : SCHEME_SETTER, + i->field); + } } } diff --git a/src/racket/src/vector.c b/src/racket/src/vector.c index f9e3a2312b..db688adc2c 100644 --- a/src/racket/src/vector.c +++ b/src/racket/src/vector.c @@ -176,12 +176,12 @@ scheme_init_unsafe_vector (Scheme_Env *env) p = scheme_make_immed_prim(unsafe_vector_ref, "unsafe-vector-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant("unsafe-vector-ref", p, env); p = scheme_make_immed_prim(unsafe_vector_star_ref, "unsafe-vector*-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant("unsafe-vector*-ref", p, env); p = scheme_make_immed_prim(unsafe_vector_set, "unsafe-vector-set!", 3, 3); @@ -194,12 +194,12 @@ scheme_init_unsafe_vector (Scheme_Env *env) p = scheme_make_immed_prim(unsafe_struct_ref, "unsafe-struct-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant("unsafe-struct-ref", p, env); p = scheme_make_immed_prim(unsafe_struct_star_ref, "unsafe-struct*-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant("unsafe-struct*-ref", p, env); p = scheme_make_immed_prim(unsafe_struct_set, "unsafe-struct-set!", 3, 3); @@ -217,12 +217,12 @@ scheme_init_unsafe_vector (Scheme_Env *env) p = scheme_make_immed_prim(unsafe_string_ref, "unsafe-string-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant("unsafe-string-ref", p, env); p = scheme_make_immed_prim(unsafe_string_set, "unsafe-string-set!", 3, 3); SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_NARY_INLINED; - scheme_add_global_constant("unsafe-string-set!", p, env); + scheme_add_global_constant("unsafe-string-set!", p, env); p = scheme_make_immed_prim(unsafe_bytes_len, "unsafe-bytes-length", 1, 1); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_UNARY_INLINED @@ -231,7 +231,7 @@ scheme_init_unsafe_vector (Scheme_Env *env) p = scheme_make_immed_prim(unsafe_bytes_ref, "unsafe-bytes-ref", 2, 2); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_BINARY_INLINED - | SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL); + | SCHEME_PRIM_IS_UNSAFE_OMITABLE); scheme_add_global_constant("unsafe-bytes-ref", p, env); p = scheme_make_immed_prim(unsafe_bytes_set, "unsafe-bytes-set!", 3, 3); From 2698db08a55e139e39a986f7b351da2ac8442848 Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Mon, 10 Oct 2011 06:45:31 -0600 Subject: [PATCH 362/746] Fixing PR 12271 (cherry picked from commit 354283132d406d9a2a8fbaea1a8fa121ac5d5474) --- collects/tests/web-server/pr/12271.rkt | 16 ++++++++++++++++ collects/xml/private/writer.rkt | 3 +++ collects/xml/private/xexpr.rkt | 8 ++++++-- collects/xml/xml.rkt | 3 +++ 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 collects/tests/web-server/pr/12271.rkt diff --git a/collects/tests/web-server/pr/12271.rkt b/collects/tests/web-server/pr/12271.rkt new file mode 100644 index 0000000000..d3e08c067b --- /dev/null +++ b/collects/tests/web-server/pr/12271.rkt @@ -0,0 +1,16 @@ +#lang racket +(require tests/eli-tester + xml) + +(test + (with-output-to-bytes + (lambda () + (write-xexpr + `(html (head (title "Form with CDATA")) + (body (p "Hello, this is a form") + (p ,(cdata 'cdata-start 'cdata-end "")) + (p ,(p-i 'pis 'pie 'target "instruction")) + (p ,(comment "comment")) + "Something"))))) + => + #"Form with CDATA

Hello, this is a form

Something") diff --git a/collects/xml/private/writer.rkt b/collects/xml/private/writer.rkt index 13339fb427..1abc891e7a 100644 --- a/collects/xml/private/writer.rkt +++ b/collects/xml/private/writer.rkt @@ -169,6 +169,9 @@ escape-table escape-attribute-table lowercase-symbol + write-xml-cdata + write-xml-comment + write-xml-p-i write-xml-element) ;; incr : Nat -> Nat diff --git a/collects/xml/private/xexpr.rkt b/collects/xml/private/xexpr.rkt index e541e9290c..ae0d35bb09 100644 --- a/collects/xml/private/xexpr.rkt +++ b/collects/xml/private/xexpr.rkt @@ -299,5 +299,9 @@ [(valid-char? x) (fprintf out "&#~a;" x)] ; Embedded XML - [(source? x) - (write-xml-element x 0 void out)])) + [(cdata? x) + (write-xml-cdata x 0 void out)] + [(comment? x) + (write-xml-comment x 0 void out)] + [(p-i? x) + (write-xml-p-i x 0 void out)])) diff --git a/collects/xml/xml.rkt b/collects/xml/xml.rkt index e61183b017..d2928312d3 100644 --- a/collects/xml/xml.rkt +++ b/collects/xml/xml.rkt @@ -7,6 +7,9 @@ escape-table escape-attribute-table lowercase-symbol + write-xml-cdata + write-xml-comment + write-xml-p-i write-xml-element) "private/xexpr.rkt" "private/syntax.rkt") From f680811cb6dff24f1ada7f53bcd335c63b870c7b Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Mon, 10 Oct 2011 08:27:34 -0600 Subject: [PATCH 363/746] Fixing breakage from push 23693 (cherry picked from commit b20ffdbe95385f8357db0a4a9ab1b33fe2161a32) --- collects/tests/rackunit/check-test.rkt | 13 ++++--------- collects/tests/rackunit/standalone.rkt | 4 ++-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/collects/tests/rackunit/check-test.rkt b/collects/tests/rackunit/check-test.rkt index 53fe998609..4f994bb426 100644 --- a/collects/tests/rackunit/check-test.rkt +++ b/collects/tests/rackunit/check-test.rkt @@ -310,14 +310,9 @@ ;; Check evaluation contexts (test-case "current-check-around is used by checks" - (check-eq? (parameterize ([current-check-around (lambda (t) 'foo)]) + (let ([x #f]) + (parameterize ([current-check-around (lambda (t) (set! x 'foo))]) (check-eq? 'a 'b)) - 'foo)) - - (test-case - "current-check-handler is used by checks" - (check-eq? (parameterize ([current-check-handler (lambda (e) 'foo)]) - (check-eq? 'a 'b)) - 'foo)) - )) + (check-eq? x + 'foo))))) diff --git a/collects/tests/rackunit/standalone.rkt b/collects/tests/rackunit/standalone.rkt index 4b7f36ef69..00f00f6769 100644 --- a/collects/tests/rackunit/standalone.rkt +++ b/collects/tests/rackunit/standalone.rkt @@ -29,9 +29,9 @@ (test-file "standalone-check-test.rkt" #"Oh HAI!\nI didn't run\n" - #"--------------------\nERROR\nOutta here!\n\n === context ===\nPLTHOME/collects/tests/rackunit/standalone-check-test.rkt:40:12: temp7\nPLTHOME/collects/rackunit/private/check.rkt:122:29\nPLTHOME/collects/racket/private/more-scheme.rkt:209:2: call-handled-body\nPLTHOME/collects/rackunit/private/check.rkt:55:0: top-level-check-around\n\n\n--------------------\n--------------------\nFAILURE\nname: check\nlocation: (# 44 0 1344 17)\nexpression: (check = 1 2)\nparams: (# 1 2)\nmessage: 0.0\n\nCheck failure\n--------------------\n") + #"--------------------\nERROR\nOutta here!\n\n === context ===\nPLTHOME/collects/tests/rackunit/standalone-check-test.rkt:40:12: temp7\nPLTHOME/collects/rackunit/private/check.rkt:122:29\nPLTHOME/collects/racket/private/more-scheme.rkt:209:2: call-handled-body\nPLTHOME/collects/rackunit/private/check.rkt:55:0: top-level-check-around\nPLTHOME/collects/rackunit/private/check.rkt:108:21: core50\n\n\n--------------------\n--------------------\nFAILURE\nname: check\nlocation: (# 44 0 1344 17)\nexpression: (check = 1 2)\nparams: (# 1 2)\nmessage: 0.0\n\nCheck failure\n--------------------\n") (test-file "standalone-test-case-test.rkt" - #"#t\n#t\n" + #"" #"--------------------\nERROR\nFirst Outta here!\n\n === context ===\nPLTHOME/collects/racket/private/more-scheme.rkt:209:2: call-handled-body\n\n\n--------------------\n--------------------\nerror\nERROR\nSecond Outta here!\n\n === context ===\nPLTHOME/collects/racket/private/more-scheme.rkt:209:2: call-handled-body\n\n\n--------------------\n--------------------\nFAILURE\nname: check-eq?\nlocation: (# 19 12 520 15)\nexpression: (check-eq? 1 2)\nactual: 1\nexpected: 2\n\nCheck failure\n--------------------\n--------------------\nfailure\nFAILURE\nname: check-eq?\nlocation: (# 20 21 558 15)\nexpression: (check-eq? 1 2)\nactual: 1\nexpected: 2\n\nCheck failure\n--------------------\n") From 1357a22a9e9b8a63a9208e500fa57b4eaf892286 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 16 Aug 2011 17:10:45 -0400 Subject: [PATCH 364/746] Typoes. (cherry picked from commit 90aa9c9d755c6accb57e54e317f90b7e436728c6) --- src/racket/src/eval.c | 4 ++-- src/racket/src/optimize.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/racket/src/eval.c b/src/racket/src/eval.c index f395266242..9628c90a37 100644 --- a/src/racket/src/eval.c +++ b/src/racket/src/eval.c @@ -98,10 +98,10 @@ lifting (of procedures that close over nothing or only globals). Beware that the resulting bytecode object is a graph, not a tree, due to sharing (potentially cyclic) of closures that are "empty" - but actually refer to other "empty" closures. See "resove.c". + but actually refer to other "empty" closures. See "resolve.c". The fourth pass, "sfs", performs another liveness analysis on stack - slows and inserts operations to clear stack slots as necessary to + slots and inserts operations to clear stack slots as necessary to make execution safe for space. In particular, dead slots need to be cleared before a non-tail call into arbitrary Scheme code. This pass can mutate the result of the "resolve" pass. See "sfs.c". diff --git a/src/racket/src/optimize.c b/src/racket/src/optimize.c index 5fcffdece9..79846dc886 100644 --- a/src/racket/src/optimize.c +++ b/src/racket/src/optimize.c @@ -5052,7 +5052,7 @@ Scheme_Object *scheme_optimize_expr(Scheme_Object *expr, Optimize_Info *info, in } Scheme_Object *scheme_optimize_clone(int dup_ok, Scheme_Object *expr, Optimize_Info *info, int delta, int closure_depth) -/* Past closure_depth, need to reverse optimize to unoptimzed with respect to info; +/* Past closure_depth, need to reverse optimize to unoptimized with respect to info; delta is the amount to skip in info to get to the frame that bound the code. If dup_ok is 1, then the old copy will be dropped, so it's ok to "duplicate" any constant. */ From f108ea88619d31e8aa88b43e8384b8384df6b01a Mon Sep 17 00:00:00 2001 From: Rodolfo Carvalho Date: Sun, 9 Oct 2011 23:02:32 -0300 Subject: [PATCH 365/746] Fix typo in Slideshow documentation (cherry picked from commit a3890f7e3272ef9fa7b44d9f09a6b8acf6a356e0) --- collects/scribblings/slideshow/slides.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/slideshow/slides.scrbl b/collects/scribblings/slideshow/slides.scrbl index 4dd6c4787d..df3f28b14f 100644 --- a/collects/scribblings/slideshow/slides.scrbl +++ b/collects/scribblings/slideshow/slides.scrbl @@ -404,7 +404,7 @@ triggered via the @DFlag{condense} command-line flag.} @defparam[current-font-size n exact-nonnegative-integer?]{ -Parameter that determines he font size used by @racket[t], +Parameter that determines the font size used by @racket[t], @racket[para], etc. The default size is @racket[32].} From 566c36c4f2911d582db8d45a9400752ce4d7faa5 Mon Sep 17 00:00:00 2001 From: Kevin Tew Date: Sat, 8 Oct 2011 12:49:18 -0600 Subject: [PATCH 366/746] pr 12268 fix merge to 5.2 (cherry picked from commit 58b1f8632621b1c5cc67e7dc9fbaa9d07d377377) --- src/racket/src/place.c | 60 ++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/racket/src/place.c b/src/racket/src/place.c index 58bf96eac0..96c10b2bf3 100644 --- a/src/racket/src/place.c +++ b/src/racket/src/place.c @@ -2465,38 +2465,40 @@ static void async_channel_finalize(void *p, void* data) { ch->out = 0; ch->count = 0; - /*release single receiver */ - if (SCHEME_PLACE_OBJECTP(ch->wakeup_signal)) { - int refcount = 0; - Scheme_Place_Object *place_obj; - place_obj = ((Scheme_Place_Object *) ch->wakeup_signal); + if (ch->wakeup_signal) { + /*release single receiver */ + if (SCHEME_PLACE_OBJECTP(ch->wakeup_signal)) { + int refcount = 0; + Scheme_Place_Object *place_obj; + place_obj = ((Scheme_Place_Object *) ch->wakeup_signal); - mzrt_mutex_lock(place_obj->lock); - place_obj->refcount--; - refcount = place_obj->refcount; - mzrt_mutex_unlock(place_obj->lock); - if (!refcount) { - destroy_place_object_locks(place_obj); + mzrt_mutex_lock(place_obj->lock); + place_obj->refcount--; + refcount = place_obj->refcount; + mzrt_mutex_unlock(place_obj->lock); + if (!refcount) { + destroy_place_object_locks(place_obj); + } } - } - /*release multiple receiver */ - else if (SCHEME_VECTORP(ch->wakeup_signal)) { - Scheme_Object *v = ch->wakeup_signal; - int i; - int size = SCHEME_VEC_SIZE(v); - for (i = 0; i < size; i++) { - Scheme_Place_Object *o3; - o3 = (Scheme_Place_Object *)SCHEME_VEC_ELS(v)[i]; - if (o3) { - int refcount = 0; - mzrt_mutex_lock(o3->lock); - SCHEME_VEC_ELS(v)[i] = NULL; - o3->refcount--; - refcount = o3->refcount; - mzrt_mutex_unlock(o3->lock); + /*release multiple receiver */ + else if (SCHEME_VECTORP(ch->wakeup_signal)) { + Scheme_Object *v = ch->wakeup_signal; + int i; + int size = SCHEME_VEC_SIZE(v); + for (i = 0; i < size; i++) { + Scheme_Place_Object *o3; + o3 = (Scheme_Place_Object *)SCHEME_VEC_ELS(v)[i]; + if (o3) { + int refcount = 0; + mzrt_mutex_lock(o3->lock); + SCHEME_VEC_ELS(v)[i] = NULL; + o3->refcount--; + refcount = o3->refcount; + mzrt_mutex_unlock(o3->lock); - if (!refcount) { - destroy_place_object_locks(o3); + if (!refcount) { + destroy_place_object_locks(o3); + } } } } From d586e78e7a99e3e75a194e55786d0ced271f368e Mon Sep 17 00:00:00 2001 From: Kevin Tew Date: Mon, 10 Oct 2011 10:30:03 -0600 Subject: [PATCH 367/746] Fix QNX merge to 5.2 (cherry picked from commit 1a2d425ece257cef5a99c49b70cacb6eb127bed2) --- src/racket/sconfig.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/racket/sconfig.h b/src/racket/sconfig.h index 917ea70455..53ef1e9ca1 100644 --- a/src/racket/sconfig.h +++ b/src/racket/sconfig.h @@ -937,7 +937,10 @@ #if defined(__QNX__) +#if defined(i386) # define SCHEME_PLATFORM_LIBRARY_SUBPATH "i386-qnx" +#endif +# define ASSUME_FIXED_STACK_SIZE # include "uconfig.h" # define SIGSET_IS_SIGNAL @@ -945,11 +948,20 @@ # define USE_FCNTL_O_NONBLOCK -# define ASSUME_FIXED_STACK_SIZE # define FIXED_STACK_SIZE 524288 # define FLAGS_ALREADY_SET +#if defined(i386) +# define MZ_USE_JIT_I386 +# define MZ_JIT_USE_MPROTECT +#endif +#if defined(__x86_64__) +# define MZ_USE_JIT_X86_64 +# define MZ_JIT_USE_MPROTECT +# define MZ_USE_DWARF_LIBUNWIND +#endif + #endif /***************************************************/ From 7a66972313bd41ae6dff2a9c3947101272b033c1 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 10 Oct 2011 12:42:44 -0400 Subject: [PATCH 368/746] Rename "$WHERE1" -> "$BASE". (cherry picked from commit de40798d49762270cecb397fb8af6f08125a3c13) --- .../build/unix-installer/installer-header | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/collects/meta/build/unix-installer/installer-header b/collects/meta/build/unix-installer/installer-header index 7c6e8156b9..59527bb45a 100644 --- a/collects/meta/build/unix-installer/installer-header +++ b/collects/meta/build/unix-installer/installer-header @@ -147,12 +147,12 @@ if test "$unixstyle" = "N"; then fi fi -# WHERE1 can be used with "$WHERE1/$TARGET" to avoid a double slash +# BASE can be used with "$BASE/$TARGET" to avoid a double slash case "$where" in "" ) failwith "internal error (empty \$where)" ;; - "/" ) WHERE1="" ;; + "/" ) BASE="" ;; *"/" ) failwith "internal error (\$where ends in a slash)" ;; - "/"* ) WHERE1="$where" ;; + "/"* ) BASE="$where" ;; * ) failwith "internal error (\$where is not absolute)" ;; esac @@ -169,20 +169,20 @@ fi set_prefix() { where="$1" # default dirs -- mimic configure behavior - bindir="$WHERE1/bin" - collectsdir="$WHERE1/lib/racket/collects" - if test -d "$WHERE1/share"; then docdir="$WHERE1/share/racket/doc" - elif test -d "$WHERE1/doc"; then docdir="$WHERE1/doc/racket" - else docdir="$WHERE1/share/racket/doc" + bindir="$BASE/bin" + collectsdir="$BASE/lib/racket/collects" + if test -d "$BASE/share"; then docdir="$BASE/share/racket/doc" + elif test -d "$BASE/doc"; then docdir="$BASE/doc/racket" + else docdir="$BASE/share/racket/doc" fi - libdir="$WHERE1/lib" - includerktdir="$WHERE1/include/racket" - librktdir="$WHERE1/lib/racket" - mandir="$WHERE1/man" + libdir="$BASE/lib" + includerktdir="$BASE/include/racket" + librktdir="$BASE/lib/racket" + mandir="$BASE/man" # The source tree is always removed -- no point keeping it if it won't work - # if test -d "$WHERE1/share"; then srcdir="$WHERE1/share/racket/src" - # elif test -d "$WHERE1/src"; then srcdir="$WHERE1/src/racket" - # else srcdir="$WHERE1/share/racket/src" + # if test -d "$BASE/share"; then srcdir="$BASE/share/racket/src" + # elif test -d "$BASE/src"; then srcdir="$BASE/src/racket" + # else srcdir="$BASE/share/racket/src" # fi } @@ -208,7 +208,7 @@ read_dir() { read new_dir case "$new_dir" in "/"* ) echo "$new_dir" ;; - * ) echo "$WHERE1/$new_dir" ;; + * ) echo "$BASE/$new_dir" ;; esac } @@ -272,30 +272,30 @@ echo "ok." unpack_installation() { # test that no TARGET exists - if test -d "$WHERE1/$TARGET" || test -f "$WHERE1/$TARGET"; then - echon "\"$WHERE1/$TARGET\" exists, delete? " + if test -d "$BASE/$TARGET" || test -f "$BASE/$TARGET"; then + echon "\"$BASE/$TARGET\" exists, delete? " read yesno case "$yesno" in [yY]*) - echon "Deleting old \"$WHERE1/$TARGET\"... " - "$rm" -rf "$WHERE1/$TARGET" \ - || failwith "could not delete \"$WHERE1/$TARGET\"." + echon "Deleting old \"$BASE/$TARGET\"... " + "$rm" -rf "$BASE/$TARGET" \ + || failwith "could not delete \"$BASE/$TARGET\"." echo "done." ;; - *) failwith "aborting because \"$WHERE1/$TARGET\" exists." ;; + *) failwith "aborting because \"$BASE/$TARGET\" exists." ;; esac fi # unpack - echon "Unpacking into \"$WHERE1/$TARGET\"... " - rm_on_abort="$WHERE1/$TARGET" - "$mkdir" "$WHERE1/$TARGET" + echon "Unpacking into \"$BASE/$TARGET\"... " + rm_on_abort="$BASE/$TARGET" + "$mkdir" "$BASE/$TARGET" "$tail" +"$BINSTARTLINE" "$0" | "$gunzip" -c \ - | { cd "$WHERE1/$TARGET" + | { cd "$BASE/$TARGET" "$tar" xf - || failwith "problems during unpacking of binary archive." } - cd "$WHERE1/$TARGET" + cd "$BASE/$TARGET" test -d "collects" \ - || failwith "unpack failed (could not find \"$WHERE1/$TARGET/collects\")." + || failwith "unpack failed (could not find \"$BASE/$TARGET/collects\")." echo "done." } @@ -346,15 +346,15 @@ if test ! "x$sysdir" = "x"; then echo "Installing links in \"$sysdir/bin\"..." printsep=" " cd "bin" - for x in `cd "$WHERE1/$TARGET/bin"; ls`; do - if test -x "$WHERE1/$TARGET/bin/$x"; then + for x in `cd "$BASE/$TARGET/bin"; ls`; do + if test -x "$BASE/$TARGET/bin/$x"; then echon "${printsep}$x" printsep=", " - link "$WHERE1/$TARGET/bin/$x" "$x" "$sysdir/bin" + link "$BASE/$TARGET/bin/$x" "$x" "$sysdir/bin" fi done echo "" - echo "Done. (see \"$WHERE1/$TARGET/bin\" for other executables)" + echo "Done. (see \"$BASE/$TARGET/bin\" for other executables)" else echo "Skipping \"$sysdir/bin\" (does not exist or not writable)." fi @@ -374,10 +374,10 @@ if test ! "x$sysdir" = "x"; then cd "$mandir" echo "Installing links in \"$sysdir/$mandir\"..." printsep=" " - for x in `cd "$WHERE1/$TARGET/man/man1/"; "$ls"`; do + for x in `cd "$BASE/$TARGET/man/man1/"; "$ls"`; do echon "${printsep}$x" printsep=", " - link "$WHERE1/$TARGET/man/man1/$x" "$x" "$sysdir/$mandir" + link "$BASE/$TARGET/man/man1/$x" "$x" "$sysdir/$mandir" done echo "" echo "Done" @@ -396,7 +396,7 @@ if test ! "x$sysdir" = "x"; then else cd "$libdir" echo "Installing \"$sysdir/$libdir/$TARGET\"." - link "$WHERE1/$TARGET/lib" "$TARGET" "$sysdir/$libdir" + link "$BASE/$TARGET/lib" "$TARGET" "$sysdir/$libdir" fi # include link cd "$sysdir" @@ -413,7 +413,7 @@ if test ! "x$sysdir" = "x"; then else cd "$incdir" echo "Installing \"$sysdir/$incdir/$TARGET\"." - link "$WHERE1/$TARGET/include" "$TARGET" "$sysdir/$incdir" + link "$BASE/$TARGET/include" "$TARGET" "$sysdir/$incdir" fi # doc link cd "$sysdir" @@ -429,7 +429,7 @@ if test ! "x$sysdir" = "x"; then else cd "$docdir" echo "Installing \"$sysdir/$docdir/$TARGET\"." - link "$WHERE1/$TARGET/notes" "$TARGET" "$sysdir/$docdir" + link "$BASE/$TARGET/notes" "$TARGET" "$sysdir/$docdir" fi fi @@ -441,12 +441,12 @@ fi unixstyle_install() { TARGET="$TARGET-tmp-install" -if test -e "$WHERE1/$TARGET"; then - echo "\"$WHERE1/$TARGET\" already exists (needed for the installation)," +if test -e "$BASE/$TARGET"; then + echo "\"$BASE/$TARGET\" already exists (needed for the installation)," echon " ok to remove? " read R case "$R" in - [yY]* ) "$rm" -rf "$WHERE1/$TARGET" ;; + [yY]* ) "$rm" -rf "$BASE/$TARGET" ;; * ) failwith "abort..." ;; esac fi @@ -468,7 +468,7 @@ unpack_installation cd "$where" "$TARGET/bin/racket" "$TARGET/collects/setup/unixstyle-install.rkt" \ - "move" "$WHERE1/$TARGET" "$bindir" "$collectsdir" "$docdir" "$libdir" \ + "move" "$BASE/$TARGET" "$bindir" "$collectsdir" "$docdir" "$libdir" \ "$includerktdir" "$librktdir" "$mandir" \ || failwith "installation failed" From c6c7490bacf6d14b0ab703212ead62ee92e78acd Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 10 Oct 2011 12:44:22 -0400 Subject: [PATCH 369/746] Clearer question about running an existing uninstaller. (cherry picked from commit e9db4df6c35ccceba32853de9a8f83484de1199a) --- collects/meta/build/unix-installer/installer-header | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/meta/build/unix-installer/installer-header b/collects/meta/build/unix-installer/installer-header index 59527bb45a..7dbbaf130f 100644 --- a/collects/meta/build/unix-installer/installer-header +++ b/collects/meta/build/unix-installer/installer-header @@ -454,7 +454,7 @@ fi if test -x "$bindir/racket-uninstall"; then echo "A previous Racket uninstaller is found at" echo " \"$bindir/racket-uninstall\"," - echon " ok to run it? " + echon " should I run it? (default: no) " read R case "$R" in [yY]* ) echon " running uninstaller..." From 4f355fbc6554b78fa6ba3175d7fd412d47d044bf Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Mon, 10 Oct 2011 13:26:30 -0600 Subject: [PATCH 370/746] Fixed error: attempt to divide by (void) when axis bounds' length is a multiple of 1000 Please merge into 5.2 (cherry picked from commit a0e2401cbef7d9745ea6be339457484fcc0f4c6a) --- collects/plot/common/ticks.rkt | 6 +++--- collects/plot/tests/plot2d-tests.rkt | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/collects/plot/common/ticks.rkt b/collects/plot/common/ticks.rkt index c6d8b6634b..b5ed92e69e 100644 --- a/collects/plot/common/ticks.rkt +++ b/collects/plot/common/ticks.rkt @@ -29,9 +29,9 @@ (define e (floor-log10 (- x-max x-min))) (define mag (expt 10 e)) (define step (let ([y (/ (- x-max x-min) mag)]) - (cond [(y . < . 2) (* 1/5 mag)] - [(y . < . 5) (* 1/2 mag)] - [(y . < . 10) mag]))) + (cond [(y . < . 2) (* 1/5 mag)] + [(y . < . 5) (* 1/2 mag)] + [else mag]))) (define start (* (ceiling (/ x-min step)) step)) (define stop (* (floor (/ x-max step)) step)) (define num (+ 1 (round (/ (- stop start) step)))) diff --git a/collects/plot/tests/plot2d-tests.rkt b/collects/plot/tests/plot2d-tests.rkt index 14a6ee42a9..000531b9bc 100644 --- a/collects/plot/tests/plot2d-tests.rkt +++ b/collects/plot/tests/plot2d-tests.rkt @@ -11,6 +11,8 @@ (plot empty #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1) +(time (plot (function values 0 1000))) + (parameterize ([plot-background "black"] [plot-foreground "white"] [plot-background-alpha 1/2] From c2ccac22acc8588855847ef5c93a34de2c6ba58a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 10 Oct 2011 14:18:26 -0600 Subject: [PATCH 371/746] fix argument-error report Merge to 5.2 (cherry picked from commit 6aaa0d44c0b0905d2ff24504a19d77ac749b8ea1) --- collects/racket/place.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/racket/place.rkt b/collects/racket/place.rkt index 16a0bc650d..ec0f3c28b3 100644 --- a/collects/racket/place.rkt +++ b/collects/racket/place.rkt @@ -175,7 +175,7 @@ (unless (or (module-path? module-path) (path? module-path)) (raise-type-error who "module-path or path" module-path)) (unless (symbol? function) - (raise-type-error who "symbol" module-path)) + (raise-type-error who "symbol" function)) (unless (or (not in) (input-port? in)) (raise-type-error who "input-port or #f" in)) (unless (or (not out) (output-port? out)) From ff5b2dd31d124498153c0d901ca07d028627ea49 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 10 Oct 2011 14:45:53 -0600 Subject: [PATCH 372/746] doc clarifications Merge to 5.2 (cherry picked from commit 5724aa1d1b2f30296b134f1ee5de57e8f4737f34) --- collects/scribblings/foreign/cpointer.scrbl | 27 +++++++++++---------- collects/scribblings/reference/places.scrbl | 7 +++--- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/collects/scribblings/foreign/cpointer.scrbl b/collects/scribblings/foreign/cpointer.scrbl index 5c40a00f4d..a6f072944f 100644 --- a/collects/scribblings/foreign/cpointer.scrbl +++ b/collects/scribblings/foreign/cpointer.scrbl @@ -22,20 +22,21 @@ to Racket, and accept only such tagged pointers when going to C. An optional @racket[ptr-type] can be given to be used as the base pointer type, instead of @racket[_pointer]. -By convention, tags are symbols named after the -type they point to. For example, the cpointer @racket[_car] would -be created using @racket['car] as the key. However, any symbol can be -used as the tag. -Pointer tags are checked with @racket[cpointer-has-tag?] and changed -with @racket[cpointer-push-tag!] which means that other tags are -preserved. Specifically, if a base @racket[ptr-type] is given and is -itself a @racket[_cpointer], then the new type will handle pointers -that have the new tag in addition to @racket[ptr-type]'s tag(s). When -the tag is a pair, its first value is used for printing, so the most -recently pushed tag which corresponds to the inheriting type will be -displayed. +Although any value can be used as a tag, by convention the symbol form +of a type name---without a leading underscore---is used as the +tag. For example, a pointer type @racketidfont{_animal} +would normally use @racket['animal] as the key. -@racket[_cpointer/null] is similar to @racket[_cpointer] except that +Pointer tags are checked with @racket[cpointer-has-tag?] and changed +with @racket[cpointer-push-tag!], which means that other tags are +preserved on an existing pointer value. Specifically, if a base +@racket[ptr-type] is given and is itself a @racket[_cpointer], then +the new type will handle pointers that have the new tag in addition to +@racket[ptr-type]'s tag(s). When the tag is a pair, its first value +is used for printing, so the most recently pushed tag which +corresponds to the inheriting type is displayed. + +The @racket[_cpointer/null] function is similar to @racket[_cpointer], except that it tolerates @cpp{NULL} pointers both going to C and back. Note that @cpp{NULL} pointers are represented as @racket[#f] in Racket, so they are not tagged.} diff --git a/collects/scribblings/reference/places.scrbl b/collects/scribblings/reference/places.scrbl index dffbb0d294..87980decf6 100644 --- a/collects/scribblings/reference/places.scrbl +++ b/collects/scribblings/reference/places.scrbl @@ -267,12 +267,13 @@ If any pumping threads were created to connect a non-@tech{file-stream } @defproc[(place-channel-get [pch place-channel?]) place-message-allowed?]{ - Returns a message received on channel @racket[pch]. + Returns a message received on channel @racket[pch], blocking until a + message is available. } -@defproc[(place-channel-put/get [pch place-channel?] [v any/c]) void]{ +@defproc[(place-channel-put/get [pch place-channel?] [v any/c]) any/c]{ Sends an immutable message @racket[v] on channel @racket[pch] and then - waits for a reply message on the same channel. + waits for a message (perhaps a reply) on the same channel. } @defproc[(place-message-allowed? [v any/c]) boolean?]{ From 635a879727ad8434e556ba5b59c0f5b8bfd771af Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 10 Oct 2011 15:38:42 -0600 Subject: [PATCH 373/746] Revert "another attempt to fix the 64-bit Lion hidden-window problem" This reverts commit f6e5468dbb85c2ed48178ac43fb25084430413ef. Merge to 5.2 (cherry picked from commit 9fd11ac92cec38a0497ae155f472ab82cca97a2b) --- collects/mred/private/wx/cocoa/filedialog.rkt | 18 ++++----- collects/mred/private/wx/cocoa/printer-dc.rkt | 9 ++--- collects/mred/private/wx/cocoa/queue.rkt | 40 ++----------------- 3 files changed, 15 insertions(+), 52 deletions(-) diff --git a/collects/mred/private/wx/cocoa/filedialog.rkt b/collects/mred/private/wx/cocoa/filedialog.rkt index 2afb278171..904acd7fbe 100644 --- a/collects/mred/private/wx/cocoa/filedialog.rkt +++ b/collects/mred/private/wx/cocoa/filedialog.rkt @@ -91,16 +91,14 @@ (let ([front (get-front)] [parent (and (version-10.6-or-later?) parent)]) - (call-in-run-loop - (lambda () - (when parent - (tellv ns beginSheetModalForWindow: (send parent get-cocoa-window) - completionHandler: #f)) - (begin0 - (tell #:type _NSInteger ns runModal) - (when parent (tell app endSheet: ns)) - (when front (tellv (send front get-cocoa-window) - makeKeyAndOrderFront: #f)))))))]) + (when parent + (tellv ns beginSheetModalForWindow: (send parent get-cocoa-window) + completionHandler: #f)) + (begin0 + (tell #:type _NSInteger ns runModal) + (when parent (tell app endSheet: ns)) + (when front (tellv (send front get-cocoa-window) + makeKeyAndOrderFront: #f)))))]) (begin0 (if (zero? result) #f diff --git a/collects/mred/private/wx/cocoa/printer-dc.rkt b/collects/mred/private/wx/cocoa/printer-dc.rkt index 10879424c5..2df653c5cc 100644 --- a/collects/mred/private/wx/cocoa/printer-dc.rkt +++ b/collects/mred/private/wx/cocoa/printer-dc.rkt @@ -16,8 +16,7 @@ "bitmap.rkt" "cg.rkt" "utils.rkt" - "types.rkt" - "queue.rkt") + "types.rkt") (provide (protect-out printer-dc% @@ -106,10 +105,8 @@ (if (atomically (let ([front (get-front)]) (begin0 - (call-in-run-loop - (lambda () - (= (tell #:type _NSInteger (tell NSPageLayout pageLayout) runModalWithPrintInfo: print-info) - NSOkButton))) + (= (tell #:type _NSInteger (tell NSPageLayout pageLayout) runModalWithPrintInfo: print-info) + NSOkButton) (when front (tellv (send front get-cocoa-window) makeKeyAndOrderFront: #f))))) (begin diff --git a/collects/mred/private/wx/cocoa/queue.rkt b/collects/mred/private/wx/cocoa/queue.rkt index e455b988af..d0ac5d21a3 100644 --- a/collects/mred/private/wx/cocoa/queue.rkt +++ b/collects/mred/private/wx/cocoa/queue.rkt @@ -21,7 +21,6 @@ set-menu-bar-hooks! set-fixup-window-locations! post-dummy-event - call-in-run-loop try-to-sync-refresh sync-cocoa-events) @@ -31,8 +30,7 @@ queue-event yield) -(import-class NSApplication NSAutoreleasePool NSColor NSProcessInfo NSArray - NSRunLoop) +(import-class NSApplication NSAutoreleasePool NSColor NSProcessInfo NSArray) (import-protocol NSApplicationDelegate) ;; Extreme hackery to hide original arguments from @@ -80,11 +78,7 @@ (queue-file-event (string->path filename))] [-a _void (applicationDidFinishLaunching: [_id notification]) (unless got-file? - (queue-start-empty-event)) - (tellv app stop: self)] - [-a _void (callbackAndStopLoop) - (run-loop-callback) - (tellv app stop: self)] + (queue-start-empty-event))] [-a _BOOL (applicationShouldHandleReopen: [_id app] hasVisibleWindows: [_BOOL has-visible?]) ;; If we have any visible windows, return #t to do the default thing. ;; Otherwise return #f, because we don't want any invisible windows resurrected. @@ -138,34 +132,7 @@ (unless (zero? v) (log-error (format "error from CGDisplayRegisterReconfigurationCallback: ~a" v)))) -;; To make sure that `finishLaunching' is called, call `run' -;; and have `applicationDidFinishLaunching' quit the run loop. -;; This seems to work better than calling `finishLaunching' -;; directly undet 64-bt Lion, where calling just `finishLaunching' -;; somehow doesn't get the start-up AppleEvents. -(tellv app run) - -;; Use `call-in-run-loop' to run something that needs to be -;; within `run', such as a modal-dialog run loop. It starts -;; a `run' with a high-priority callback to run `thunk', and -;; the run loop is stopped immediately after `thunk' returns. -(define (call-in-run-loop thunk) - (define result #f) - (set! run-loop-callback - (lambda () - (set! run-loop-callback void) - (set! result (thunk)))) - (tellv (tell NSRunLoop currentRunLoop) - performSelector: #:type _SEL (selector callbackAndStopLoop) - target: app-delegate - argument: #f - order: #:type _NSUInteger 0 - modes: (tell NSArray - arrayWithObjects: #:type (_vector i _id) (vector NSDefaultRunLoopMode) - count: #:type _NSUInteger 1)) - (tellv app run) - result) -(define run-loop-callback void) +(tellv app finishLaunching) ;; ------------------------------------------------------------ ;; Create an event to post when MzScheme has been sleeping but is @@ -254,6 +221,7 @@ (define kCFSocketReadCallBack 1) +(import-class NSRunLoop) (let* ([rl (tell #:type _CFRunLoopRef (tell NSRunLoop currentRunLoop) getCFRunLoop)] [cfs (CFSocketCreateWithNative (CFAllocatorGetDefault) ready_sock kCFSocketReadCallBack socket_callback sock-context)] From baa0191aff29fab9132f89ed991a19b9ffa9828d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 10 Oct 2011 15:44:44 -0600 Subject: [PATCH 374/746] third attempt to fix 64-bit Lion hidden-window problem After all the previous attempts, the problem seems almost trivial: although Apple documents `NSAnyEventMask' as the constant #xFFFFFFFF, it's actually NSUIntegerMax (and the difference matters in 64-bit mode). Merge to 5.2. (cherry picked from commit dc912ee6def7a6e8b4edc13c230b367761c5c722) --- collects/mred/private/wx/cocoa/const.rkt | 2 -- collects/mred/private/wx/cocoa/queue.rkt | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/mred/private/wx/cocoa/const.rkt b/collects/mred/private/wx/cocoa/const.rkt index d2f99cb325..63e6b8a78f 100644 --- a/collects/mred/private/wx/cocoa/const.rkt +++ b/collects/mred/private/wx/cocoa/const.rkt @@ -16,8 +16,6 @@ (define NSRoundedBezelStyle 1) (define NSRegularSquareBezelStyle 2) -(define NSAnyEventMask #xffffffff) - (define NSLeftMouseDown 1) (define NSLeftMouseUp 2) (define NSRightMouseDown 3) diff --git a/collects/mred/private/wx/cocoa/queue.rkt b/collects/mred/private/wx/cocoa/queue.rkt index d0ac5d21a3..67af3656dd 100644 --- a/collects/mred/private/wx/cocoa/queue.rkt +++ b/collects/mred/private/wx/cocoa/queue.rkt @@ -312,6 +312,8 @@ (custodian-shutdown-all c))))))) (set! was-menu-bar #f))) +(define NSAnyEventMask (sub1 (arithmetic-shift 1 (* 8 (ctype-sizeof _NSUInteger))))) + ;; Call this function only in atomic mode: (define (check-one-event wait? dequeue?) (pre-event-sync wait?) From aeac9e4df57264f695392c9211e25f107c193315 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 11 Oct 2011 06:45:14 -0600 Subject: [PATCH 375/746] add missing GC registration for places Merge to 5.2 (cherry picked from commit 32b5390ad2f5dfe5f7af46b96e33b03e47c20f33) --- collects/tests/racket/place-master-gc.rkt | 5 +++++ src/racket/src/env.c | 1 + src/racket/src/place.c | 1 + 3 files changed, 7 insertions(+) create mode 100644 collects/tests/racket/place-master-gc.rkt diff --git a/collects/tests/racket/place-master-gc.rkt b/collects/tests/racket/place-master-gc.rkt new file mode 100644 index 0000000000..974425f52a --- /dev/null +++ b/collects/tests/racket/place-master-gc.rkt @@ -0,0 +1,5 @@ +#lang racket/base + +;; Try to trigger master GCs: +(for ([i 100000]) + (make-shared-bytes 1024)) diff --git a/src/racket/src/env.c b/src/racket/src/env.c index dfe7a8ba6c..60840f1339 100644 --- a/src/racket/src/env.c +++ b/src/racket/src/env.c @@ -292,6 +292,7 @@ Scheme_Env *scheme_engine_instance_init() #if defined(MZ_PRECISE_GC) && defined(MZ_USE_PLACES) { void *signal_handle; + REGISTER_SO(place_object); place_object = (Scheme_Place_Object*) scheme_make_place_object(); signal_handle = scheme_get_signal_handle(); GC_set_put_external_event_fd(signal_handle); diff --git a/src/racket/src/place.c b/src/racket/src/place.c index 96c10b2bf3..de3f85c5bf 100644 --- a/src/racket/src/place.c +++ b/src/racket/src/place.c @@ -2189,6 +2189,7 @@ static void *place_start_proc_after_stack(void *data_arg, void *stack_base) { channel = place_data->channel; } place_obj = place_data->place_obj; + REGISTER_SO(place_object); place_object = place_obj; place_obj->refcount++; From 6981f40cd6902c4b3fc925aca0d7e48f98e7e4b4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 11 Oct 2011 08:32:42 -0500 Subject: [PATCH 376/746] adjust 2htdp/image library so that it doesn't create arbitrarily large bitmaps when rendering images closes PR 12277 (except I didn't fix the make-bitmap contract) include in 5.2 (cherry picked from commit 10d19bf8d51d24c83e495e957c2a50af265e23a7) --- collects/mrlib/image-core.rkt | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/collects/mrlib/image-core.rkt b/collects/mrlib/image-core.rkt index c151a926ce..214aa6a648 100644 --- a/collects/mrlib/image-core.rkt +++ b/collects/mrlib/image-core.rkt @@ -230,17 +230,21 @@ has been moved out). (get-output-bytes s))] [else default]))]))) -(define (to-bitmap img) - (let* ([bb (send img get-bb)] - [bm (make-bitmap - (inexact->exact (ceiling (bb-right bb))) - (inexact->exact (ceiling (bb-bottom bb))))] - [bdc (new bitmap-dc% [bitmap bm])]) - (send bdc erase) - (render-image img bdc 0 0) - (begin0 - (send bdc get-bitmap) - (send bdc set-bitmap #f)))) +;; these are used when building a bitmap to render the final image +;; they are probably smaller than the allowed maximum, but they are +;; still huge +(define maximum-width 5000) +(define maximum-height 5000) + +(define (to-bitmap img) + (define bb (send img get-bb)) + (define w (min (inexact->exact (ceiling (bb-right bb))) maximum-width)) + (define h (min (inexact->exact (ceiling (bb-bottom bb))) maximum-height)) + (define bm (make-bitmap w h)) + (define bdc (new bitmap-dc% [bitmap bm])) + (render-image img bdc 0 0) + (send bdc set-bitmap #f) + bm) (define-local-member-name set-use-bitmap-cache?! @@ -350,8 +354,8 @@ has been moved out). (define/public (compute-cached-bitmap) (when use-cached-bitmap? (unless cached-bitmap - (set! cached-bitmap (make-bitmap (+ (inexact->exact (round (bb-right bb))) 1) - (+ (inexact->exact (round (bb-bottom bb))) 1))) + (set! cached-bitmap (make-bitmap (min (+ (inexact->exact (round (bb-right bb))) 1) maximum-width) + (min (+ (inexact->exact (round (bb-bottom bb))) 1) maximum-height))) (define bdc (make-object bitmap-dc% cached-bitmap)) (send bdc erase) (render-image this bdc 0 0) @@ -1032,7 +1036,7 @@ the mask bitmap and the original bitmap are all together in a single bytes! (define sth (apply max latitudes)) (define new-w (ceiling (inexact->exact (- east west)))) (define new-h (ceiling (inexact->exact (- sth nrth)))) - + (define new-bm (make-bitmap new-w new-h)) (define bdc (make-object bitmap-dc% new-bm)) (send bdc set-smoothing 'smoothed) From 804408bdae5dc2241054832e6ee450b75059086c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 11 Oct 2011 10:43:37 -0500 Subject: [PATCH 377/746] error message typo include in 5.2 (cherry picked from commit 95e29376fd04c54c9e4a4647fc6e95b73d5c0b21) --- collects/mred/private/mrcontainer.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/mred/private/mrcontainer.rkt b/collects/mred/private/mrcontainer.rkt index d947ba8297..fce9f336ef 100644 --- a/collects/mred/private/mrcontainer.rkt +++ b/collects/mred/private/mrcontainer.rkt @@ -87,7 +87,7 @@ (unless (and (procedure? f) (procedure-arity-includes? f 1)) (raise-type-error (who->name '(method container<%> change-children)) - "procedure or arity 1" + "procedure of arity 1" f)) (send (get-wx-panel) change-children (lambda (kids) From 5e141b087d6aa067891d65d6032600b46bb1bbf6 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 11 Oct 2011 10:44:00 -0500 Subject: [PATCH 378/746] adjust the autosave gui so that closing the window doesn't cause drracket to exit (this only happened on non-mac os x platforms) include in 5.2 (cherry picked from commit 4d00b13ce0f28e876ea87bc4159673c274247f7b) --- collects/framework/private/autosave.rkt | 81 +++++++++++-------------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/collects/framework/private/autosave.rkt b/collects/framework/private/autosave.rkt index f094654390..2fc4e4efaf 100644 --- a/collects/framework/private/autosave.rkt +++ b/collects/framework/private/autosave.rkt @@ -144,16 +144,22 @@ [filtered-table (filter (λ (x) (file-exists? (cadr x))) table)]) (unless (null? filtered-table) - (let* ([f (new final-frame% - (label (string-constant recover-autosave-files-frame-title)))] + (let* ([dlg (new dialog% + (label (string-constant recover-autosave-files-frame-title)))] [t (new text% (auto-wrap #t))] [ec (new editor-canvas% - (parent (send f get-area-container)) + (parent dlg) (editor t) (line-count 2) + (stretchable-height #f) (style '(no-hscroll)))] - [hp (make-object horizontal-panel% (send f get-area-container))] - [vp (make-object vertical-panel% hp)]) + [hp (new horizontal-panel% + [parent dlg] + [stretchable-height #f])] + [vp (new vertical-panel% + [parent hp] + [stretchable-height #f])] + [details-parent (new horizontal-panel% [parent dlg])]) (send vp set-alignment 'right 'center) (make-object grow-box-spacer-pane% hp) (send t insert (string-constant autosave-explanation)) @@ -161,36 +167,24 @@ (send t set-position 0 0) (send t lock #t) - (for-each (add-table-line vp f) filtered-table) + (for-each (add-table-line vp dlg details-parent) filtered-table) (make-object button% (string-constant autosave-done) vp (λ (x y) - (when (send f can-close?) - (send f on-close) - (send f show #f)))) - (send f show #t) - (yield done-semaphore) + (when (send dlg can-close?) + (send dlg on-close) + (send dlg show #f)))) + (send dlg show #t) (void)))))) - (define done-semaphore (make-semaphore 0)) - - (define final-frame% - (class frame:basic% - (define/augment (can-close?) #t) - (define/augment (on-close) - (inner (void) on-close) - (send (group:get-the-frame-group) - remove-frame - this) - (semaphore-post done-semaphore)) - (super-new))) - - ;; add-table-line : (is-a? area-container<%>) (union #f (is-a?/c top-level-window<%>)) - ;; -> (list (union #f string[filename]) string[filename-file-exists?]) - ;; -> void + ;; add-table-line : (is-a? area-container<%>) + ;; (or/c #f (is-a?/c top-level-window<%>)) + ;; (is-a? area-container<%>) + ;; -> (list/c (or/c #f path?) path?) + ;; -> void? ;; adds in a line to the overview table showing this pair of files. - (define (add-table-line area-container parent) + (define (add-table-line area-container dlg show-details-parent) (λ (table-entry) (letrec ([orig-file (car table-entry)] [backup-file (cadr table-entry)] @@ -221,7 +215,7 @@ [details (make-object button% (string-constant autosave-details) hp (λ (x y) - (show-files table-entry)))] + (show-files table-entry show-details-parent dlg)))] [delete (make-object button% (string-constant autosave-delete-button) @@ -235,7 +229,7 @@ (string-constant autosave-recover) hp (λ (recover y) - (let ([filename-result (recover-file parent table-entry)]) + (let ([filename-result (recover-file dlg table-entry)]) (when filename-result (disable-line) (send msg2 set-label (string-constant autosave-recovered!)) @@ -276,23 +270,21 @@ (delete-file autosave-file) #t)))) - ;; show-files : (list (union #f string[filename]) string) -> void - (define (show-files table-entry) + ;; show-files : (list (or/c #f path?) path?) (is-a?/c area-container<%>) (is-a?/c dialog%) -> void + (define (show-files table-entry show-details-parent dlg) (let ([file1 (list-ref table-entry 0)] [file2 (list-ref table-entry 1)]) - (define frame (make-object show-files-frame% - (if file1 - (string-constant autosave-compare-files) - (string-constant autosave-show-autosave)) - #f - (if file1 600 300) - 600)) - (define hp (new horizontal-panel% - (parent (send frame get-area-container)))) + (send dlg begin-container-sequence) + (define had-children? #f) + (send show-details-parent change-children (λ (x) + (set! had-children? (not (null? x))) + '())) (when file1 - (add-file-viewer file1 hp (string-constant autosave-original-label))) - (add-file-viewer file2 hp (string-constant autosave-autosave-label)) - (send frame show #t))) + (add-file-viewer file1 show-details-parent (string-constant autosave-original-label))) + (add-file-viewer file2 show-details-parent (string-constant autosave-autosave-label)) + (send dlg end-container-sequence) + (unless had-children? + (send dlg center)))) ;; add-file-viewer : path? -> void (define (add-file-viewer filename parent label) @@ -305,6 +297,7 @@ #:quote-amp? #f)] [parent vp])) (define ec (make-object editor-canvas% vp t)) + (send ec min-height 400) (send t load-file filename) (send t hide-caret #t) (send t lock #t)) From c760197bd05a8882a38aa2824521271f82859571 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 11 Oct 2011 16:15:40 -0600 Subject: [PATCH 379/746] fix framework doc reference to `set-icon' method Merge to 5.2 (cherry picked from commit f2082e6eeb4a41ad6e1c33416fa4ae59430362a2) --- collects/framework/main.rkt | 4 ++-- collects/scribblings/framework/frame.scrbl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/framework/main.rkt b/collects/framework/main.rkt index 5b23f4795f..383b502783 100644 --- a/collects/framework/main.rkt +++ b/collects/framework/main.rkt @@ -707,10 +707,10 @@ @racket[frame:basic-mixin]. @itemize[ @item{If it is @racket[#f], then its value is ignored.} - @item{If it is a @racket[bitmap%], then the @method[frame% set-icon] is + @item{If it is a @racket[bitmap%], then the @method[top-level-window<%> set-icon] is called with the bitmap, the result of invoking the @racket[bitmap% get-loaded-mask] method, and @racket['both].} - @item{If it is a pair of bitmaps, then the @method[frame% set-icon] + @item{If it is a pair of bitmaps, then the @method[top-level-window<%> set-icon] method is invoked twice, once with each bitmap in the pair. The first bitmap is passed (along with the result of its @racket[bitmap% get-loaded-mask]) and @racket['small], and then the diff --git a/collects/scribblings/framework/frame.scrbl b/collects/scribblings/framework/frame.scrbl index 11c71d5332..f77140e24e 100644 --- a/collects/scribblings/framework/frame.scrbl +++ b/collects/scribblings/framework/frame.scrbl @@ -113,7 +113,7 @@ This mixin calls its @method[window<%> accept-drop-files] with @racket[#t]. - It also calls its @method[frame% set-icon] method according to the current + It also calls its @method[top-level-window<%> set-icon] method according to the current value of @racket[frame:current-icon]. See also @racket[frame:reorder-menus]. From a24c809202cfbd24de37ea197a5f35c81449cffe Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 11 Oct 2011 16:40:54 -0600 Subject: [PATCH 380/746] fix `place-break' on terminated place Merge to 5.2 (cherry picked from commit 0993408c19b5f4d640a381f000f4c31d0b6bffcc) --- src/racket/src/place.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racket/src/place.c b/src/racket/src/place.c index de3f85c5bf..9516e27546 100644 --- a/src/racket/src/place.c +++ b/src/racket/src/place.c @@ -515,7 +515,7 @@ static int do_place_break(Scheme_Place *place) Scheme_Place_Object *place_obj; place_obj = place->place_obj; - { + if (place_obj) { mzrt_mutex_lock(place_obj->lock); place_obj->pbreak = 1; From fa0809eb4d9bc6e339c60b58996368bfb82e67fa Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Wed, 12 Oct 2011 09:36:39 -0400 Subject: [PATCH 381/746] document unexpected mouse event reporting; Closes PR 12278 (cherry picked from commit 8cdbd3285b5acc34df301545df26144159e13b83) --- collects/teachpack/2htdp/scribblings/universe.scrbl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index 31f45bb72a..a3d1f5a4e7 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -442,10 +442,16 @@ All @tech{MouseEvent}s are represented via strings: coordinates may be negative or larger than the (implicitly) specified width and height. - Note: the computer's software doesn't really notice every single movement + @bold{Note 1}: the operating system doesn't really notice every single movement of the mouse (across the mouse pad). Instead it samples the movements and signals most of them.} -} + + @bold{Note 2}: while mouse events are usually reported in the expected + manner, the operating system doesn't necessarily report them in the + expected order. For example, the Windows operating system insists on + signaling a @racket["move"] event immediately after a @racket["button-up"] + event is discovered. Programmers must design the @racket[on-mouse] + handler to handle any possible mouse event at any moment. } @item{ From 61f2ed8ac784d6d175fd6311042e81baa0fe40b2 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 11 Oct 2011 16:32:12 -0500 Subject: [PATCH 382/746] add call to 'test-results' (cherry picked from commit a43973157b82266a97c874a7860dd246601ff5ba) --- collects/redex/examples/cont-mark-transform/all-test.rkt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/collects/redex/examples/cont-mark-transform/all-test.rkt b/collects/redex/examples/cont-mark-transform/all-test.rkt index 56c8966aff..e0188bb4de 100644 --- a/collects/redex/examples/cont-mark-transform/all-test.rkt +++ b/collects/redex/examples/cont-mark-transform/all-test.rkt @@ -2,4 +2,7 @@ (require "TL-semantics-test.rkt" "SL-semantics-test.rkt" - "CMT-test.rkt") + "CMT-test.rkt" + redex/reduction-semantics) + +(test-results) \ No newline at end of file From 8ad66c4b8dff7c52713ea01fb2c5bb599d1b96f8 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 12 Oct 2011 20:45:09 -0500 Subject: [PATCH 383/746] swapped the backwards triangles (cherry picked from commit 770c2d14f807dfd5b1426b18cf5275167e2fce97) --- collects/mrlib/tex-table.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/mrlib/tex-table.rkt b/collects/mrlib/tex-table.rkt index cead332c48..9fde899291 100644 --- a/collects/mrlib/tex-table.rkt +++ b/collects/mrlib/tex-table.rkt @@ -113,13 +113,13 @@ ("otimes" "⊗") ("div" "÷") ("sqcap" "⊓") - ("triangleleft" "▹") + ("triangleright" "▹") ("oslash" "⊘") ("ast" "∗") ("sqcup" "⊔") ("vee" "∨") ("wedge" "∧") - ("triangleright" "◃") + ("triangleleft" "◃") ("odot" "⊙") ("star" "★") ("dagger" "†") From ff34ed4f0a2048b2228876fa6406a5e216b730d2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Oct 2011 05:56:08 -0600 Subject: [PATCH 384/746] fix tab problem in text% Merge to 5.2 (cherry picked from commit 5fb2f56fdffc5646b7858af9fea7eb528a73234a) --- collects/racket/snip/private/snip.rkt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/collects/racket/snip/private/snip.rkt b/collects/racket/snip/private/snip.rkt index 839111f080..908784dc45 100644 --- a/collects/racket/snip/private/snip.rkt +++ b/collects/racket/snip/private/snip.rkt @@ -697,12 +697,12 @@ (send admin get-editor))]) (let-values ([(n tabs tabspace mult) (let-boxes ([n 0] - [space 0] - [units? #f] - [tabs null]) + [space 0] + [units? #f] + [tabs null]) (set-box! tabs (send admin get-tabs n space units?)) (values n - tabs ;; this should be a vector, right? + tabs ;; a list space (if units? 1 @@ -714,12 +714,12 @@ (if (= i n) (let ([base (if (zero? n) 0 - (vector-ref tabs (- n 1)))]) + (list-ref tabs (- n 1)))]) (let ([tabspace (* tabspace mult)]) (+ base (- (->long tabspace) (modulo (->long (- ex base)) (->long tabspace)))))) - (let ([v (vector-ref tabs i)]) + (let ([v (list-ref tabs i)]) (if ((* mult v) . > . ex) (- (* mult v) ex) (loop (add1 i)))))))))) From d02d7aae9787801230c0c67e4790ba19f96d56c7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 13 Oct 2011 06:03:10 -0600 Subject: [PATCH 385/746] add missing test for text% tab fix Merge to 5.2 (cherry picked from commit 6d608e392c301cfcff4529445a74788745ad79cc) --- collects/tests/gracket/wxme.rkt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/collects/tests/gracket/wxme.rkt b/collects/tests/gracket/wxme.rkt index 2315916b51..c8da28eeaa 100644 --- a/collects/tests/gracket/wxme.rkt +++ b/collects/tests/gracket/wxme.rkt @@ -1414,6 +1414,16 @@ (expect (send t paragraph-end-position 3) 9) (expect (send t line-end-position 3) 9)) +;; ---------------------------------------- +;; tabs + +(let ([t1 (new text%)]) + (send t1 set-admin (new test-editor-admin%)) + (send t1 set-tabs '(100 200 300 400 500 600 700 800 900 1000 100) 1 #t) + (send t1 insert "Hello\tWorld") + (send t1 get-extent (box 0) (box 0))) + + ;; ---------------------------------------- (done) From 8031c88b9ce8348318bc6b7b3b44ab14cae1543c Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Thu, 13 Oct 2011 16:16:02 -0600 Subject: [PATCH 386/746] Rename plot3d-animating? -> plot->animating? Combine plot-ps-interactive? and plot-pdf-interactive? into plot-ps/pdf-interactive? Rename plot3d-ambient-light-value -> plot3d-ambient-light Fix off-by-one 2D plot area clipping Add warning to docs about 'fit' disappearing Stop providing 'fit', 'derivative', 'gradient' and 'make-vec' from the 'plot' module Merge into 5.2 (cherry picked from commit 522ba14b9f646403a6978c910d615b37f324a601) --- collects/plot/common/parameters.rkt | 17 ++++----- collects/plot/deprecated.rkt | 13 +------ collects/plot/plot2d/area.rkt | 4 +- collects/plot/plot2d/plot.rkt | 12 ++++-- collects/plot/plot3d/area.rkt | 2 +- collects/plot/plot3d/contour.rkt | 8 ++-- collects/plot/plot3d/isosurface.rkt | 18 ++++----- collects/plot/plot3d/line.rkt | 2 +- collects/plot/plot3d/plot.rkt | 52 +++++++++++++------------- collects/plot/plot3d/surface.rkt | 4 +- collects/plot/scribblings/compat.scrbl | 15 +++++++- collects/plot/scribblings/params.scrbl | 15 ++++---- collects/plot/scribblings/plot2d.scrbl | 2 +- collects/plot/tests/compat-tests.rkt | 40 +++++++++----------- collects/plot/tests/fit-test-1.rkt | 35 ++++++++++------- collects/plot/tests/fit-test-2.rkt | 37 ++++++++++-------- 16 files changed, 144 insertions(+), 132 deletions(-) diff --git a/collects/plot/common/parameters.rkt b/collects/plot/common/parameters.rkt index 45d7c15377..2b0387f854 100644 --- a/collects/plot/common/parameters.rkt +++ b/collects/plot/common/parameters.rkt @@ -20,8 +20,7 @@ (defparam plot-height exact-positive-integer? 400) (defparam plot-new-window? boolean? #f) (defparam plot-jpeg-quality (integer-in 0 100) 100) -(defparam plot-ps-interactive? boolean? #f) -(defparam plot-pdf-interactive? boolean? #f) +(defparam plot-ps/pdf-interactive? boolean? #f) ;; General appearance @@ -46,6 +45,12 @@ (defparam plot-y-label (or/c string? #f) "y axis") (defparam plot-z-label (or/c string? #f) #f) +(defparam plot-animating? boolean? #f) + +(defproc (animated-samples [samples (and/c exact-integer? (>=/c 2))]) (and/c exact-integer? (>=/c 2)) + (cond [(plot-animating?) (max 2 (ceiling (* 1/4 samples)))] + [else samples])) + ;; Lines (defparam line-samples (and/c exact-integer? (>=/c 2)) 500) @@ -148,18 +153,12 @@ ;; General appearance (defparam plot3d-samples (and/c exact-integer? (>=/c 2)) 41) -(defparam plot3d-animating? boolean? #f) (defparam plot3d-angle real? 30) (defparam plot3d-altitude real? 60) -(defparam plot3d-ambient-light-value (real-in 0 1) 2/3) +(defparam plot3d-ambient-light (real-in 0 1) 2/3) (defparam plot3d-diffuse-light? boolean? #t) (defparam plot3d-specular-light? boolean? #t) -(defproc (samples/animating? [samples (and/c exact-integer? (>=/c 2))] - ) (and/c exact-integer? (>=/c 2)) - (cond [(plot3d-animating?) (max 2 (ceiling (* 1/4 samples)))] - [else samples])) - ;; Surfaces (defparam surface-color plot-color/c 0) diff --git a/collects/plot/deprecated.rkt b/collects/plot/deprecated.rkt index 4f050d4c84..5099f52abb 100644 --- a/collects/plot/deprecated.rkt +++ b/collects/plot/deprecated.rkt @@ -11,18 +11,9 @@ "plot3d/surface.rkt" "plot3d/renderer.rkt" "utils.rkt" - "deprecated/renderers.rkt" - ;; Curve fitting - "deprecated/fit.rkt" - ;; Miscellaneous - "deprecated/math.rkt") + "deprecated/renderers.rkt") -(provide mix line contour shade surface - ;; Curve fitting - (rename-out [fit-int fit]) - (struct-out fit-result) - ;; Miscellaneous - make-vec derivative gradient) +(provide mix line contour shade surface) (define (mix . renderers) (deprecation-warning "mix" "list") diff --git a/collects/plot/plot2d/area.rkt b/collects/plot/plot2d/area.rkt index 713c3baa5a..8ed1256b0c 100644 --- a/collects/plot/plot2d/area.rkt +++ b/collects/plot/plot2d/area.rkt @@ -246,8 +246,8 @@ (define/public (start-renderer rx-min rx-max ry-min ry-max) (reset-drawing-params) - (set-clipping-rect (vector (- area-x-min (plot-line-width)) - (- area-y-min (plot-line-width))) + (set-clipping-rect (vector (+ 1/2 (- area-x-min (plot-line-width))) + (+ 1/2 (- area-y-min (plot-line-width)))) (vector (+ area-x-max (plot-line-width)) (+ area-y-max (plot-line-width)))) (clip-to-bounds rx-min rx-max ry-min ry-max)) diff --git a/collects/plot/plot2d/plot.rkt b/collects/plot/plot2d/plot.rkt index 122127eed3..5689886c57 100644 --- a/collects/plot/plot2d/plot.rkt +++ b/collects/plot/plot2d/plot.rkt @@ -131,6 +131,8 @@ (define tick-skip (plot-tick-skip)) (define x-transform (plot-x-transform)) (define y-transform (plot-y-transform)) + (define z-transform (plot-z-transform)) + (define animating? (plot-animating?)) (dc (λ (dc x y) (parameterize ([plot-foreground foreground] @@ -144,7 +146,9 @@ [plot-tick-size tick-size] [plot-tick-skip tick-skip] [plot-x-transform x-transform] - [plot-y-transform y-transform]) + [plot-y-transform y-transform] + [plot-z-transform z-transform] + [plot-animating? animating?]) (plot/dc renderer-tree dc x y width height #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))) @@ -211,10 +215,10 @@ (define dc (case real-kind [(ps) (new post-script-dc% - [interactive (plot-ps-interactive?)] [parent #f] [use-paper-bbox #f] [as-eps #t] - [width width] [height height] [output output])] + [interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f] + [as-eps #t] [width width] [height height] [output output])] [(pdf) (new pdf-dc% - [interactive (plot-pdf-interactive?)] [parent #f] [use-paper-bbox #f] + [interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f] [width width] [height height] [output output])] [(svg) (new svg-dc% [width width] [height height] [output output] [exists 'truncate/replace])])) diff --git a/collects/plot/plot3d/area.rkt b/collects/plot/plot3d/area.rkt index 9803775e26..c000c4c0e7 100644 --- a/collects/plot/plot3d/area.rkt +++ b/collects/plot/plot3d/area.rkt @@ -467,7 +467,7 @@ (* 32 (expt (if (cos-angle . > . 0) cos-angle 0.0) 10))] [else 0.0])) ; ambient lighting - (define amb (plot3d-ambient-light-value)) + (define amb (plot3d-ambient-light)) ; put it all together (values (+ amb (* (- 1 amb) diff)) spec)])) diff --git a/collects/plot/plot3d/contour.rkt b/collects/plot/plot3d/contour.rkt index 5c8bcee125..05ed7646e5 100644 --- a/collects/plot/plot3d/contour.rkt +++ b/collects/plot/plot3d/contour.rkt @@ -21,8 +21,8 @@ (define ((contours3d-render-proc f levels samples colors widths styles alphas label) area) (define-values (x-min x-max y-min y-max z-min z-max) (send area get-bounds)) - (match-define (list xs ys zss) (f x-min x-max (samples/animating? samples) - y-min y-max (samples/animating? samples))) + (match-define (list xs ys zss) (f x-min x-max (animated-samples samples) + y-min y-max (animated-samples samples))) (define zs (cond [(list? levels) levels] [(eq? levels 'auto) (auto-contour-zs z-min z-max)] @@ -91,8 +91,8 @@ contour-colors contour-widths contour-styles alphas label) area) (define-values (x-min x-max y-min y-max z-min z-max) (send area get-bounds)) - (match-define (list xs ys zss) (f x-min x-max (samples/animating? samples) - y-min y-max (samples/animating? samples))) + (match-define (list xs ys zss) (f x-min x-max (animated-samples samples) + y-min y-max (animated-samples samples))) (define contour-zs (cond [(list? levels) levels] diff --git a/collects/plot/plot3d/isosurface.rkt b/collects/plot/plot3d/isosurface.rkt index 923b1988ad..e8b745fd73 100644 --- a/collects/plot/plot3d/isosurface.rkt +++ b/collects/plot/plot3d/isosurface.rkt @@ -25,9 +25,9 @@ area) (define-values (x-min x-max y-min y-max z-min z-max) (send area get-bounds)) (match-define (list xs ys zs dsss) - (f x-min x-max (samples/animating? samples) - y-min y-max (samples/animating? samples) - z-min z-max (samples/animating? samples))) + (f x-min x-max (animated-samples samples) + y-min y-max (animated-samples samples) + z-min z-max (animated-samples samples))) (send area put-alpha alpha) (send area put-brush color 'solid) @@ -98,9 +98,9 @@ area) (define-values (x-min x-max y-min y-max z-min z-max) (send area get-bounds)) (match-define (list xs ys zs dsss) - (f x-min x-max (samples/animating? samples) - y-min y-max (samples/animating? samples) - z-min z-max (samples/animating? samples))) + (f x-min x-max (animated-samples samples) + y-min y-max (animated-samples samples) + z-min z-max (animated-samples samples))) (define-values (fd-min fd-max) (let ([regular-ds (filter regular? (3d-sample->list dsss))]) @@ -189,9 +189,9 @@ (define ((polar3d-render-proc f g samples color line-color line-width line-style alpha label) area) (define-values (x-min x-max y-min y-max z-min z-max) (send area get-bounds)) (match-define (list xs ys zs dsss) - (g x-min x-max (samples/animating? samples) - y-min y-max (samples/animating? samples) - z-min z-max (samples/animating? samples))) + (g x-min x-max (animated-samples samples) + y-min y-max (animated-samples samples) + z-min z-max (animated-samples samples))) (send area put-alpha alpha) (send area put-brush color 'solid) diff --git a/collects/plot/plot3d/line.rkt b/collects/plot/plot3d/line.rkt index 37d7b05beb..e7ced21fc5 100644 --- a/collects/plot/plot3d/line.rkt +++ b/collects/plot/plot3d/line.rkt @@ -65,5 +65,5 @@ [#:alpha alpha (real-in 0 1) (line-alpha)] [#:label label (or/c string? #f) #f] ) renderer3d? - (lines3d-renderer (λ () (sample-parametric f t-min t-max (samples/animating? samples))) + (lines3d-renderer (λ () (sample-parametric f t-min t-max (animated-samples samples))) x-min x-max y-min y-max z-min z-max color width style alpha label)) diff --git a/collects/plot/plot3d/plot.rkt b/collects/plot/plot3d/plot.rkt index 1b0ffb3088..2df82378ea 100644 --- a/collects/plot/plot3d/plot.rkt +++ b/collects/plot/plot3d/plot.rkt @@ -93,11 +93,11 @@ (send area end-plot) (when (and (not (empty? legend-entries)) - (or (not (plot3d-animating?)) + (or (not (plot-animating?)) (not (equal? (plot-legend-anchor) 'center)))) (send area put-legend legend-entries)) - (when (plot3d-animating?) (send area put-angles)) + (when (plot-animating?) (send area put-angles)) (send area restore-drawing-params))))) @@ -154,31 +154,31 @@ (define x-transform (plot-x-transform)) (define y-transform (plot-y-transform)) (define z-transform (plot-z-transform)) + (define animating? (plot-animating?)) (define samples (plot3d-samples)) - (define animating? (plot3d-animating?)) - (define ambient-light-value (plot3d-ambient-light-value)) + (define ambient-light (plot3d-ambient-light)) (define diffuse-light? (plot3d-diffuse-light?)) (define specular-light? (plot3d-specular-light?)) (dc (λ (dc x y) - (parameterize ([plot-foreground foreground] - [plot-background background] - [plot-foreground-alpha foreground-alpha] - [plot-background-alpha background-alpha] - [plot-font-size font-size] - [plot-font-family font-family] - [plot-line-width line-width] - [plot-legend-box-alpha legend-box-alpha] - [plot-tick-size tick-size] - [plot-tick-skip tick-skip] - [plot-x-transform x-transform] - [plot-y-transform y-transform] - [plot-z-transform z-transform] - [plot3d-samples samples] - [plot3d-animating? animating?] - [plot3d-ambient-light-value ambient-light-value] - [plot3d-diffuse-light? diffuse-light?] - [plot3d-specular-light? specular-light?]) + (parameterize ([plot-foreground foreground] + [plot-background background] + [plot-foreground-alpha foreground-alpha] + [plot-background-alpha background-alpha] + [plot-font-size font-size] + [plot-font-family font-family] + [plot-line-width line-width] + [plot-legend-box-alpha legend-box-alpha] + [plot-tick-size tick-size] + [plot-tick-skip tick-skip] + [plot-x-transform x-transform] + [plot-y-transform y-transform] + [plot-z-transform z-transform] + [plot-animating? animating?] + [plot3d-samples samples] + [plot3d-ambient-light ambient-light] + [plot3d-diffuse-light? diffuse-light?] + [plot3d-specular-light? specular-light?]) (plot3d/dc renderer-tree dc x y width height #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max @@ -203,7 +203,7 @@ ) (is-a?/c image-snip%) (make-3d-plot-snip (λ (angle altitude anim?) - (parameterize ([plot3d-animating? (if anim? #t (plot3d-animating?))]) + (parameterize ([plot-animating? (if anim? #t (plot-animating?))]) (plot3d-bitmap renderer-tree #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max @@ -264,10 +264,10 @@ (define dc (case real-kind [(ps) (new post-script-dc% - [interactive (plot-ps-interactive?)] [parent #f] [use-paper-bbox #f] [as-eps #t] - [width width] [height height] [output output])] + [interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f] + [as-eps #t] [width width] [height height] [output output])] [(pdf) (new pdf-dc% - [interactive (plot-pdf-interactive?)] [parent #f] [use-paper-bbox #f] + [interactive (plot-ps/pdf-interactive?)] [parent #f] [use-paper-bbox #f] [width width] [height height] [output output])] [(svg) (new svg-dc% [width width] [height height] [output output] [exists 'truncate/replace])])) diff --git a/collects/plot/plot3d/surface.rkt b/collects/plot/plot3d/surface.rkt index 5e6943ad94..e858f586d0 100644 --- a/collects/plot/plot3d/surface.rkt +++ b/collects/plot/plot3d/surface.rkt @@ -23,8 +23,8 @@ (define ((surface3d-render-proc f samples color style line-color line-width line-style alpha label) area) (define-values (x-min x-max y-min y-max z-min z-max) (send area get-bounds)) - (match-define (list xs ys zss) (f x-min x-max (samples/animating? samples) - y-min y-max (samples/animating? samples))) + (match-define (list xs ys zss) (f x-min x-max (animated-samples samples) + y-min y-max (animated-samples samples))) (send area put-alpha alpha) (send area put-brush color style) diff --git a/collects/plot/scribblings/compat.scrbl b/collects/plot/scribblings/compat.scrbl index 0c37b0686e..8ec712b9da 100644 --- a/collects/plot/scribblings/compat.scrbl +++ b/collects/plot/scribblings/compat.scrbl @@ -129,8 +129,17 @@ Returns @racket[#t] if @racket[v] is one of the following symbols, @section[#:tag "curve-fit"]{Curve Fitting} -The @racketmodname[plot] library uses a non-linear, least-squares fit -algorithm to fit parameterized functions to given data. +@define[fit-warning]{ +@para{ +@bold{Do not use the @(racket fit) function. It is going to be removed in Racket 5.2.1.} +It relies on old C code that nobody understands or is willing to maintain, and that is also slightly crashy. +}} + +@fit-warning + +Quite independent of plotting, and for reasons lost in the sands of time, +the @racketmodname[plot] library provides a non-linear, least-squares +fit algorithm to fit parameterized functions to given data. The code that implements the algorithm is public domain, and is used by the @tt{gnuplot} package. @@ -204,6 +213,8 @@ A more realistic example can be found in (list-of (vector/c real? real? real? real?)))]) fit-result?]{ +@fit-warning + Attempts to fit a @defterm{fittable function} to the data that is given. The @racket[guess-list] should be a set of arguments and values. The more accurate your initial guesses are, the more likely diff --git a/collects/plot/scribblings/params.scrbl b/collects/plot/scribblings/params.scrbl index 687f4e364e..3aaa1ce164 100644 --- a/collects/plot/scribblings/params.scrbl +++ b/collects/plot/scribblings/params.scrbl @@ -27,12 +27,8 @@ before using @(racket plot) or @(racket plot3d).} The quality of JPEG images written by @(racket plot-file) and @(racket plot3d-file). See @(method bitmap% save-file). } -@doc-apply[plot-ps-interactive?]{ -If @(racket #t), @(racket plot-file) and @(racket plot3d-file) open a dialog when writing PostScript files. See @(racket post-script-dc%). -} - -@doc-apply[plot-pdf-interactive?]{ -If @(racket #t), @(racket plot-file) and @(racket plot3d-file) open a dialog when writing PDF files. See @(racket pdf-dc%). +@doc-apply[plot-ps/pdf-interactive?]{ +If @(racket #t), @(racket plot-file) and @(racket plot3d-file) open a dialog when writing PostScript or PDF files. See @(racket post-script-dc%) and @(racket pdf-dc%). } @section{Axis Transforms} @@ -96,6 +92,10 @@ See @(racket ->pen-color) and @(racket ->brush-color) for details on how PLoT in @doc-apply[plot-z-label]{The title and axis labels. A @(racket #f) value means the label is not drawn and takes no space. A @(racket "") value effectively means the label is not drawn, but it takes space. } +@doc-apply[plot-animating?]{ +When @(racket #t), certain renderers draw simplified plots to speed up drawing. PLoT sets it to @(racket #t), for example, when a user is clicking and dragging a 3D plot to rotate it. +} + @section{Lines} @doc-apply[line-samples] @@ -189,10 +189,9 @@ These parameters do not control the @italic{typical} appearance of plots. Instea @section{3D General Appearance} @doc-apply[plot3d-samples] -@doc-apply[plot3d-animating?] @doc-apply[plot3d-angle] @doc-apply[plot3d-altitude] -@doc-apply[plot3d-ambient-light-value] +@doc-apply[plot3d-ambient-light] @doc-apply[plot3d-diffuse-light?] @doc-apply[plot3d-specular-light?] diff --git a/collects/plot/scribblings/plot2d.scrbl b/collects/plot/scribblings/plot2d.scrbl index 6e0dee80b0..9893030dc2 100644 --- a/collects/plot/scribblings/plot2d.scrbl +++ b/collects/plot/scribblings/plot2d.scrbl @@ -62,7 +62,7 @@ Plot to different backends. Each of these procedures has the same keyword argume Use @(racket plot-file) to save a plot to a file. When creating a JPEG file, the parameter @(racket plot-jpeg-quality) determines its quality. -When creating a PostScript or PDF file, the parameters @(racket plot-ps-interactive?) and @(racket plot-pdf-interactive?) determine whether the user is given a dialog for setting printing parameters. +When creating a PostScript or PDF file, the parameter @(racket plot-ps/pdf-interactive?) determines whether the user is given a dialog for setting printing parameters. (See @(racket post-script-dc%) and @(racket pdf-dc%).) When @(racket kind) is @(racket 'auto), @(racket plot-file) tries to determine the kind of file to write from the file name extension. diff --git a/collects/plot/tests/compat-tests.rkt b/collects/plot/tests/compat-tests.rkt index dcf2573f0f..22caf316d1 100644 --- a/collects/plot/tests/compat-tests.rkt +++ b/collects/plot/tests/compat-tests.rkt @@ -1,7 +1,7 @@ #reader(lib"read.ss""wxme")WXME0108 ## #| This file uses the GRacket editor format. - Open this file in DrRacket version 5.1.3.11 or later to read it. + Open this file in DrRacket version 5.2.0.1 or later to read it. Most likely, it was created by saving a program in DrRacket, and it probably contains a program with non-text elements @@ -446,7 +446,7 @@ 255 255 -1 -1 43 1 #"\0" 0 -1 1 #"\0" 1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 1 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 255 -255 255 -1 -1 0 1595 0 26 3 12 #"#lang racket" +255 255 -1 -1 0 1589 0 26 3 12 #"#lang racket" 0 0 4 29 1 #"\n" 0 0 4 29 1 #"\n" 0 0 17 3 1 #"#" @@ -494,6 +494,18 @@ 0 0 4 29 1 #"\n" 0 0 4 29 1 #"\n" 0 0 22 3 1 #"(" +0 0 14 3 7 #"require" +0 0 4 3 1 #" " +0 0 22 3 1 #"(" +0 0 14 3 7 #"only-in" +0 0 4 3 1 #" " +0 0 14 3 11 #"plot/compat" +0 0 4 3 1 #" " +0 0 14 3 8 #"gradient" +0 0 22 3 2 #"))" +0 0 4 29 1 #"\n" +0 0 4 29 1 #"\n" +0 0 22 3 1 #"(" 0 0 15 3 6 #"define" 0 0 4 3 1 #" " 0 0 22 3 1 #"(" @@ -542,8 +554,7 @@ 0 0 4 3 1 #" " 0 0 19 3 1 #"\"" 0 0 19 3 3 #"The" -0 0 19 3 1 #" " -0 0 19 3 37 #"old plot library produced this plot:\"" +0 0 19 3 38 #" old plot library produced this plot:\"" 0 0 22 3 1 #")" 0 0 4 29 1 #"\n" 0 0 4 3 2 #" " @@ -742,21 +753,6 @@ 0 0 22 3 2 #"))" 0 0 4 29 1 #"\n" 0 0 4 3 2 #" " -0 0 22 3 1 #"(" -0 0 15 3 6 #"define" -0 0 4 3 1 #" " -0 0 14 3 8 #"gradient" -0 0 4 3 1 #" " -0 0 22 3 1 #"(" -0 0 14 3 15 #"dynamic-require" -0 0 4 3 1 #" " -0 0 14 3 11 #"module-path" -0 0 4 3 1 #" " -0 0 20 3 1 #"'" -0 0 14 3 8 #"gradient" -0 0 22 3 2 #"))" -0 0 4 29 1 #"\n" -0 0 4 3 2 #" " 0 0 4 29 1 #"\n" 0 0 4 3 2 #" " 0 0 17 3 71 @@ -14292,8 +14288,7 @@ 0 0 4 3 1 #" " 0 0 19 3 1 #"\"" 0 0 19 3 7 #"Testing" -0 0 19 3 1 #" " -0 0 19 3 18 #"plot's #:out-file\"" +0 0 19 3 19 #" plot's #:out-file\"" 0 0 22 3 1 #")" 0 0 4 29 1 #"\n" 0 0 4 3 2 #" " @@ -14349,8 +14344,7 @@ 0 0 4 3 1 #" " 0 0 19 3 1 #"\"" 0 0 19 3 7 #"Testing" -0 0 19 3 1 #" " -0 0 19 3 20 #"plot3d's #:out-file\"" +0 0 19 3 21 #" plot3d's #:out-file\"" 0 0 22 3 1 #")" 0 0 4 29 1 #"\n" 0 0 4 3 2 #" " diff --git a/collects/plot/tests/fit-test-1.rkt b/collects/plot/tests/fit-test-1.rkt index 132e285e8e..9e3f47ed72 100644 --- a/collects/plot/tests/fit-test-1.rkt +++ b/collects/plot/tests/fit-test-1.rkt @@ -1,7 +1,7 @@ #reader(lib"read.ss""wxme")WXME0108 ## #| This file uses the GRacket editor format. - Open this file in DrRacket version 5.1.3.11 or later to read it. + Open this file in DrRacket version 5.2.0.1 or later to read it. Most likely, it was created by saving a program in DrRacket, and it probably contains a program with non-text elements @@ -221,12 +221,15 @@ 0 71 1 #"\0" 1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1.0 1.0 1.0 0 100 0 0 0 0 -1 -1 0 1 #"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 200 0 0 0 0 0 -1 -1 0 1 -#"\0" 0 75 10 #"Monospace\0" 0.0 10 90 -1 90 -1 3 -1 0 1 0 1 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 255 255 255 1 -1 0 1 #"\0" +0 -1 1 #"\0" +1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0.0 0.0 0.0 1.0 1.0 1.0 200 0 0 0 0 +0 -1 -1 4 1 #"\0" +0 -1 1 #"\0" +1.0 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 1 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 255 +255 0 -1 -1 0 1 #"\0" 0 75 1 #"\0" 0.0 11 90 -1 90 -1 3 -1 0 1 0 1 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 255 255 255 1 -1 0 1 #"\0" @@ -356,7 +359,7 @@ #"macro-debugger/syntax-browser/properties color-text% basic\0" 0 70 1 #"\0" 1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1.0 1.0 1.0 1.0 1.0 1.0 0 0 0 0 0 0 --1 -1 98 1 #"\0" +-1 -1 99 1 #"\0" 0 -1 1 #"\0" 1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0.0 0.0 0.0 1.0 1.0 1.0 190 190 190 0 0 0 -1 -1 4 1 #"\0" @@ -443,10 +446,7 @@ 255 255 -1 -1 43 1 #"\0" 0 -1 1 #"\0" 1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 1 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 255 -255 255 -1 -1 4 1 #"\0" -0 -1 1 #"\0" -1.0 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 1 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 255 -255 0 -1 -1 0 250 0 26 3 12 #"#lang racket" +255 255 -1 -1 0 259 0 26 3 12 #"#lang racket" 0 0 4 29 1 #"\n" 0 0 4 29 1 #"\n" 0 0 17 3 81 @@ -457,9 +457,19 @@ 0 0 4 29 1 #"\n" 0 0 22 3 1 #"(" 0 0 14 3 7 #"require" -0 0 17 3 1 #" " +0 0 4 3 1 #" " 0 0 14 3 4 #"plot" -0 0 22 3 1 #")" +0 0 4 29 1 #"\n" +0 0 4 3 9 #" " +0 0 22 3 1 #"(" +0 0 14 3 7 #"only-in" +0 0 4 3 1 #" " +0 0 14 3 11 #"plot/compat" +0 0 4 3 1 #" " +0 0 14 3 3 #"fit" +0 0 4 3 1 #" " +0 0 14 3 23 #"fit-result-final-params" +0 0 22 3 2 #"))" 0 0 4 29 1 #"\n" 0 0 4 29 1 #"\n" 0 0 22 3 1 #"(" @@ -622,8 +632,7 @@ 0 0 14 3 9 #"displayln" 0 0 4 3 1 #" " 0 0 19 3 1 #"\"" -0 0 19 3 4 #"The " -0 0 19 3 37 #"old plot library produced this plot:\"" +0 0 19 3 41 #"The old plot library produced this plot:\"" 0 0 22 3 1 #")" 0 0 4 29 1 #"\n" 0 2 41 4 1 #"\0" diff --git a/collects/plot/tests/fit-test-2.rkt b/collects/plot/tests/fit-test-2.rkt index fd8b256223..bad31fed8e 100644 --- a/collects/plot/tests/fit-test-2.rkt +++ b/collects/plot/tests/fit-test-2.rkt @@ -1,7 +1,7 @@ #reader(lib"read.ss""wxme")WXME0108 ## #| This file uses the GRacket editor format. - Open this file in DrRacket version 5.1.3.12 or later to read it. + Open this file in DrRacket version 5.2.0.1 or later to read it. Most likely, it was created by saving a program in DrRacket, and it probably contains a program with non-text elements @@ -446,7 +446,7 @@ 255 255 -1 -1 43 1 #"\0" 0 -1 1 #"\0" 1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 1 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 255 -255 255 -1 -1 0 748 0 26 3 12 #"#lang racket" +255 255 -1 -1 0 753 0 26 3 12 #"#lang racket" 0 0 4 29 1 #"\n" 0 0 4 29 1 #"\n" 0 0 17 3 81 @@ -461,7 +461,19 @@ 0 0 14 3 4 #"plot" 0 0 4 3 1 #" " 0 0 14 3 8 #"rackunit" -0 0 22 3 1 #")" +0 0 4 29 1 #"\n" +0 0 4 3 9 #" " +0 0 22 3 1 #"(" +0 0 14 3 7 #"only-in" +0 0 4 3 1 #" " +0 0 14 3 11 #"plot/compat" +0 0 4 3 1 #" " +0 0 14 3 3 #"fit" +0 0 4 3 1 #" " +0 0 14 3 19 #"fit-result-function" +0 0 4 3 1 #" " +0 0 14 3 23 #"fit-result-final-params" +0 0 22 3 2 #"))" 0 0 4 29 1 #"\n" 0 0 4 29 1 #"\n" 0 0 17 3 45 #";; This is data from the Cavendish experiment" @@ -1416,8 +1428,7 @@ 0 0 4 3 1 #" " 0 0 19 3 1 #"\"" 0 0 19 3 3 #"The" -0 0 19 3 1 #" " -0 0 19 3 32 #"old library produced this plot:\"" +0 0 19 3 33 #" old library produced this plot:\"" 0 0 22 3 1 #")" 0 0 4 29 1 #"\n" 0 2 83 4 1 #"\0" @@ -2593,38 +2604,32 @@ 0 0 17 3 1 #" " 0 0 17 3 1 #"a" 0 0 17 3 1 #" " -0 0 17 3 4 #"44.5" -0 0 17 3 5 #" 0.5)" +0 0 17 3 9 #"44.5 0.5)" 0 0 4 29 1 #"\n" 0 0 17 3 2 #";(" 0 0 17 3 7 #"check-=" 0 0 17 3 1 #" " 0 0 17 3 3 #"tau" 0 0 17 3 1 #" " -0 0 17 3 4 #"57.5" -0 0 17 3 5 #" 0.5)" +0 0 17 3 9 #"57.5 0.5)" 0 0 4 29 1 #"\n" 0 0 17 3 2 #";(" 0 0 17 3 7 #"check-=" 0 0 17 3 1 #" " 0 0 17 3 3 #"phi" 0 0 17 3 1 #" " -0 0 17 3 5 #"-0.38" -0 0 17 3 6 #" 0.05)" +0 0 17 3 11 #"-0.38 0.05)" 0 0 4 29 1 #"\n" 0 0 17 3 2 #";(" 0 0 17 3 7 #"check-=" 0 0 17 3 1 #" " 0 0 17 3 1 #"T" 0 0 17 3 1 #" " -0 0 17 3 4 #"13.1" -0 0 17 3 5 #" 0.5)" +0 0 17 3 9 #"13.1 0.5)" 0 0 4 29 1 #"\n" 0 0 17 3 2 #";(" 0 0 17 3 7 #"check-=" 0 0 17 3 1 #" " -0 0 17 3 6 #"theta0" -0 0 17 3 1 #" " -0 0 17 3 8 #"2.5 0.5)" +0 0 17 3 15 #"theta0 2.5 0.5)" 0 0 4 29 1 #"\n" 0 0 From 9465805f50a665b7f369d500ea38dbb3d3c2977b Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Fri, 14 Oct 2011 22:04:59 -0600 Subject: [PATCH 387/746] Fixed x/y mixup in 'axes' Removed 'plot-tick-skip' parameter Merge into 5.2 (cherry picked from commit 7270c27141d017a4d3edd19231489a780a111348) --- collects/plot/common/parameters.rkt | 1 - collects/plot/common/ticks.rkt | 2 +- collects/plot/plot2d/decoration.rkt | 4 ++-- collects/plot/plot2d/plot.rkt | 2 -- collects/plot/plot3d/plot.rkt | 2 -- collects/plot/scribblings/params.scrbl | 1 - collects/plot/tests/plot2d-tests.rkt | 2 ++ 7 files changed, 5 insertions(+), 9 deletions(-) diff --git a/collects/plot/common/parameters.rkt b/collects/plot/common/parameters.rkt index 2b0387f854..dbb8d5ce70 100644 --- a/collects/plot/common/parameters.rkt +++ b/collects/plot/common/parameters.rkt @@ -38,7 +38,6 @@ (defparam plot-legend-box-alpha alpha (real-in 0 1) 2/3) (defparam plot-tick-size (>=/c 0) 10) -(defparam plot-tick-skip exact-positive-integer? 2) (defparam plot-title (or/c string? #f) #f) (defparam plot-x-label (or/c string? #f) "x axis") diff --git a/collects/plot/common/ticks.rkt b/collects/plot/common/ticks.rkt index b5ed92e69e..d87c12ba66 100644 --- a/collects/plot/common/ticks.rkt +++ b/collects/plot/common/ticks.rkt @@ -42,7 +42,7 @@ (map tick ps labels majors))) (defproc (default-ticks-fun [x-min real?] [x-max real?]) (listof tick?) - (linear-ticks (plot-tick-skip) x-min x-max)) + (linear-ticks 2 x-min x-max)) (defproc (auto-contour-zs [z-min real?] [z-max real?]) (listof real?) (let* ([zs (map tick-p (default-ticks-fun z-min z-max))] diff --git a/collects/plot/plot2d/decoration.rkt b/collects/plot/plot2d/decoration.rkt index 90bdebd46a..7f2b2335d6 100644 --- a/collects/plot/plot2d/decoration.rkt +++ b/collects/plot/plot2d/decoration.rkt @@ -76,8 +76,8 @@ [#:x-ticks? x-ticks? boolean? (x-axis-ticks?)] [#:y-ticks? y-ticks? boolean? (y-axis-ticks?)] ) (listof renderer2d?) - (list (x-axis x #:ticks? x-ticks?) - (y-axis y #:ticks? y-ticks?))) + (list (x-axis y #:ticks? x-ticks?) + (y-axis x #:ticks? y-ticks?))) ;; =================================================================================================== ;; Polar axes diff --git a/collects/plot/plot2d/plot.rkt b/collects/plot/plot2d/plot.rkt index 5689886c57..9555afbb34 100644 --- a/collects/plot/plot2d/plot.rkt +++ b/collects/plot/plot2d/plot.rkt @@ -128,7 +128,6 @@ (define line-width (plot-line-width)) (define legend-box-alpha (plot-legend-box-alpha)) (define tick-size (plot-tick-size)) - (define tick-skip (plot-tick-skip)) (define x-transform (plot-x-transform)) (define y-transform (plot-y-transform)) (define z-transform (plot-z-transform)) @@ -144,7 +143,6 @@ [plot-line-width line-width] [plot-legend-box-alpha legend-box-alpha] [plot-tick-size tick-size] - [plot-tick-skip tick-skip] [plot-x-transform x-transform] [plot-y-transform y-transform] [plot-z-transform z-transform] diff --git a/collects/plot/plot3d/plot.rkt b/collects/plot/plot3d/plot.rkt index 2df82378ea..97b9b6ded5 100644 --- a/collects/plot/plot3d/plot.rkt +++ b/collects/plot/plot3d/plot.rkt @@ -150,7 +150,6 @@ (define line-width (plot-line-width)) (define legend-box-alpha (plot-legend-box-alpha)) (define tick-size (plot-tick-size)) - (define tick-skip (plot-tick-skip)) (define x-transform (plot-x-transform)) (define y-transform (plot-y-transform)) (define z-transform (plot-z-transform)) @@ -170,7 +169,6 @@ [plot-line-width line-width] [plot-legend-box-alpha legend-box-alpha] [plot-tick-size tick-size] - [plot-tick-skip tick-skip] [plot-x-transform x-transform] [plot-y-transform y-transform] [plot-z-transform z-transform] diff --git a/collects/plot/scribblings/params.scrbl b/collects/plot/scribblings/params.scrbl index 3aaa1ce164..89654e4cbb 100644 --- a/collects/plot/scribblings/params.scrbl +++ b/collects/plot/scribblings/params.scrbl @@ -84,7 +84,6 @@ See @(racket ->pen-color) and @(racket ->brush-color) for details on how PLoT in @doc-apply[plot-legend-box-alpha]{The opacity of the filled rectangle behind the legend entries.} @doc-apply[plot-tick-size]{The length of tick lines, in drawing units.} -@doc-apply[plot-tick-skip]{Controls the spacing between major ticks for renderers that use the default tick function, such as the renderers returned by @(racket function) and @(racket surface3d). With the default value @(racket 2), every other tick is major. A tick at @(racket 0) is always major. Major ticks are thicker and labeled; minor ticks are thinner and unlabeled.} @doc-apply[plot-title] @doc-apply[plot-x-label] diff --git a/collects/plot/tests/plot2d-tests.rkt b/collects/plot/tests/plot2d-tests.rkt index 000531b9bc..9db7b8634a 100644 --- a/collects/plot/tests/plot2d-tests.rkt +++ b/collects/plot/tests/plot2d-tests.rkt @@ -11,6 +11,8 @@ (plot empty #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1) +(plot (list (axes 1 2) (function values -4 4))) + (time (plot (function values 0 1000))) (parameterize ([plot-background "black"] From 67dd5e8c1b93487409e4406ada2146d3533fe82a Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Sat, 15 Oct 2011 14:28:22 +0200 Subject: [PATCH 388/746] Synch German string constants with latest. (cherry picked from commit 2db0791e274650858051a20b75b6d8e80ed34163) --- .../private/german-string-constants.rkt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/collects/string-constants/private/german-string-constants.rkt b/collects/string-constants/private/german-string-constants.rkt index edec0f2aae..3889fa6273 100644 --- a/collects/string-constants/private/german-string-constants.rkt +++ b/collects/string-constants/private/german-string-constants.rkt @@ -1120,9 +1120,13 @@ (exited-successfully "Erfolgreich beendet.") (exited-with-error-code "Beendet mit Fehlercode ~a.") ;; ~a is filled in with a number between 1 and 255 (program-ran-out-of-memory "Dem Programm ist der Speicher ausgegangen.") - (last-stack-frame "letzten Stack-Frame zeigen") - (last-stack-frames "die letzten ~a Stack-Frames zeigen") - (next-stack-frames "die nächsten ~a Stack-Frames zeigen") + + (show-evaluation-terminated-dialog "Den Dialog ‘Auswertung abgebrochen’ zeigen") + (evaluation-terminated-ask "Diesen Dialog das nächste Mal anzeigen?") + + (last-stack-frame "letzten Stack-Frame anzeigen") + (last-stack-frames "die letzten ~a Stack-Frames anzeigen") + (next-stack-frames "die nächsten ~a Stack-Frames anzeigen") ;;; welcoming message in repl (language "Sprache") From ab2d140d7d86844926bd3eca41734bfa85d0b292 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 14 Oct 2011 08:54:46 -0700 Subject: [PATCH 389/746] reader doc fixes Closes PR 11086 (cherry picked from commit e55e0a5e4a94719eb90d09b8a45495e2dad0b76b) --- collects/scribblings/reference/reader.scrbl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/collects/scribblings/reference/reader.scrbl b/collects/scribblings/reference/reader.scrbl index 508d130a8f..0d4171eb8a 100644 --- a/collects/scribblings/reference/reader.scrbl +++ b/collects/scribblings/reference/reader.scrbl @@ -229,13 +229,17 @@ specials with the @litchar{.0} suffix, like @racket[-nan.0] are double-precision, whereas specials with the @litchar{.f} suffix are single-precision. +A @litchar{#} in an @nunterm{inexact} number is the same as +@litchar{0}, but @litchar{#} can be used to suggest +that the digit's actual value is unknown. + @BNF[(list @nunterm{number} @BNF-alt[@nunterm{exact} @nunterm{inexact}]) (list @nunterm{exact} @BNF-alt[@nunterm{exact-integer} @nunterm{exact-rational}] @nunterm{exact-complex}) - (list @nunterm{exact-integer} @BNF-seq[@optional{@nonterm{sign}} @nunterm{digits}]) - (list @nunterm{digits} @kleeneplus{@nunterm{digit}}) + (list @nunterm{exact-integer} @BNF-seq[@optional{@nonterm{sign}} @nunterm{unsigned-integer}]) + (list @nunterm{unsigned-integer} @kleeneplus{@nunterm{digit}}) (list @nunterm{exact-rational} @BNF-seq[@nunterm{exact-integer} @litchar{/} @nunterm{unsigned-integer}]) (list @nunterm{exact-complex} @BNF-seq[@nunterm{exact-rational} @nonterm{sign} @nunterm{exact-rational} @litchar{i}]) (list @nunterm{inexact} @BNF-alt[@nunterm{inexact-real} @@ -263,8 +267,8 @@ single-precision. (list @nonterm{digit@sub{8}} @BNF-alt[@nonterm{digit@sub{2}} @litchar{2} @litchar{3} @litchar{4} @litchar{5} @litchar{6} @litchar{7}]) (list @nonterm{digit@sub{2}} @BNF-alt[@litchar{0} @litchar{1}]) - (list @nonterm{exp-mark@sub{16}} @BNF-alt[@litchar{s} @litchar{d} @litchar{l}]) - (list @nonterm{exp-mark@sub{10}} @BNF-alt[@nonterm{exp-mark@sub{16}} @litchar{e} @litchar{f}]) + (list @nonterm{exp-mark@sub{16}} @BNF-alt[@litchar{s} @litchar{l}]) + (list @nonterm{exp-mark@sub{10}} @BNF-alt[@nonterm{exp-mark@sub{16}} @litchar{d} @litchar{e} @litchar{f}]) (list @nonterm{exp-mark@sub{8}} @nonterm{exp-mark@sub{10}}) (list @nonterm{exp-mark@sub{2}} @nonterm{exp-mark@sub{10}}) (list @nunterm{general-number} @BNF-seq[@optional{@nonterm{exactness}} @nunterm{number}]) From a997bc72fd82ede71bc645ec65c117f2e05be405 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 14 Oct 2011 09:12:35 -0700 Subject: [PATCH 390/746] add cross-ref from reference to guide on places (cherry picked from commit eba0ca2d4dd874903953a742504d753729528965) --- collects/scribblings/reference/places.scrbl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/collects/scribblings/reference/places.scrbl b/collects/scribblings/reference/places.scrbl index 87980decf6..6301370169 100644 --- a/collects/scribblings/reference/places.scrbl +++ b/collects/scribblings/reference/places.scrbl @@ -15,12 +15,7 @@ @; ---------------------------------------------------------------------- -@margin-note{Currently, parallel support for places is enabled - only for Racket 3m (which is the main variant of Racket), and only - by default for Windows, Linux x86/x86_64, and Mac OS X x86/x86_64. To - enable support for other platforms, use @DFlag{enable-places} with - @exec{configure} when building Racket. The @racket[place-enabled?] - function reports whether places run in parallel.} +@guideintro["effective-places"]{places} @note-lib[racket/place] @@ -28,6 +23,13 @@ take advantage of machines with multiple processors, cores, or hardware threads. +@margin-note{Currently, parallel support for places is enabled + only for Racket 3m (which is the main variant of Racket), and only + by default for Windows, Linux x86/x86_64, and Mac OS X x86/x86_64. To + enable support for other platforms, use @DFlag{enable-places} with + @exec{configure} when building Racket. The @racket[place-enabled?] + function reports whether places run in parallel.} + A @deftech{place} is a parallel task that is effectively a separate instance of the Racket virtual machine. Places communicate through @deftech{place channels}, which are endpoints for a two-way buffered From 7ad41cd9dcb34f8de6d12efb4429eac73b35bfe1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 14 Oct 2011 09:12:48 -0700 Subject: [PATCH 391/746] fix docs on reading characters Closes PR 11102 (cherry picked from commit 2a39a098a65997565dbda6a738d35b3886cae6be) --- collects/scribblings/reference/reader.scrbl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/collects/scribblings/reference/reader.scrbl b/collects/scribblings/reference/reader.scrbl index 0d4171eb8a..22dc2fc2e3 100644 --- a/collects/scribblings/reference/reader.scrbl +++ b/collects/scribblings/reference/reader.scrbl @@ -678,10 +678,13 @@ one of the following forms: 3]{@nonterm{digit@sub{8}}}, as in string escapes (see @secref["parse-string"]).} +@;{ + Not implemented: @item{@litchar{#\x}@kleenerange[1 2]{@nonterm{digit@sub{16}}}: Unicode for the hexadecimal number specified by @kleenerange[1 2]{@nonterm{digit@sub{16}}}, as in string escapes (see @secref["parse-string"]).} +} @item{@litchar{#\u}@kleenerange[1 4]{@nonterm{digit@sub{16}}}: like @litchar{#\x}, but with up to four hexadecimal digits.} From 394e62a31e9193fce707fbd9de3040cff8470464 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 15 Oct 2011 07:18:01 -0700 Subject: [PATCH 392/746] add cross-reference between data and read/print descriptions Closes PR 11096 (cherry picked from commit d4f7020cd2c11088530b649fdbee972ab2705f62) --- collects/scribblings/reference/booleans.scrbl | 4 +- collects/scribblings/reference/bytes.scrbl | 2 + collects/scribblings/reference/chars.scrbl | 2 + collects/scribblings/reference/data.scrbl | 6 + collects/scribblings/reference/hashes.scrbl | 3 + collects/scribblings/reference/mz.rkt | 272 +++++++++--------- collects/scribblings/reference/numbers.scrbl | 2 + collects/scribblings/reference/pairs.scrbl | 2 + collects/scribblings/reference/printer.scrbl | 12 +- collects/scribblings/reference/regexps.scrbl | 3 + collects/scribblings/reference/strings.scrbl | 2 + collects/scribblings/reference/vectors.scrbl | 4 + 12 files changed, 175 insertions(+), 139 deletions(-) diff --git a/collects/scribblings/reference/booleans.scrbl b/collects/scribblings/reference/booleans.scrbl index a18c1905d0..25f91ae50e 100644 --- a/collects/scribblings/reference/booleans.scrbl +++ b/collects/scribblings/reference/booleans.scrbl @@ -9,7 +9,9 @@ depend on a boolean value typically treat anything other than @racket[#f] as true. The @racket[#t] value is always @racket[eq?] to itself, and @racket[#f] is always @racket[eq?] to itself. -See also: @racket[and], @racket[or], @racket[andmap], @racket[ormap]. +@see-read-print["boolean" #:print "booleans"]{booleans} + +See also @racket[and], @racket[or], @racket[andmap], and @racket[ormap]. @defproc[(boolean? [v any/c]) boolean?]{ diff --git a/collects/scribblings/reference/bytes.scrbl b/collects/scribblings/reference/bytes.scrbl index a3fae2021c..9eee201572 100644 --- a/collects/scribblings/reference/bytes.scrbl +++ b/collects/scribblings/reference/bytes.scrbl @@ -22,6 +22,8 @@ A byte string can be used as a single-valued sequence (see @secref["sequences"]). The bytes of the string serve as elements of the sequence. See also @racket[in-bytes]. +@see-read-print["string"]{byte strings} + See also: @racket[immutable?]. @; ---------------------------------------- diff --git a/collects/scribblings/reference/chars.scrbl b/collects/scribblings/reference/chars.scrbl index e4c8f211ef..0e183a9bc1 100644 --- a/collects/scribblings/reference/chars.scrbl +++ b/collects/scribblings/reference/chars.scrbl @@ -18,6 +18,8 @@ Two characters are @racket[eqv?] if they correspond to the same scalar value. For each scalar value less than 256, character values that are @racket[eqv?] are also @racket[eq?]. +@see-read-print["character"]{characters} + @; ---------------------------------------- @section{Characters and Scalar Values} diff --git a/collects/scribblings/reference/data.scrbl b/collects/scribblings/reference/data.scrbl index 966bd5633a..2f0b7884b0 100644 --- a/collects/scribblings/reference/data.scrbl +++ b/collects/scribblings/reference/data.scrbl @@ -59,6 +59,8 @@ disappear when placed into a weak box (see @secref["weakbox"]) used as the key in a weak @tech{hash table} (see @secref["hashtables"]), or used as an ephemeron key (see @secref["ephemerons"]). +@see-read-print["symbol"]{symbols} + @defproc[(symbol? [v any/c]) boolean?]{Returns @racket[#t] if @racket[v] is a symbol, @racket[#f] otherwise. @@ -141,6 +143,8 @@ Two keywords are @racket[eq?] if and only if they print the same. Like symbols, keywords are only weakly held by the internal keyword table; see @secref["symbols"] for more information. +@see-read-print["keyword"]{keywords} + @defproc[(keyword? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a keyword, @racket[#f] otherwise.} @@ -178,6 +182,8 @@ for each pair of keywords is the same as using A @deftech{box} is like a single-element vector, normally used as minimal mutable storage. +A literal or printed box starts with @litchar{#&}. @see-read-print["box"]{boxes} + @defproc[(box? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a box, @racket[#f] otherwise.} diff --git a/collects/scribblings/reference/hashes.scrbl b/collects/scribblings/reference/hashes.scrbl index 15c16379ee..e48e9aa399 100644 --- a/collects/scribblings/reference/hashes.scrbl +++ b/collects/scribblings/reference/hashes.scrbl @@ -80,6 +80,9 @@ keys:}} If a key in an @racket[equal?]-based hash table is mutated hash table's behavior for insertion and lookup operations becomes unpredictable. +A literal or printed hash table starts with @litchar{#hash}, +@litchar{#hasheqv}, or +@litchar{#hasheq}. @see-read-print["hashtable"]{hash tables} @defproc[(hash? [v any/c]) boolean?]{ diff --git a/collects/scribblings/reference/mz.rkt b/collects/scribblings/reference/mz.rkt index d2e6cac114..4bacbf193b 100644 --- a/collects/scribblings/reference/mz.rkt +++ b/collects/scribblings/reference/mz.rkt @@ -1,137 +1,145 @@ -(module mz racket/base - (require scribble/struct - scribble/manual - scribble/eval - scribble/decode - racket/contract - "../icons.rkt") - - (provide (all-from-out scribble/manual) - (all-from-out scribble/eval) - (all-from-out racket/contract)) - - (require (for-label racket)) - (provide (for-label (all-from-out racket))) - - (provide mz-examples) - (define mz-eval (make-base-eval)) - (define-syntax mz-examples - (syntax-rules () - [(_ #:eval . rest) - (examples #:eval . rest)] - [(_ . rest) - (examples #:eval mz-eval . rest)])) - - (define AllUnix "Unix and Mac OS X") - (provide AllUnix) - - (provide note-lib) - (define-syntax note-lib - (syntax-rules () - [(_ lib #:use-sources (src ...) . more) - (begin - (declare-exporting lib racket #:use-sources (src ...)) - (defmodule*/no-declare (lib) - (t (make-collect-element - #f null - (lambda (ci) - (collect-put! ci `(racket-extra-lib ,'lib) (racketmodname lib)))) - "The bindings documented in this section are provided by the " - (racketmodname lib) - " and " - (racketmodname racket) - " libraries, but not " (racketmodname racket/base) - "." - . more)))] - [(_ lib . more) - (note-lib lib #:use-sources () . more)])) - - (provide note-init-lib) - (define-syntax note-init-lib - (syntax-rules () - [(_ lib #:use-sources (src ...) . more) - (begin - (declare-exporting lib racket/init #:use-sources (src ...)) - (defmodule*/no-declare (lib) - (t "The bindings documented in this section are provided by the " - (racketmodname lib) - " and " - (racketmodname racket/init) - " libraries, which means that they are available when " - " the Racket executable is started with no command-line arguments." - " They are not provided by " (racketmodname racket/base) - " or " (racketmodname racket) "." - . more)))] - [(_ lib . more) - (note-init-lib lib #:use-sources () . more)])) - - (provide note-lib-only) - (define-syntax note-lib-only - (syntax-rules () - [(_ lib #:use-sources (src ...) . more) - (defmodule lib #:use-sources (src ...) +#lang at-exp racket/base + +(require scribble/struct + scribble/manual + scribble/eval + scribble/decode + racket/contract + "../icons.rkt") + +(provide (all-from-out scribble/manual) + (all-from-out scribble/eval) + (all-from-out racket/contract)) + +(require (for-label racket)) +(provide (for-label (all-from-out racket))) + +(provide mz-examples) +(define mz-eval (make-base-eval)) +(define-syntax mz-examples + (syntax-rules () + [(_ #:eval . rest) + (examples #:eval . rest)] + [(_ . rest) + (examples #:eval mz-eval . rest)])) + +(define AllUnix "Unix and Mac OS X") +(provide AllUnix) + +(provide note-lib) +(define-syntax note-lib + (syntax-rules () + [(_ lib #:use-sources (src ...) . more) + (begin + (declare-exporting lib racket #:use-sources (src ...)) + (defmodule*/no-declare (lib) + (t (make-collect-element + #f null + (lambda (ci) + (collect-put! ci `(racket-extra-lib ,'lib) (racketmodname lib)))) + "The bindings documented in this section are provided by the " + (racketmodname lib) + " and " + (racketmodname racket) + " libraries, but not " (racketmodname racket/base) + "." + . more)))] + [(_ lib . more) + (note-lib lib #:use-sources () . more)])) + +(provide note-init-lib) +(define-syntax note-init-lib + (syntax-rules () + [(_ lib #:use-sources (src ...) . more) + (begin + (declare-exporting lib racket/init #:use-sources (src ...)) + (defmodule*/no-declare (lib) (t "The bindings documented in this section are provided by the " (racketmodname lib) - " library, not " (racketmodname racket/base) - " or " (racketmodname racket) - "." - . more))] - [(_ lib . more) - (note-lib-only lib #:use-sources () . more)])) + " and " + (racketmodname racket/init) + " libraries, which means that they are available when " + " the Racket executable is started with no command-line arguments." + " They are not provided by " (racketmodname racket/base) + " or " (racketmodname racket) "." + . more)))] + [(_ lib . more) + (note-init-lib lib #:use-sources () . more)])) - (define (*exnraise s) - (make-element #f (list s " exception is raised"))) - (define-syntax exnraise - (syntax-rules () - [(_ s) (*exnraise (racket s))])) - (define-syntax Exn - (syntax-rules () - [(_ s) (racket s)])) - (provide exnraise Exn) - - (provide margin-note/ref - refalso moreref Guide guideintro guidealso guidesecref - raco-doc) - - (define (margin-note/ref . s) - (apply margin-note - (decode-content (cons magnify s)))) - - (define (refalso tag . s) - (apply margin-note - (decode-content (append (list magnify (secref tag) " also provides information on ") - s - (list "."))))) - - (define (moreref tag . s) - (apply margin-note - (decode-content (append (list magnify (secref tag) " provides more information on ") - s - (list "."))))) - - (define (guidesecref s) - (secref #:doc '(lib "scribblings/guide/guide.scrbl") s)) - - (define (guideintro tag . s) - (apply margin-note - (decode-content (append (list finger (guidesecref tag) " in " Guide " introduces ") - s - (list "."))))) +(provide note-lib-only) +(define-syntax note-lib-only + (syntax-rules () + [(_ lib #:use-sources (src ...) . more) + (defmodule lib #:use-sources (src ...) + (t "The bindings documented in this section are provided by the " + (racketmodname lib) + " library, not " (racketmodname racket/base) + " or " (racketmodname racket) + "." + . more))] + [(_ lib . more) + (note-lib-only lib #:use-sources () . more)])) - (define (guidealso tag) - (apply margin-note - (decode-content (append (list finger "See also " (guidesecref tag) " in " Guide "."))))) - - (define Guide - (other-manual '(lib "scribblings/guide/guide.scrbl"))) +(define (*exnraise s) + (make-element #f (list s " exception is raised"))) +(define-syntax exnraise + (syntax-rules () + [(_ s) (*exnraise (racket s))])) +(define-syntax Exn + (syntax-rules () + [(_ s) (racket s)])) +(provide exnraise Exn) - (define raco-doc - '(lib "scribblings/raco/raco.scrbl")) - - (provide speed) - (define-syntax speed - (syntax-rules () - [(_ id what) - (t "An " (racket id) " application can provide better performance for " - (elem what) - " iteration when it appears directly in a " (racket for) " clause.")]))) +(provide margin-note/ref + refalso moreref Guide guideintro guidealso guidesecref + raco-doc) + +(define (margin-note/ref . s) + (apply margin-note + (decode-content (cons magnify s)))) + +(define (refalso tag . s) + (apply margin-note + (decode-content (append (list magnify (secref tag) " also provides information on ") + s + (list "."))))) + +(define (moreref tag . s) + (apply margin-note + (decode-content (append (list magnify (secref tag) " provides more information on ") + s + (list "."))))) + +(define (guidesecref s) + (secref #:doc '(lib "scribblings/guide/guide.scrbl") s)) + +(define (guideintro tag . s) + (apply margin-note + (decode-content (append (list finger (guidesecref tag) " in " Guide " introduces ") + s + (list "."))))) + +(define (guidealso tag) + (apply margin-note + (decode-content (append (list finger "See also " (guidesecref tag) " in " Guide "."))))) + +(define Guide + (other-manual '(lib "scribblings/guide/guide.scrbl"))) + +(define raco-doc + '(lib "scribblings/raco/raco.scrbl")) + +(provide see-read-print) +(define (see-read-print tag-part #:print [print-tag-part tag-part] vals) + @elem{See @secref[(string-append "parse-" tag-part)] + for information on @racket[read]ing + @|vals| and @secref[(string-append "print-" print-tag-part)] + for information on @racket[print]ing @|vals|.}) + +(provide speed) +(define-syntax speed + (syntax-rules () + [(_ id what) + (t "An " (racket id) " application can provide better performance for " + (elem what) + " iteration when it appears directly in a " (racket for) " clause.")])) diff --git a/collects/scribblings/reference/numbers.scrbl b/collects/scribblings/reference/numbers.scrbl index 57d9c108ed..a5ac42d59c 100644 --- a/collects/scribblings/reference/numbers.scrbl +++ b/collects/scribblings/reference/numbers.scrbl @@ -87,6 +87,8 @@ exact, and when they are @racket[=] (except for @racket[+nan.0], @racket[+nan.f] @racket[+0.0], @racket[+0.0f0], @racket[-0.0], and @racket[-0.0f0], as noted above). Two numbers are @racket[equal?] when they are @racket[eqv?]. +@see-read-print["number"]{numbers} + @local-table-of-contents[] @; ---------------------------------------- diff --git a/collects/scribblings/reference/pairs.scrbl b/collects/scribblings/reference/pairs.scrbl index 4ccc6386a3..2e677f1d8c 100644 --- a/collects/scribblings/reference/pairs.scrbl +++ b/collects/scribblings/reference/pairs.scrbl @@ -97,6 +97,8 @@ Cyclic data structures can be created using only immutable pairs via and using some number of @racket[cdr]s returns to the starting pair, then the pair is not a list. +@see-read-print["pair" #:print "pairs"]{pairs and lists} + @; ---------------------------------------- @section{Pair Constructors and Selectors} diff --git a/collects/scribblings/reference/printer.scrbl b/collects/scribblings/reference/printer.scrbl index 4a5ec9c927..62009bc9cc 100644 --- a/collects/scribblings/reference/printer.scrbl +++ b/collects/scribblings/reference/printer.scrbl @@ -97,7 +97,7 @@ Symbols @racket[print] the same as they @racket[write], unless @racket[print]ed form is prefixed with @litchar{'}. For the purposes of printing enclosing datatypes, a symbol is @tech{quotable}. -@section{Printing Numbers} +@section[#:tag "print-number"]{Printing Numbers} A @tech{number} prints the same way in @racket[write], @racket[display], and @racket[print] modes. For the purposes of printing enclosing @@ -126,7 +126,7 @@ determined by @racket[numerator] and @racket[denominator]). A negative @tech{exact number} prints with a @litchar{-} prefix on the printed form of the number's exact negation. -@section{Printing Booleans} +@section[#:tag "print-booleans"]{Printing Booleans} The @tech{boolean} constant @racket[#t] prints as @litchar{#true} or @litchar{#t} in all modes (@racket[display], @racket[write], and @racket[print]), @@ -219,7 +219,7 @@ always @tech{quotable}, a pair is @tech{quotable} when its @racket[car] and @racket[cdr] are @tech{quotable}, and a mutable list is never @tech{quotable}. -@section{Printing Strings} +@section[#:tag "print-string"]{Printing Strings} All @tech{strings} @racket[display] as their literal character sequences. @@ -419,7 +419,7 @@ When the @racket[print-box] parameter is set to @racket[#f], a box prints as @litchar{#} and counts as @tech{quotable}. -@section{Printing Characters} +@section[#:tag "print-character"]{Printing Characters} @tech{Characters} with the special names described in @secref["parse-character"] @racket[write] and @racket[print] using the @@ -439,7 +439,7 @@ For the purposes of printing enclosing datatypes, a character is @tech{quotable}. -@section{Printing Keywords} +@section[#:tag "print-keyword"]{Printing Keywords} @tech{Keywords} @racket[write], @racket[print], and @racket[display] the same as symbols (see @secref["print-symbol"]) except with a leading @@ -452,7 +452,7 @@ For the purposes of printing enclosing datatypes, a keyword is @tech{quotable}. -@section{Printing Regular Expressions} +@section[#:tag "print-regexp"]{Printing Regular Expressions} @tech{Regexp values} @racket[write], @racket[display], and @racket[print] starting with @litchar{#px} (for @racket[pregexp]-based regexps) or diff --git a/collects/scribblings/reference/regexps.scrbl b/collects/scribblings/reference/regexps.scrbl index c810e9858e..ed00b16b5d 100644 --- a/collects/scribblings/reference/regexps.scrbl +++ b/collects/scribblings/reference/regexps.scrbl @@ -54,6 +54,9 @@ compatible with Perl. In addition, Racket constants written with @litchar{#rx} or @litchar{#px} (see @secref["reader"]) produce compiled regexp values. +A literal or printed regular expression starts with @litchar{#rx} or +@litchar{#px}. @see-read-print["regexp"]{regular expressions} + The internal size of a regexp value is limited to 32 kilobytes; this limit roughly corresponds to a source string with 32,000 literal characters or 5,000 operators. diff --git a/collects/scribblings/reference/strings.scrbl b/collects/scribblings/reference/strings.scrbl index 2a88811bfd..1cd62544da 100644 --- a/collects/scribblings/reference/strings.scrbl +++ b/collects/scribblings/reference/strings.scrbl @@ -22,6 +22,8 @@ A string can be used as a single-valued sequence (see @secref["sequences"]). The characters of the string serve as elements of the sequence. See also @racket[in-string]. +@see-read-print["string"]{strings} + See also: @racket[immutable?], @racket[symbol->string], @racket[bytes->string/utf-8]. diff --git a/collects/scribblings/reference/vectors.scrbl b/collects/scribblings/reference/vectors.scrbl index 6dae2282a4..e2e21b5664 100644 --- a/collects/scribblings/reference/vectors.scrbl +++ b/collects/scribblings/reference/vectors.scrbl @@ -22,6 +22,10 @@ A vector can be used as a single-valued sequence (see @secref["sequences"]). The elements of the vector serve as elements of the sequence. See also @racket[in-vector]. +A literal or printed vector starts with @litchar{#(}, optionally with +a number between the @litchar{#} and +@litchar{(}. @see-read-print["vector" #:print "vectors"]{vectors} + @defproc[(vector? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a vector, @racket[#f] otherwise.} From 38c55dc0635211d2fa3dbbda3aa16648a893cf8c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 15 Oct 2011 13:59:26 -0500 Subject: [PATCH 393/746] fix the error check closes PR 12290 (cherry picked from commit 9ab6a93127f079f9d9380e16568e7e65e4bcc11e) --- collects/redex/private/reduction-semantics.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/redex/private/reduction-semantics.rkt b/collects/redex/private/reduction-semantics.rkt index 15377870c0..182dbdd85d 100644 --- a/collects/redex/private/reduction-semantics.rkt +++ b/collects/redex/private/reduction-semantics.rkt @@ -1757,7 +1757,7 @@ (for-each (λ (x) (syntax-case x () - [(stuff ...) (void)] + [(stuff stuff2 ...) (void)] [x (raise-syntax-error syn-error-name "expected a clause" stx #'x)])) (syntax->list #'(x ...))) (raise-syntax-error syn-error-name "error checking failed.2" stx))])) From b655a344180ae49d05142b7764701a802574c581 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sat, 8 Oct 2011 01:07:08 -0600 Subject: [PATCH 394/746] rackunit: fix tests merge to 5.2 (cherry picked from commit 18b3899e6aac5a6d39507e8b2b549f05b4eec0ca) --- collects/tests/rackunit/check-test.rkt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/collects/tests/rackunit/check-test.rkt b/collects/tests/rackunit/check-test.rkt index 4f994bb426..4952d7570c 100644 --- a/collects/tests/rackunit/check-test.rkt +++ b/collects/tests/rackunit/check-test.rkt @@ -314,5 +314,12 @@ (parameterize ([current-check-around (lambda (t) (set! x 'foo))]) (check-eq? 'a 'b)) (check-eq? x - 'foo))))) + 'foo))) + (test-case + "current-check-handler is used by checks" + (check-eq? (let/ec escape + (parameterize ([current-check-handler (lambda (e) (escape 'foo))]) + (check-eq? 'a 'b))) + 'foo)) + )) From cafe0d95358527a575e4590f6f3c046008954620 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sat, 8 Oct 2011 01:21:54 -0600 Subject: [PATCH 395/746] rackunit: fixed test merge to 5.2 (cherry picked from commit 1695d73f5b427a0ced3dbf314bdbded48be4c955) --- collects/tests/rackunit/standalone.rkt | 57 ++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/collects/tests/rackunit/standalone.rkt b/collects/tests/rackunit/standalone.rkt index 00f00f6769..5c096a2266 100644 --- a/collects/tests/rackunit/standalone.rkt +++ b/collects/tests/rackunit/standalone.rkt @@ -8,12 +8,14 @@ (normalize-path (build-path here ".." ".."))) (define (collect-trim bs) (regexp-replace* (regexp-quote (path->bytes collects)) bs #"PLTHOME/collects")) - + (define (require&catch path) (define out-bs (open-output-bytes)) (define err-bs (open-output-bytes)) (parameterize ([current-output-port out-bs] - [current-error-port err-bs]) + [current-error-port err-bs] + ;; Don't test context output; it's too fragile. + [error-print-context-length 0]) (dynamic-require path #f)) (close-output-port out-bs) (close-output-port err-bs) @@ -29,9 +31,56 @@ (test-file "standalone-check-test.rkt" #"Oh HAI!\nI didn't run\n" - #"--------------------\nERROR\nOutta here!\n\n === context ===\nPLTHOME/collects/tests/rackunit/standalone-check-test.rkt:40:12: temp7\nPLTHOME/collects/rackunit/private/check.rkt:122:29\nPLTHOME/collects/racket/private/more-scheme.rkt:209:2: call-handled-body\nPLTHOME/collects/rackunit/private/check.rkt:55:0: top-level-check-around\nPLTHOME/collects/rackunit/private/check.rkt:108:21: core50\n\n\n--------------------\n--------------------\nFAILURE\nname: check\nlocation: (# 44 0 1344 17)\nexpression: (check = 1 2)\nparams: (# 1 2)\nmessage: 0.0\n\nCheck failure\n--------------------\n") + #"\ +-------------------- +ERROR +Outta here! + +-------------------- +-------------------- +FAILURE +name: check +location: (# 44 0 1344 17) +expression: (check = 1 2) +params: (# 1 2)\nmessage: 0.0 + +Check failure +-------------------- +") (test-file "standalone-test-case-test.rkt" #"" - #"--------------------\nERROR\nFirst Outta here!\n\n === context ===\nPLTHOME/collects/racket/private/more-scheme.rkt:209:2: call-handled-body\n\n\n--------------------\n--------------------\nerror\nERROR\nSecond Outta here!\n\n === context ===\nPLTHOME/collects/racket/private/more-scheme.rkt:209:2: call-handled-body\n\n\n--------------------\n--------------------\nFAILURE\nname: check-eq?\nlocation: (# 19 12 520 15)\nexpression: (check-eq? 1 2)\nactual: 1\nexpected: 2\n\nCheck failure\n--------------------\n--------------------\nfailure\nFAILURE\nname: check-eq?\nlocation: (# 20 21 558 15)\nexpression: (check-eq? 1 2)\nactual: 1\nexpected: 2\n\nCheck failure\n--------------------\n") + #"\ +-------------------- +ERROR +First Outta here! +-------------------- +-------------------- +error +ERROR +Second Outta here! + +-------------------- +-------------------- +FAILURE +name: check-eq? +location: (# 19 12 520 15) +expression: (check-eq? 1 2) +actual: 1 +expected: 2 + +Check failure +-------------------- +-------------------- +failure +FAILURE +name: check-eq? +location: (# 20 21 558 15) +expression: (check-eq? 1 2) +actual: 1 +expected: 2 + +Check failure +-------------------- +") From 067c4b4359fbaa496dd1d91e35e97bc57d2d593f Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sat, 8 Oct 2011 23:23:57 -0600 Subject: [PATCH 396/746] updated documentation for syntax/trusted-xforms closes PR 12269 merge to 5.2 (cherry picked from commit 81fa15e27bc88c6a7f494d0d6f32e1d748205021) --- collects/syntax/scribblings/trusted-xforms.scrbl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/collects/syntax/scribblings/trusted-xforms.scrbl b/collects/syntax/scribblings/trusted-xforms.scrbl index 5719bd4bd6..e14c0a5745 100644 --- a/collects/syntax/scribblings/trusted-xforms.scrbl +++ b/collects/syntax/scribblings/trusted-xforms.scrbl @@ -8,8 +8,8 @@ The @racketmodname[syntax/trusted-xforms] library has no exports. It exists only to require other modules that perform syntax transformations, where the other transformations must use -@racket[syntax-recertify]. An application that wishes to provide a -less powerful code inspector to a sub-program should generally attach -@racketmodname[syntax/trusted-xforms] to the sub-program's namespace -so that things like the class system from @racketmodname[scheme/class] -work properly. +@racket[syntax-disarm] or @racket[syntax-arm]. An application that +wishes to provide a less powerful code inspector to a sub-program +should generally attach @racketmodname[syntax/trusted-xforms] to the +sub-program's namespace so that things like the class system from +@racketmodname[racket/class] work properly. From 26aadb28d7e2dea24264f59d36ed2527e5049d2d Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sun, 16 Oct 2011 00:05:26 -0600 Subject: [PATCH 397/746] db: updated note about sqlite3.dll merge to 5.2 (cherry picked from commit 8f2fe7a5aaced310594faa0d42f028c0638dc1a2) --- collects/db/scribblings/notes.scrbl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/collects/db/scribblings/notes.scrbl b/collects/db/scribblings/notes.scrbl index 2a5860c060..be11551191 100644 --- a/collects/db/scribblings/notes.scrbl +++ b/collects/db/scribblings/notes.scrbl @@ -82,11 +82,8 @@ SQLite support requires the appropriate native library. @itemlist[ -@item{On Windows, the library is @tt{sqlite3.dll}. It can be obtained -from @hyperlink["http://www.sqlite.org/download.html"]{the SQLite -download page}; the DLL file should be extracted and placed into one -of the directories produced by -@racketblock[(begin (require setup/dirs) (get-lib-search-dirs))]} +@item{On Windows, the library is @tt{sqlite3.dll}. It is included in +the Racket distribution.} @item{On Mac OS X, the library is @tt{libsqlite3.0.dylib}, which is included (in @tt{/usr/lib}) in Mac OS X version 10.4 onwards.} From 97a1f3cd5cd2d1bd2e58cec25e08d965bfe03a79 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 16 Oct 2011 07:00:04 -0700 Subject: [PATCH 398/746] fix an identifier binding bug Merge to 5.2 (cherry picked from commit c514fd3470dad254850086a11d7ec5a2345ea59d) --- collects/tests/racket/macro.rktl | 36 ++++++++++++++++++++++++++++++++ src/racket/src/compenv.c | 9 +++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/collects/tests/racket/macro.rktl b/collects/tests/racket/macro.rktl index 1b84ae708b..96f98a9fc9 100644 --- a/collects/tests/racket/macro.rktl +++ b/collects/tests/racket/macro.rktl @@ -566,6 +566,42 @@ (q)))) (require 'm-check-varref-expand) +;; ---------------------------------------- +;; Check that a modul-level binding with 0 marks +;; but lexical context is found correctly with +;; 1 and 2 marks (test case by Carl): + +(module check-macro-introduced-via-defctx racket/base + (require (for-syntax racket/base racket/syntax)) + + (begin-for-syntax + (define env (box #false))) + + (define-syntax (one stx) + (define ctx (syntax-local-make-definition-context #false)) + (define id + (internal-definition-context-apply + ctx + (syntax-local-introduce (datum->syntax #false 'private)))) + (syntax-local-bind-syntaxes (list id) #false ctx) + (internal-definition-context-seal ctx) + #`(begin + (begin-for-syntax (set-box! env #'#,id)) + (define #,id #false))) + (one) + + (define-syntax (two stx) + (define id ((make-syntax-introducer) (unbox env))) + (unless (free-identifier=? id (syntax-local-introduce id)) + (raise-syntax-error + #false + (format "mark changes identifier's binding: ~v / ~v" + (identifier-binding id) + (identifier-binding (syntax-local-introduce id))) + id)) + #'#f) + (two)) + ;; ---------------------------------------- (report-errs) diff --git a/src/racket/src/compenv.c b/src/racket/src/compenv.c index 9bf196b9cd..2bd5720e42 100644 --- a/src/racket/src/compenv.c +++ b/src/racket/src/compenv.c @@ -1086,10 +1086,13 @@ Scheme_Object *scheme_tl_id_sym(Scheme_Env *env, Scheme_Object *id, Scheme_Objec break; } } else { - if (!SCHEME_PAIRP(marks)) { + if (SCHEME_NULLP(amarks)) { + /* can always match empty marks */ + best_match = SCHEME_CDR(a); + best_match_skipped = 0; + } else if (!SCHEME_PAIRP(marks)) { /* To be better than nothing, could only match exactly: */ - if (scheme_equal(amarks, marks) - || SCHEME_NULLP(amarks)) { + if (scheme_equal(amarks, marks)) { best_match = SCHEME_CDR(a); best_match_skipped = 0; } From 728153bb07aa258ebc0c9671134ef2c90a1b4d85 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 16 Oct 2011 17:38:50 -0500 Subject: [PATCH 399/746] adjust the code that checks to see if a file is in the module language so that it uses read-language, in the case that the simpler check (that just looks for "#lang") fails. please include in 5.2 (cherry picked from commit abf722f19ac5268616826ca4c461d71c13b790b9) --- collects/drracket/private/auto-language.rkt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/collects/drracket/private/auto-language.rkt b/collects/drracket/private/auto-language.rkt index 44ec5a5d5e..86d69776a6 100644 --- a/collects/drracket/private/auto-language.rkt +++ b/collects/drracket/private/auto-language.rkt @@ -58,7 +58,11 @@ (: looks-like-module? ((Instance Text%) -> Boolean)) (define (looks-like-module? text) (or (looks-like-new-module-style? text) - (looks-like-old-module-style? text))) + (looks-like-old-module-style? text) + (with-handlers ((exn:fail? (λ (x) #f))) + (procedure? + (read-language (open-input-text-editor text 0 'end (λ (x) x) text #f) + (λ () #f)))))) (: looks-like-old-module-style? ((Instance Text%) -> Boolean)) (define (looks-like-old-module-style? text) From 83c56bb5f21823bb9700968e371116bf1ac0b10a Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 10 Oct 2011 21:24:17 -0400 Subject: [PATCH 400/746] Make the default answer for running an older uninstaller "yes". This makes it behave more like the Windows installer, where the default is to remove an older installation, which most people want to do anyway. (cherry picked from commit 08e70c5e45c8040c9e1440c3a7fa9f30caedae14) --- collects/meta/build/unix-installer/installer-header | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/collects/meta/build/unix-installer/installer-header b/collects/meta/build/unix-installer/installer-header index 7dbbaf130f..ecd42048d4 100644 --- a/collects/meta/build/unix-installer/installer-header +++ b/collects/meta/build/unix-installer/installer-header @@ -454,13 +454,13 @@ fi if test -x "$bindir/racket-uninstall"; then echo "A previous Racket uninstaller is found at" echo " \"$bindir/racket-uninstall\"," - echon " should I run it? (default: no) " + echon " should I run it? (default: yes) " read R case "$R" in - [yY]* ) echon " running uninstaller..." - "$bindir/racket-uninstall" || failwith "problems during uninstall" - echo " done." ;; - * ) failwith "abort..." ;; + [nN]* ) failwith "abort..." ;; + * ) echon " running uninstaller..." + "$bindir/racket-uninstall" || failwith "problems during uninstall" + echo " done." ;; esac fi From 87500a7e8f5f23b01453f9fc50e28bd817b131cf Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 11 Oct 2011 17:13:10 -0400 Subject: [PATCH 401/746] Misc improvements (no functionality changes, yet). (cherry picked from commit f882c01e654890d3076db856bb6b9414236fee3a) --- .../build/unix-installer/installer-header | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/collects/meta/build/unix-installer/installer-header b/collects/meta/build/unix-installer/installer-header index ecd42048d4..9da4b97dc6 100644 --- a/collects/meta/build/unix-installer/installer-header +++ b/collects/meta/build/unix-installer/installer-header @@ -4,7 +4,7 @@ PATH=/usr/bin:/bin -if [ "x`echo -n`" = "x-n" ]; then +if test "x`echo -n`" = "x-n"; then echon() { /bin/echo "$*\c"; } else echon() { echo -n "$*"; } @@ -27,16 +27,16 @@ exithandler() { trap exithandler 2 3 9 15 lookfor() { - save_IFS="${IFS}" + saved_IFS="${IFS}" IFS=":" for dir in $PATH; do if test -x "$dir/$1"; then eval "$1=$dir/$1" - IFS="$save_IFS" + IFS="$saved_IFS" return fi done - IFS="$save_IFS" + IFS="$saved_IFS" failwith "could not find \"$1\"." } @@ -65,7 +65,7 @@ origwd="`pwd`" echo "This program will extract and install $DISTNAME." echo "" -echo "Note: the required diskspace for this installation is about $ORIGSIZE." +echo "Note: the required diskspace for this installation is $ORIGSIZE." ############################################################################### ## What kind of installation? @@ -76,9 +76,9 @@ echo " In this distribution mode files go into different directories according" echo " to Unix conventions. A \"racket-uninstall\" script will be generated" echo " to be used when you want to remove the installation. If you say 'no'," echo " the whole Racket directory is kept in a single installation directory" -echo " (movable and erasable) unit, possibly with convenient external links" -echo " into it -- this is often more convenient, especially if you want to" -echo " install multiple versions or keep it in your home directory." +echo " (movable and erasable), possibly with external links into it -- this is" +echo " often more convenient, especially if you want to install multiple" +echo " versions or keep it in your home directory." if test ! "x$RELEASED" = "xyes"; then echo "*** This is a nightly build: such a unix-style distribution is *not*" echo "*** recommended because it cannot be used to install multiple versions." @@ -101,9 +101,8 @@ done echo "" if test "$unixstyle" = "Y"; then echo "Where do you want to base your installation of $DISTNAME?" - echo " (Use an existing directory. If you've done such an installation in" - echo " the past, either use the same place, or manually run" - echo " 'racket-uninstall' now.)" + echo " (If you've done such an installation in the past, either" + echo " enter the same directory, or run 'racket-uninstall' manually.)" TARGET1="..." else echo "Where do you want to install the \"$TARGET\" directory tree?" @@ -167,7 +166,7 @@ fi ## Deal with Unix-style path questions set_prefix() { - where="$1" + BASE="$1" # default dirs -- mimic configure behavior bindir="$BASE/bin" collectsdir="$BASE/lib/racket/collects" @@ -205,6 +204,7 @@ show_dir_var() { } read_dir() { + echon "New directory: " read new_dir case "$new_dir" in "/"* ) echo "$new_dir" ;; @@ -213,7 +213,7 @@ read_dir() { } if test "$unixstyle" = "Y"; then - set_prefix "$where" + set_prefix "$BASE" # loop for possible changes done="N" while test ! "$done" = "Y"; do @@ -232,19 +232,19 @@ if test "$unixstyle" = "Y"; then # show_dir_var "[r] Source Tree " "$srcdir" fi if test "$err" = "Y"; then echo "*** Errors in some paths ***"; fi - echo "Enter a new prefix, a letter to change an entry, enter to continue" + echo "Enter a letter to change an entry, a new prefix, or enter to continue" echon "> " read change_what case "$change_what" in - [eE]* ) echon "New directory: "; bindir="`read_dir`" ;; - [sS]* ) echon "New directory: "; collectsdir="`read_dir`" ;; - [dD]* ) echon "New directory: "; docdir="`read_dir`" ;; - [lL]* ) echon "New directory: "; libdir="`read_dir`" ;; - [hH]* ) echon "New directory: "; includerktdir="`read_dir`" ;; - [oO]* ) echon "New directory: "; librktdir="`read_dir`" ;; - [mM]* ) echon "New directory: "; mandir="`read_dir`" ;; + [eE]* ) bindir="`read_dir`" ;; + [sS]* ) collectsdir="`read_dir`" ;; + [dD]* ) docdir="`read_dir`" ;; + [lL]* ) libdir="`read_dir`" ;; + [hH]* ) includerktdir="`read_dir`" ;; + [oO]* ) librktdir="`read_dir`" ;; + [mM]* ) mandir="`read_dir`" ;; # [rR]* ) if test "$PNAME" = "full"; then - # echon "New directory: "; srcdir="`read_dir`" + # srcdir="`read_dir`" # else # echo "Invalid response" # fi ;; @@ -268,21 +268,21 @@ test "$BINSUM" = "$SUM" || failwith "bad CRC checksum." echo "ok." ############################################################################### -## Unpacking into $where/$TARGET +## Unpacking into $BASE/$TARGET unpack_installation() { # test that no TARGET exists if test -d "$BASE/$TARGET" || test -f "$BASE/$TARGET"; then echon "\"$BASE/$TARGET\" exists, delete? " - read yesno - case "$yesno" in - [yY]*) + read R + case "$R" in + [yY]* ) echon "Deleting old \"$BASE/$TARGET\"... " "$rm" -rf "$BASE/$TARGET" \ || failwith "could not delete \"$BASE/$TARGET\"." echo "done." ;; - *) failwith "aborting because \"$BASE/$TARGET\" exists." ;; + * ) failwith "aborting because \"$BASE/$TARGET\" exists." ;; esac fi # unpack @@ -307,14 +307,14 @@ wholedir_install() { unpack_installation rm_on_abort="" -cd "$where" +cd "$BASE" if test -d "bin"; then echo "Do you want to install new system links within the bin, lib, include," - echo " man, and doc subdirectories of \"$where\", possibly overriding" + echo " man, and doc subdirectories of \"$BASE\", possibly overriding" echon " existing links? " - read yesno - case "$yesno" in - [yY]* ) sysdir="$where" ;; + read R + case "$R" in + [yY]* ) sysdir="$BASE" ;; * ) sysdir="" ;; esac else @@ -429,7 +429,7 @@ if test ! "x$sysdir" = "x"; then else cd "$docdir" echo "Installing \"$sysdir/$docdir/$TARGET\"." - link "$BASE/$TARGET/notes" "$TARGET" "$sysdir/$docdir" + link "$BASE/$TARGET/doc" "$TARGET" "$sysdir/$docdir" fi fi @@ -466,7 +466,7 @@ fi unpack_installation -cd "$where" +cd "$BASE" "$TARGET/bin/racket" "$TARGET/collects/setup/unixstyle-install.rkt" \ "move" "$BASE/$TARGET" "$bindir" "$collectsdir" "$docdir" "$libdir" \ "$includerktdir" "$librktdir" "$mandir" \ From b06d1efc4d2cbf7754f821950062e6ebfd4a2bba Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 13 Oct 2011 17:25:50 -0400 Subject: [PATCH 402/746] Rewrote large parts of the unix installer script. It's now simpler, shorter, and better. Some of the text is revised, accepts environment variables when asked for the path, some additional fixes in misc places. (cherry picked from commit 3589a703087038a58ae3c3cb27a5dc7d2e4aec47) --- .../build/unix-installer/installer-header | 522 +++++++----------- 1 file changed, 206 insertions(+), 316 deletions(-) diff --git a/collects/meta/build/unix-installer/installer-header b/collects/meta/build/unix-installer/installer-header index 9da4b97dc6..205835dd51 100644 --- a/collects/meta/build/unix-installer/installer-header +++ b/collects/meta/build/unix-installer/installer-header @@ -20,9 +20,10 @@ failwith() { fi exit 1 } -exithandler() { - failwith "Aborting..." -} +# intentional aborts +abort() { failwith "abort."; } +# unexpected exits +exithandler() { failwith "Aborting..."; } trap exithandler 2 3 9 15 @@ -40,11 +41,6 @@ lookfor() { failwith "could not find \"$1\"." } -link() { # args are source, target, where we are - "$rm" -f "$2" || failwith "could not remove \"$2\" in \"$3\"." - "$ln" -s "$1" "$2" || failwith "could not link \"$2\" in \"$3\"." -} - lookfor rm lookfor ls lookfor ln @@ -62,6 +58,12 @@ _POSIX2_VERSION=199209 export _POSIX2_VERSION origwd="`pwd`" +installer_file="$0" +cat_installer() { + oldwd="`pwd`"; cd "$origwd" + "$tail" +"$BINSTARTLINE" "$installer_file" + cd "$oldwd" +} echo "This program will extract and install $DISTNAME." echo "" @@ -97,6 +99,7 @@ done ############################################################################### ## Where do you want it? +## sets $where to the location: target path for wholedir, prefix for unixstyle echo "" if test "$unixstyle" = "Y"; then @@ -119,183 +122,89 @@ else fi echon "> " read where -case "$where" in - "~/"* ) where="$HOME/${where#\~/}" ;; - "~"* ) failwith "cannot use '~user' paths" ;; -esac -case "$unixstyle$where" in - ? | ?1 ) where="/usr" ;; - ?2 ) where="/usr/local" ;; - ?3 ) where="$HOME" ;; - ?4 | ?. ) where="`pwd`" ;; - N/* ) TARGET="`\"$basename\" \"$where\"`" - where="`\"$dirname\" \"$where\"`" ;; - Y/* ) ;; - N* ) TARGET="`\"$basename\" \"$where\"`" - where="`\"$dirname\" \"$where\"`" - if test -d "$where"; then cd "$where"; where="`pwd`"; cd "$origwd" - else where="`pwd`/$where"; fi ;; - Y* ) if test -d "$where"; then cd "$where"; where="`pwd`"; cd "$origwd" - else where="`pwd`/$where"; fi ;; + +# numeric choice (make "." and "./" synonym for 4) +if test "$unixstyle" = "Y"; then TARGET1="" +else TARGET1="/$TARGET"; fi +case "x$where" in + x | x1 ) where="/usr$TARGET1" ;; + x2 ) where="/usr/local${TARGET1}" ;; + x3 ) where="${HOME}${TARGET1}" ;; + x4 | x. | x./ ) where="`pwd`${TARGET1}" ;; esac -if test "$unixstyle" = "N"; then - # can happen when choosing the root - if test "$TARGET" = "/"; then - failwith "refusing to remove your root" - fi -fi - -# BASE can be used with "$BASE/$TARGET" to avoid a double slash -case "$where" in - "" ) failwith "internal error (empty \$where)" ;; - "/" ) BASE="" ;; - *"/" ) failwith "internal error (\$where ends in a slash)" ;; - "/"* ) BASE="$where" ;; - * ) failwith "internal error (\$where is not absolute)" ;; -esac - -if test ! -d "$where"; then - failwith "the directory \"$where\" does not exist." -fi -if test ! -w "$where"; then - failwith "cannot write to \"$where\"." -fi +# substitute env vars and tildes +where="`eval \"echo \\\"$where\\\"\"`" ############################################################################### -## Deal with Unix-style path questions +## Default system directories prefixed by $1, mimic configure behavior +## used for unixstyle targets and for wholedir links -set_prefix() { - BASE="$1" - # default dirs -- mimic configure behavior - bindir="$BASE/bin" - collectsdir="$BASE/lib/racket/collects" - if test -d "$BASE/share"; then docdir="$BASE/share/racket/doc" - elif test -d "$BASE/doc"; then docdir="$BASE/doc/racket" - else docdir="$BASE/share/racket/doc" +set_dirs() { + # unixstyle: uses all of these + # wholedir: uses only bindir & mandir, no need for the others + bindir="$1/bin" + libdir="$1/lib" + incrktdir="$1/include/$TARGET" + librktdir="$1/lib/$TARGET" + collectsdir="$1/lib/$TARGET/collects" + has_share="N" + if test -d "$1/share"; then has_share="Y"; fi + if test "$has_share" = "N" && test -d "$1/doc"; then docdir="$1/doc/$TARGET" + else docdir="$1/share/$TARGET/doc" + fi + if test "$has_share" = "N" && test -d "$1/man"; then mandir="$1/man" + else mandir="$1/share/man" fi - libdir="$BASE/lib" - includerktdir="$BASE/include/racket" - librktdir="$BASE/lib/racket" - mandir="$BASE/man" # The source tree is always removed -- no point keeping it if it won't work - # if test -d "$BASE/share"; then srcdir="$BASE/share/racket/src" - # elif test -d "$BASE/src"; then srcdir="$BASE/src/racket" - # else srcdir="$BASE/share/racket/src" + # if test "$has_share" = "N" && test -d "$1/src"; then srcdir="$1/src/$TARGET" + # else srcdir="$1/share/$TARGET/src" # fi } -dir_createable() { - test_dir="`\"$dirname\" \"$1\"`" - if test -d "$test_dir" && test -w "$test_dir"; then return 0 - elif test "$test_dir" = "/"; then return 1 - else dir_createable "$test_dir"; fi -} - -show_dir_var() { - if test -f "$2"; then dir_status="(error: not a directory!)"; err="Y" - elif test ! -d "$2"; then - if dir_createable "$2"; then dir_status="(will be created)" - else dir_status="(error: not writable!)"; err="Y"; fi - elif test ! -w "$2"; then dir_status="(error: not writable!)"; err="Y" - else dir_status="(exists)" - fi - echo " $1 $2 $dir_status" -} - -read_dir() { - echon "New directory: " - read new_dir - case "$new_dir" in - "/"* ) echo "$new_dir" ;; - * ) echo "$BASE/$new_dir" ;; - esac -} - -if test "$unixstyle" = "Y"; then - set_prefix "$BASE" - # loop for possible changes - done="N" - while test ! "$done" = "Y"; do - echo "" - echo "Target Directories:" - err="N" - show_dir_var "[e] Executables " "$bindir" - show_dir_var "[s] Scheme Code " "$collectsdir" - show_dir_var "[d] Core Docs " "$docdir" - show_dir_var "[l] C Libraries " "$libdir" - show_dir_var "[h] C headers " "$includerktdir" - show_dir_var "[o] Extra C Objs " "$librktdir" - show_dir_var "[m] Man Pages " "$mandir" - if test "$PNAME" = "full"; then - echo " (C sources are not kept)" - # show_dir_var "[r] Source Tree " "$srcdir" - fi - if test "$err" = "Y"; then echo "*** Errors in some paths ***"; fi - echo "Enter a letter to change an entry, a new prefix, or enter to continue" - echon "> " - read change_what - case "$change_what" in - [eE]* ) bindir="`read_dir`" ;; - [sS]* ) collectsdir="`read_dir`" ;; - [dD]* ) docdir="`read_dir`" ;; - [lL]* ) libdir="`read_dir`" ;; - [hH]* ) includerktdir="`read_dir`" ;; - [oO]* ) librktdir="`read_dir`" ;; - [mM]* ) mandir="`read_dir`" ;; - # [rR]* ) if test "$PNAME" = "full"; then - # srcdir="`read_dir`" - # else - # echo "Invalid response" - # fi ;; - "/"* ) set_prefix "$change_what" ;; - "" ) done="Y" ;; - * ) echo "Invalid response" ;; - esac - done - if test "$err" = "Y"; then failwith "errors in some paths"; fi -fi - ############################################################################### -## Integrity check - -echo "" -echon "Checking the integrity of the binary archive... " -SUM="`\"$tail\" +\"$BINSTARTLINE\" \"$0\" | \"$cksum\"`" \ - || failwith "problems running cksum." -SUM="`set $SUM; echo $1`" -test "$BINSUM" = "$SUM" || failwith "bad CRC checksum." -echo "ok." - -############################################################################### -## Unpacking into $BASE/$TARGET +## Integrity check and unpack into $1 +## also sets $INSTDIR to the directory in its canonical form unpack_installation() { - # test that no TARGET exists - if test -d "$BASE/$TARGET" || test -f "$BASE/$TARGET"; then - echon "\"$BASE/$TARGET\" exists, delete? " + T="$1" + # integrity check + echo "" + echon "Checking the integrity of the binary archive... " + SUM="`cat_installer | \"$cksum\"`" || failwith "problems running cksum." + SUM="`set $SUM; echo $1`" + test "$BINSUM" = "$SUM" || failwith "bad CRC checksum." + echo "ok." + # test that the target does not exists + if test -d "$T" || test -f "$T"; then + if test -d "$T"; then + # use the real name, so "/foo/.." shows as an explicit "/" + oldwd="`pwd`"; cd "$T"; T="`pwd`"; cd "$oldwd"; echon "\"$T\" exists" + else + echon "\"$T\" exists (as a file)" + fi + echon ", delete? " read R case "$R" in [yY]* ) - echon "Deleting old \"$BASE/$TARGET\"... " - "$rm" -rf "$BASE/$TARGET" \ - || failwith "could not delete \"$BASE/$TARGET\"." + echon "Deleting old \"$T\"... " + "$rm" -rf "$T" || failwith "could not delete \"$T\"." echo "done." ;; - * ) failwith "aborting because \"$BASE/$TARGET\" exists." ;; + * ) abort ;; esac fi # unpack - echon "Unpacking into \"$BASE/$TARGET\"... " - rm_on_abort="$BASE/$TARGET" - "$mkdir" "$BASE/$TARGET" - "$tail" +"$BINSTARTLINE" "$0" | "$gunzip" -c \ - | { cd "$BASE/$TARGET" - "$tar" xf - || failwith "problems during unpacking of binary archive." - } - cd "$BASE/$TARGET" - test -d "collects" \ - || failwith "unpack failed (could not find \"$BASE/$TARGET/collects\")." + rm_on_abort="$T" + "$mkdir" -p "$T" || failwith "could not create directory: $T" + oldwd="`pwd`"; cd "$T"; INSTDIR="`pwd`"; cd "$oldwd" + echon "Unpacking into \"$INSTDIR\" (Ctrl+C to abort)... " + cat_installer | "$gunzip" -c \ + | { cd "$INSTDIR" + "$tar" xf - || failwith "problems during unpacking of binary archive." + } + test -d "$INSTDIR/collects" \ + || failwith "unpack failed (could not find \"$T/collects\")." echo "done." } @@ -304,178 +213,159 @@ unpack_installation() { wholedir_install() { -unpack_installation -rm_on_abort="" + unpack_installation "$where" + rm_on_abort="" -cd "$BASE" -if test -d "bin"; then - echo "Do you want to install new system links within the bin, lib, include," - echo " man, and doc subdirectories of \"$BASE\", possibly overriding" - echon " existing links? " - read R - case "$R" in - [yY]* ) sysdir="$BASE" ;; - * ) sysdir="" ;; - esac -else - cd "$origwd" echo "" - echo "If you want to install new system links within the bin, lib, include," - echo " man, and doc subdirectories of a common directory prefix (for" - echo " example, \"/usr/local\") then enter the prefix you want to use." + echo "If you want to install new system links within the \"bin\" and" + echo " \"man\" subdirectories of a common directory prefix (for example," + echo " \"/usr/local\") then enter the prefix of an existing directory" + echo " that you want to use. This might overwrite existing symlinks," + echo " but not files." echon "(default: skip links) > " - read sysdir - if test ! "x$sysdir" = "x"; then - if test ! -d "$sysdir"; then - echo "Directory \"$sysdir\" does not exist, skipping links." - sysdir="" - elif test ! -w "$sysdir"; then - echo "Directory \"$sysdir\" is not writable, skipping links." - sysdir="" - else - cd "$sysdir" - sysdir="`pwd`" - fi - fi -fi - -if test ! "x$sysdir" = "x"; then - # binaries - cd "$sysdir" - if test -d "bin" && test -w "bin"; then - echo "Installing links in \"$sysdir/bin\"..." - printsep=" " - cd "bin" - for x in `cd "$BASE/$TARGET/bin"; ls`; do - if test -x "$BASE/$TARGET/bin/$x"; then - echon "${printsep}$x" - printsep=", " - link "$BASE/$TARGET/bin/$x" "$x" "$sysdir/bin" + read SYSDIR + if test "x$SYSDIR" = "x"; then : + elif test ! -d "$SYSDIR"; then + echo "\"$SYSDIR\" does not exist, skipping links." + elif test ! -w "$SYSDIR"; then + echo "\"$SYSDIR\" is not writable, skipping links." + else + oldwd="`pwd`"; cd "$SYSDIR"; SYSDIR="`pwd`"; cd "$oldwd" + set_dirs "$SYSDIR" + install_links() { # tgtdir(absolute) srcdir(relative to INSTDIR) + if ! test -d "$1"; then + echo "\"$1\" does not exist, skipping." + elif ! test -w "$1"; then + echo "\"$1\" is not writable, skipping" + else + echo "Installing links in \"$1\"..." + printsep=" " + cd "$1" + for x in `cd "$INSTDIR/$2"; ls`; do + echon "${printsep}$x"; printsep=", " + if test -h "$x"; then rm -f "$x"; fi + if test -d "$x" || test -f "$x"; then + echon " skipped (non-link exists)" + elif ! "$ln" -s "$INSTDIR/$2/$x" "$x"; then + echon " skipped (symlink failed)" + fi + done + echo ""; echo " done." fi - done - echo "" - echo "Done. (see \"$BASE/$TARGET/bin\" for other executables)" - else - echo "Skipping \"$sysdir/bin\" (does not exist or not writable)." + } + install_links "$bindir" "bin" + install_links "$mandir/man1" "man/man1" fi - # man pages - cd "$sysdir" - if test -d "man" && test -d "man/man1" && test -w "man/man1"; then - mandir="man/man1" - elif test -d "share" && test -d "share/man" && test -d "share/man/man1" \ - && test -w "share/man/man1"; then - mandir="share/man/man1" - else - mandir="" - fi - if test "x$mandir" = "x"; then - echo "Skipping \"$sysdir/man/man1\" (does not exist or not writable)." - else - cd "$mandir" - echo "Installing links in \"$sysdir/$mandir\"..." - printsep=" " - for x in `cd "$BASE/$TARGET/man/man1/"; "$ls"`; do - echon "${printsep}$x" - printsep=", " - link "$BASE/$TARGET/man/man1/$x" "$x" "$sysdir/$mandir" - done - echo "" - echo "Done" - fi - # lib link - cd "$sysdir" - if test -d "lib" && test -w "lib"; then - libdir="lib" - elif test -d "share" && test -d "share/lib" && test -w "share/lib"; then - libdir="share/lib" - else - libdir="" - fi - if test "x$libdir" = "x"; then - echo "Skipping \"$sysdir/lib\" (does not exist or not writable)." - else - cd "$libdir" - echo "Installing \"$sysdir/$libdir/$TARGET\"." - link "$BASE/$TARGET/lib" "$TARGET" "$sysdir/$libdir" - fi - # include link - cd "$sysdir" - if test -d "include" && test -w "include"; then - incdir="include" - elif test -d "share" && test -d "share/include" \ - && test -w "share/include"; then - incdir="share/include" - else - incdir="" - fi - if test "x$incdir" = "x"; then - echo "Skipping \"$sysdir/include\" (does not exist or not writable)." - else - cd "$incdir" - echo "Installing \"$sysdir/$incdir/$TARGET\"." - link "$BASE/$TARGET/include" "$TARGET" "$sysdir/$incdir" - fi - # doc link - cd "$sysdir" - if test -d "doc" && test -w "doc"; then - docdir="doc" - elif test -d "share" && test -d "share/doc" && test -w "share/doc"; then - docdir="share/doc" - else - docdir="" - fi - if test "x$docdir" = "x"; then - echo "Skipping \"$sysdir/doc\" (does not exist or not writable)." - else - cd "$docdir" - echo "Installing \"$sysdir/$docdir/$TARGET\"." - link "$BASE/$TARGET/doc" "$TARGET" "$sysdir/$docdir" - fi -fi } ############################################################################### ## Unix-style installations +dir_createable() { + test_dir="`\"$dirname\" \"$1\"`" + if test -d "$test_dir" && test -w "$test_dir"; then return 0 + elif test "$test_dir" = "/"; then return 1 + else dir_createable "$test_dir"; fi +} +show_dir_var() { + if test -f "$2"; then status="error: not a directory!"; err="Y" + elif test ! -d "$2"; then + if dir_createable "$2"; then status="will be created" + else status="error: not writable!"; err="Y"; fi + elif test ! -w "$2"; then status="error: not writable!"; err="Y" + else status="exists" + fi + echo " $1 $2 ($status)" +} + unixstyle_install() { -TARGET="$TARGET-tmp-install" -if test -e "$BASE/$TARGET"; then - echo "\"$BASE/$TARGET\" already exists (needed for the installation)," - echon " ok to remove? " - read R - case "$R" in - [yY]* ) "$rm" -rf "$BASE/$TARGET" ;; - * ) failwith "abort..." ;; - esac -fi + if test -f "$where"; then + failwith "The entered base directory exists as a file: $where" + elif test ! -d "$where"; then + echo "Base directory does not exist: $where" + echon " should I create it? (default: yes) " + read R; case "$R" in [nN]* ) abort ;; esac + "$mkdir" -p "$where" || failwith "could not create directory: $where" + fi + cd "$where" || failwith "Base directory does not exist: $where" + where="`pwd`"; cd "$origwd" -if test -x "$bindir/racket-uninstall"; then - echo "A previous Racket uninstaller is found at" - echo " \"$bindir/racket-uninstall\"," - echon " should I run it? (default: yes) " - read R - case "$R" in - [nN]* ) failwith "abort..." ;; - * ) echon " running uninstaller..." - "$bindir/racket-uninstall" || failwith "problems during uninstall" - echo " done." ;; - esac -fi + set_dirs "$where" + # loop for possible changes + done="N" + while test ! "$done" = "Y" || test "x$err" = "xY" ; do + echo "" + echo "Target Directories:" + err="N" + show_dir_var "[e] Executables " "$bindir" + show_dir_var "[r] Racket Code " "$collectsdir" + show_dir_var "[d] Core Docs " "$docdir" + show_dir_var "[l] C Libraries " "$libdir" + show_dir_var "[h] C headers " "$incrktdir" + show_dir_var "[o] Extra C Objs " "$librktdir" + show_dir_var "[m] Man Pages " "$mandir" + if test "$PNAME" = "full"; then + echo " (C sources are not kept)" + # show_dir_var "[s] Source Tree " "$srcdir" + fi + echo "Enter a letter to change an entry, or enter to continue" + echon "> "; read change_what + read_dir() { + echon "New directory (absolute or relative to $where): "; read new_dir + case "$new_dir" in + "/"* ) echo "$new_dir" ;; + * ) echo "$where/$new_dir" ;; + esac + } + case "$change_what" in + [eE]* ) bindir="`read_dir`" ;; + [rR]* ) collectsdir="`read_dir`" ;; + [dD]* ) docdir="`read_dir`" ;; + [lL]* ) libdir="`read_dir`" ;; + [hH]* ) incrktdir="`read_dir`" ;; + [oO]* ) librktdir="`read_dir`" ;; + [mM]* ) mandir="`read_dir`" ;; + # [sS]* ) if test "$PNAME" = "full"; then srcdir="`read_dir`" + # else echo "Invalid response"; fi ;; + "" ) if test "$err" = "N"; then done="Y" + else echo "*** Please fix erroneous paths to proceed"; fi ;; + * ) echo "Invalid response" ;; + esac + done -unpack_installation + if test -x "$bindir/racket-uninstall"; then + echo "A previous Racket uninstaller is found at" + echo " \"$bindir/racket-uninstall\"," + echon " should I run it? (default: yes) " + read R + case "$R" in + [nN]* ) abort ;; + * ) echon " running uninstaller..." + "$bindir/racket-uninstall" || failwith "problems during uninstall" + echo " done." ;; + esac + fi -cd "$BASE" -"$TARGET/bin/racket" "$TARGET/collects/setup/unixstyle-install.rkt" \ - "move" "$BASE/$TARGET" "$bindir" "$collectsdir" "$docdir" "$libdir" \ - "$includerktdir" "$librktdir" "$mandir" \ -|| failwith "installation failed" + tmp="$where/$TARGET-tmp-install" + if test -f "$tmp" || test -d "$tmp"; then + echo "\"$tmp\" already exists (needed for the installation)," + echon " ok to remove it? " + read R; case "$R" in [yY]* ) "$rm" -rf "$tmp" ;; * ) abort ;; esac + fi + unpack_installation "$tmp" + + cd "$where" + "$tmp/bin/racket" "$tmp/collects/setup/unixstyle-install.rkt" \ + "move" "$tmp" "$bindir" "$collectsdir" "$docdir" "$libdir" \ + "$incrktdir" "$librktdir" "$mandir" \ + || failwith "installation failed" } ############################################################################### -## Done +## Run the right installer now if test "$unixstyle" = "Y"; then unixstyle_install; else wholedir_install; fi From 06bc3bd4706606fbe079c39cb869e9422cef8fe9 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 16 Oct 2011 18:53:13 -0400 Subject: [PATCH 403/746] Lots of little changes and fixes, and an extensive testing script. (cherry picked from commit 08b2d7b595780e6e95a851b54611fcd643247d62) --- .../build/unix-installer/installer-header | 107 +++-- .../meta/build/unix-installer/test-installer | 447 ++++++++++++++++++ 2 files changed, 510 insertions(+), 44 deletions(-) create mode 100755 collects/meta/build/unix-installer/test-installer diff --git a/collects/meta/build/unix-installer/installer-header b/collects/meta/build/unix-installer/installer-header index 205835dd51..3edd4f7c4d 100644 --- a/collects/meta/build/unix-installer/installer-header +++ b/collects/meta/build/unix-installer/installer-header @@ -12,7 +12,9 @@ fi rm_on_abort="" failwith() { - echo "Error: $*" 1>&2 + err="Error: " + if test "x$1" = "x-noerror"; then err=""; shift; fi + echo "$err$*" 1>&2 if test ! "x$rm_on_abort" = "x" && test -e "$rm_on_abort"; then echon " (Removing installation files in $rm_on_abort)" "$rm" -rf "$rm_on_abort" @@ -21,9 +23,9 @@ failwith() { exit 1 } # intentional aborts -abort() { failwith "abort."; } +abort() { failwith -noerror "Aborting installation."; } # unexpected exits -exithandler() { failwith "Aborting..."; } +exithandler() { echo ""; failwith "Aborting..."; } trap exithandler 2 3 9 15 @@ -68,11 +70,11 @@ cat_installer() { echo "This program will extract and install $DISTNAME." echo "" echo "Note: the required diskspace for this installation is $ORIGSIZE." +echo "" ############################################################################### ## What kind of installation? -echo "" echo "Do you want a Unix-style distribution?" echo " In this distribution mode files go into different directories according" echo " to Unix conventions. A \"racket-uninstall\" script will be generated" @@ -96,12 +98,12 @@ while test "$unixstyle" = "x"; do * ) unixstyle="x" ;; esac done +echo "" ############################################################################### ## Where do you want it? ## sets $where to the location: target path for wholedir, prefix for unixstyle -echo "" if test "$unixstyle" = "Y"; then echo "Where do you want to base your installation of $DISTNAME?" echo " (If you've done such an installation in the past, either" @@ -176,12 +178,15 @@ unpack_installation() { test "$BINSUM" = "$SUM" || failwith "bad CRC checksum." echo "ok." # test that the target does not exists + here="N" if test -d "$T" || test -f "$T"; then - if test -d "$T"; then + if test -d "$T" && test -x "$T"; then # use the real name, so "/foo/.." shows as an explicit "/" - oldwd="`pwd`"; cd "$T"; T="`pwd`"; cd "$oldwd"; echon "\"$T\" exists" - else - echon "\"$T\" exists (as a file)" + oldwd="`pwd`"; cd "$T"; T="`pwd`"; cd "$oldwd" + fi + if test -f "$T"; then echon "\"$T\" exists (as a file)" + elif test ! "`pwd`" = "$T"; then echon "\"$T\" exists" + else here="Y"; echon "\"$T\" is where you ran the installer from" fi echon ", delete? " read R @@ -197,15 +202,23 @@ unpack_installation() { # unpack rm_on_abort="$T" "$mkdir" -p "$T" || failwith "could not create directory: $T" - oldwd="`pwd`"; cd "$T"; INSTDIR="`pwd`"; cd "$oldwd" - echon "Unpacking into \"$INSTDIR\" (Ctrl+C to abort)... " + if test "$here" = "Y"; then + cd "$T"; INSTDIR="$T" + echo "*** Note: your original directory was deleted, so you will need" + echo "*** to 'cd' back into it when the installer is done, otherwise" + echo "*** it will look like you have an empty directory." + sleep 1 + else oldwd="`pwd`"; cd "$T"; INSTDIR="`pwd`"; cd "$oldwd" + fi + rm_on_abort="$INSTDIR" + echo "Unpacking into \"$INSTDIR\" (Ctrl+C to abort)..." cat_installer | "$gunzip" -c \ | { cd "$INSTDIR" "$tar" xf - || failwith "problems during unpacking of binary archive." } test -d "$INSTDIR/collects" \ || failwith "unpack failed (could not find \"$T/collects\")." - echo "done." + echo "Done." } ############################################################################### @@ -227,7 +240,7 @@ wholedir_install() { if test "x$SYSDIR" = "x"; then : elif test ! -d "$SYSDIR"; then echo "\"$SYSDIR\" does not exist, skipping links." - elif test ! -w "$SYSDIR"; then + elif test ! -x "$SYSDIR" || test ! -w "$SYSDIR"; then echo "\"$SYSDIR\" is not writable, skipping links." else oldwd="`pwd`"; cd "$SYSDIR"; SYSDIR="`pwd`"; cd "$oldwd" @@ -235,7 +248,7 @@ wholedir_install() { install_links() { # tgtdir(absolute) srcdir(relative to INSTDIR) if ! test -d "$1"; then echo "\"$1\" does not exist, skipping." - elif ! test -w "$1"; then + elif ! test -x "$1" || ! test -w "$1"; then echo "\"$1\" is not writable, skipping" else echo "Installing links in \"$1\"..." @@ -263,10 +276,10 @@ wholedir_install() { ## Unix-style installations dir_createable() { - test_dir="`\"$dirname\" \"$1\"`" - if test -d "$test_dir" && test -w "$test_dir"; then return 0 - elif test "$test_dir" = "/"; then return 1 - else dir_createable "$test_dir"; fi + tdir="`\"$dirname\" \"$1\"`" + if test -d "$tdir" && test -x "$tdir" && test -w "$tdir"; then return 0 + elif test "$tdir" = "/"; then return 1 + else dir_createable "$tdir"; fi } show_dir_var() { if test -f "$2"; then status="error: not a directory!"; err="Y" @@ -288,54 +301,60 @@ unixstyle_install() { echon " should I create it? (default: yes) " read R; case "$R" in [nN]* ) abort ;; esac "$mkdir" -p "$where" || failwith "could not create directory: $where" + elif test ! -w "$where"; then + failwith "The entered base directory is not writable: $where" fi cd "$where" || failwith "Base directory does not exist: $where" where="`pwd`"; cd "$origwd" set_dirs "$where" # loop for possible changes - done="N" + done="N"; retry="N" while test ! "$done" = "Y" || test "x$err" = "xY" ; do - echo "" - echo "Target Directories:" err="N" - show_dir_var "[e] Executables " "$bindir" - show_dir_var "[r] Racket Code " "$collectsdir" - show_dir_var "[d] Core Docs " "$docdir" - show_dir_var "[l] C Libraries " "$libdir" - show_dir_var "[h] C headers " "$incrktdir" - show_dir_var "[o] Extra C Objs " "$librktdir" - show_dir_var "[m] Man Pages " "$mandir" - if test "$PNAME" = "full"; then - echo " (C sources are not kept)" - # show_dir_var "[s] Source Tree " "$srcdir" + if test "$retry" = "N"; then + echo "" + echo "Target Directories:" + show_dir_var "[e] Executables " "$bindir" + show_dir_var "[r] Racket Code " "$collectsdir" + show_dir_var "[d] Core Docs " "$docdir" + show_dir_var "[l] C Libraries " "$libdir" + show_dir_var "[h] C headers " "$incrktdir" + show_dir_var "[o] Extra C Objs " "$librktdir" + show_dir_var "[m] Man Pages " "$mandir" + if test "$PNAME" = "full"; then + echo " (C sources are not kept)" + # show_dir_var "[s] Source Tree " "$srcdir" + fi + echo "Enter a letter to change an entry, or enter to continue." fi - echo "Enter a letter to change an entry, or enter to continue" + retry="N" echon "> "; read change_what read_dir() { echon "New directory (absolute or relative to $where): "; read new_dir case "$new_dir" in - "/"* ) echo "$new_dir" ;; - * ) echo "$where/$new_dir" ;; + "/"* ) eval "$1=\"$new_dir\"" ;; + * ) eval "$1=\"$where/$new_dir\"" ;; esac } case "$change_what" in - [eE]* ) bindir="`read_dir`" ;; - [rR]* ) collectsdir="`read_dir`" ;; - [dD]* ) docdir="`read_dir`" ;; - [lL]* ) libdir="`read_dir`" ;; - [hH]* ) incrktdir="`read_dir`" ;; - [oO]* ) librktdir="`read_dir`" ;; - [mM]* ) mandir="`read_dir`" ;; - # [sS]* ) if test "$PNAME" = "full"; then srcdir="`read_dir`" + [eE]* ) read_dir bindir ;; + [rR]* ) read_dir collectsdir ;; + [dD]* ) read_dir docdir ;; + [lL]* ) read_dir libdir ;; + [hH]* ) read_dir incrktdir ;; + [oO]* ) read_dir librktdir ;; + [mM]* ) read_dir mandir ;; + # [sS]* ) if test "$PNAME" = "full"; then read_dir srcdir # else echo "Invalid response"; fi ;; "" ) if test "$err" = "N"; then done="Y" else echo "*** Please fix erroneous paths to proceed"; fi ;; - * ) echo "Invalid response" ;; + * ) retry="Y" ;; esac done if test -x "$bindir/racket-uninstall"; then + echo "" echo "A previous Racket uninstaller is found at" echo " \"$bindir/racket-uninstall\"," echon " should I run it? (default: yes) " @@ -370,7 +389,7 @@ unixstyle_install() { if test "$unixstyle" = "Y"; then unixstyle_install; else wholedir_install; fi echo "" -echo "All done." +echo "Installation complete." exit diff --git a/collects/meta/build/unix-installer/test-installer b/collects/meta/build/unix-installer/test-installer new file mode 100755 index 0000000000..55ed825f61 --- /dev/null +++ b/collects/meta/build/unix-installer/test-installer @@ -0,0 +1,447 @@ +#!/bin/sh +#| -*- scheme -*- +exec racket "$0" "$@" +|# + +#lang at-exp racket/base + +(require racket/list racket/file racket/match racket/system) + +(define testdir "/tmp/racket-installer-test") +(define installer "/tmp/r.sh") + +(define (err fmt . args) + (raise-user-error (format "Error: ~a" (apply format fmt args)))) + +(define (exe name [just-path? #f]) + (define path (or (find-executable-path name) + (err "no `~a' executable found" name))) + (λ args (unless (apply system* path args) + (err "`~a' signalled an error" name)))) + +(define expect-exe (exe "expect")) +(define sync-exe (exe "sync")) + +(unless (file-exists? installer) (err "missing installer at: ~a" installer)) +(when (directory-exists? testdir) (err "test directory exists: ~a" testdir)) +(make-directory testdir) +(current-directory testdir) +;; make identifiable prompts, predictable ls output, safe-for-play home +(void (putenv "PS1" "sh> ") (putenv "COLUMNS" "72") (putenv "HOME" testdir)) + +(define (transcript) + ;; the test transcript text: + ;; - text is matched against the process output (anchored) + ;; - `i' is for user input to send + ;; - `r' is for a regexp + ;; - `s' is a nested list to be spliced in + ;; - `N' is short for @r{[0-9.]+} + ;; - `...' makes the next match unanchored (so it's similar to a non-greedy + ;; ".*" regexp) + (define (i . xs) `(i . ,xs)) + (define (r . xs) `(r . ,xs)) + (define (s . xs) `(s . ,xs)) + (define break 'break) + (define N @r{[0-9.]+}) + (define ... '...) + @list{ + @; the first few puzzling interactions are testing that we generate the + @; right expect code -- which requires regexp and $-quoting. + sh> @i{echo "blah"} + blah + sh> @i{echo 'blah'} + blah + sh> @i{x=123} + sh> @i{echo "][@"}{"blah*$x*"} + ][@"}{"blah*123* + sh> @i{echo '[]{}blah*$x*'} + []{}blah*$x* + sh> @i{pwd} + @testdir + @; proper testing begins here + sh> @i{sh @installer} + This program will extract and install Racket v@|N|. + @|| + Note: the required diskspace for this installation is @|N|M. + @|| + Do you want a Unix-style distribution? + In this distribution mode files go into different directories according + to Unix conventions. A "racket-uninstall" script will be generated + to be used when you want to remove the installation. If you say 'no', + the whole Racket directory is kept in a single installation directory + (movable and erasable), possibly with external links into it -- this is + often more convenient, especially if you want to install multiple + versions or keep it in your home directory. + *** This is a nightly build: such a unix-style distribution is *not* + *** recommended because it cannot be used to install multiple versions. + Enter yes/no (default: no) > @i{bleh} + Enter yes/no (default: no) > @i{foo} + Enter yes/no (default: no) > @i{} + @|| + Where do you want to install the "racket-@N" directory tree? + 1 - /usr/racket-@N [default] + 2 - /usr/local/racket-@N + 3 - ~/racket-@N (@|testdir|/racket-@N) + 4 - ./racket-@N (here) + Or enter a different "racket" directory to install in. + > @i{4} + @|| + Checking the integrity of the binary archive... ok. + Unpacking into "@|testdir|/racket-@N" (Ctrl+C to abort)... + Done. + @|| + If you want to install new system links within the "bin" and + "man" subdirectories of a common directory prefix (for example, + "/usr/local") then enter the prefix of an existing directory + that you want to use. This might overwrite existing symlinks, + but not files. + (default: skip links) > @i{} + @|| + Installation complete. + sh> @i{ls -mF} + racket-@|N|/ + sh> @i{ls -mF racket-*} + README, bin/, collects/, doc/, include/, lib/, man/ + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{No} + @... + > @i{.} + @|| + Checking the integrity of the binary archive... ok. + "@|testdir|/racket-@N" exists, delete? @i{n} + Aborting installation. + sh> @i{ls -mF racket-*} + README, bin/, collects/, doc/, include/, lib/, man/ + sh> @i{chmod 000 racket*} + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{No} + @... + > @i{./} + @|| + Checking the integrity of the binary archive... ok. + "@|testdir|/racket-@N" exists, delete? @i{y} + Deleting old "@|testdir|/racket-@N"... @; + /bin/rm: cannot remove `@|testdir|/racket-@N': @; + Permission denied + Error: could not delete "@|testdir|/racket-@N". + sh> @i{chmod 755 racket*} + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{No} + @... + > @i{.} + @|| + Checking the integrity of the binary archive... ok. + "@|testdir|/racket-@N" exists, delete? @i{y} + Deleting old "@|testdir|/racket-@N"... done. + @... + (default: skip links) > @i{.} + "@|testdir|/bin" does not exist, skipping. + "@|testdir|/share/man/man1" does not exist, skipping. + @|| + Installation complete. + sh> @i{mkdir bin} + sh> @i{touch R bin/gracket} + sh> @i{export TGT=R} + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{} + @... + > @i{$TGT} + @|| + Checking the integrity of the binary archive... ok. + "R" exists (as a file), delete? @i{y} + Deleting old "R"... done. + Unpacking into "@|testdir|/R" (Ctrl+C to abort)... + Done. + @... + (default: skip links) > @i{.} + Installing links in "@|testdir|/bin"... + drracket, gracket skipped (non-link exists), gracket-text, mred, @; + mred-text, mzc, mzpp, mzscheme, mztext, pdf-slatex, planet, plt-games, @; + plt-help, plt-r5rs, plt-r6rs, plt-web-server, racket, raco, scribble, @; + setup-plt, slatex, slideshow, swindle, tex2page + done. + "@|testdir|/share/man/man1" does not exist, skipping. + @|| + Installation complete. + sh> @i{ls -mF .} + R/, bin/, racket-@|N|/ + sh> @i{ls -mF R} + README, bin/, collects/, doc/, include/, lib/, man/ + sh> @i{ls -mF bin} + @s|{drracket@, gracket, gracket-text@, mred@, mred-text@, mzc@, mzpp@, + mzscheme@, mztext@, pdf-slatex@, planet@, plt-games@, plt-help@, + plt-r5rs@, plt-r6rs@, plt-web-server@, racket@, raco@, scribble@, + setup-plt@, slatex@, slideshow@, swindle@, tex2page@}| + sh> @i{ls -l bin/ra*} + lrwxrwxrwx. @... bin/racket -> @|testdir|/R/bin/racket + lrwxrwxrwx. @... bin/raco -> @|testdir|/R/bin/raco + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{} + @... + > @i{$TGT`echo 1`} + @|| + Checking the integrity of the binary archive... ok. + Unpacking into "@|testdir|/R1" (Ctrl+C to abort)... + @break + Error: Aborting... + (Removing installation files in @|testdir|/R1) + sh> @i{ls -mF} + R/, bin/, racket-@|N|/ + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{} + @... + > @i{mmm} + @... + Unpacking into "@|testdir|/mmm" (Ctrl+C to abort)... + Done. + @... + (default: skip links) > @break + Error: Aborting... + sh> @i{ls -mF} + R/, bin/, mmm/, racket-5.2.0.1/ + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{} + @... + > @i{`pwd`} + @... + "@testdir" is where you ran the installer from, delete? @i{y} + Deleting old "@testdir"... done. + *** Note: your original directory was deleted, so you will need + *** to 'cd' back into it when the installer is done, otherwise + *** it will look like you have an empty directory. + Unpacking into "@testdir" (Ctrl+C to abort)... + Done. + @... + (default: skip links) > @i{/usr/local} + "/usr/local" is not writable, skipping links. + @|| + Installation complete. + sh> @i{ls -mF} + sh> @i{cd /} + sh> @i{cd @testdir} + sh> @i{ls -mF} + README, bin/, collects/, doc/, include/, lib/, man/ + sh> @i{rm -rf [a-zR]*} + sh> @i{ls -mF} + sh> @i{sh @installer} + @... + Do you want a Unix-style distribution? + @... + Enter yes/no (default: no) > @i{bleh} + Enter yes/no (default: no) > @i{yes} + @|| + Where do you want to base your installation of Racket v@|N|? + (If you've done such an installation in the past, either + enter the same directory, or run 'racket-uninstall' manually.) + 1 - /usr/... [default] + 2 - /usr/local/... + 3 - ~/... (@|testdir|/...) + 4 - ./... (here) + Or enter a different directory prefix to install in. + > @i{} + Error: The entered base directory is not writable: /usr + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{y} + @... + > @i{2} + Error: The entered base directory is not writable: /usr/local + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{y} + @... + > @i{3} + @|| + Target Directories: + [e] Executables @|testdir|/bin (will be created) + [r] Racket Code @|testdir|/lib/racket-@|N|/collects (will be created) + [d] Core Docs @|testdir|/share/racket-@|N|/doc (will be created) + [l] C Libraries @|testdir|/lib (will be created) + [h] C headers @|testdir|/include/racket-@|N| (will be created) + [o] Extra C Objs @|testdir|/lib/racket-@|N| (will be created) + [m] Man Pages @|testdir|/share/man (will be created) + Enter a letter to change an entry, or enter to continue. + > @i{z} + > @i{Q} + > @i{} + @|| + Checking the integrity of the binary archive... ok. + Unpacking into "@|testdir|/racket-@|N|-tmp-install" (Ctrl+C to abort)... + Done. + Moving bin -> @|testdir|/bin + Moving collects -> @|testdir|/lib/racket-@|N|/collects + Moving doc -> @|testdir|/share/racket-@|N|/doc + Moving include -> @|testdir|/include/racket-@|N| + Moving lib -> @|testdir|/lib/racket-@|N| + Moving man -> @|testdir|/share/man + Moving README -> @|testdir|/share/racket-@|N|/doc/README + Writing uninstaller at: @|testdir|/bin/racket-uninstall... + Rewriting configuration file at: @|testdir|/lib/racket-@|N|/@; + collects/config/config.rkt... + Recompiling to @|testdir|/lib/racket-@|N|/@; + collects/config/compiled/config_rkt.zo... + @|| + Installation complete. + sh> @i{ls -mF} + bin/, include/, lib/, share/ + sh> @i{ls -mF bin} + drracket*, gracket*, gracket-text*, mred*, mred-text*, mzc*, mzpp*, + mzscheme*, mztext*, pdf-slatex*, planet*, plt-games*, plt-help*, + plt-r5rs*, plt-r6rs*, plt-web-server*, racket*, racket-uninstall*, + raco*, scribble*, setup-plt*, slatex*, slideshow*, swindle*, tex2page* + sh> @i{ls -mF include && ls -mF lib && ls -mF share} + racket-@|N|/ + racket-@|N|/ + man/, racket-@|N|/ + sh> @i{ls -mF include/r*} + escheme.h, ext.exp, mzconfig.h, mzscheme3m.exp, scheme.h, schemef.h, + schemegc2.h, schemex.h, schemexm.h, schexn.h, schgc2obj.h, schthread.h, + schvers.h, sconfig.h, stypes.h, uconfig.h + sh> @i{ls -mF lib/r*} + buildinfo, collects/, libfit.so*, mzdyn3m.o, starter* + sh> @i{ls -mF share/r* && ls -mF share/r*/doc} + doc/ + README, @... xrepl/ + sh> @i{ls -mF share/man && ls -mF share/man/man1} + man1/ + drracket.1, gracket.1, mred.1, mzc.1, mzscheme.1, plt-help.1, racket.1, + raco.1, setup-plt.1, tex2page.1 + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{y} + @... + > @i{meh} + Base directory does not exist: meh + should I create it? (default: yes) @i{n} + Aborting installation. + sh> @i{touch m} + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{y} + @... + > @i{4} + @|| + Target Directories: + [e] Executables @|testdir|/bin (exists) + [r] Racket Code @|testdir|/lib/racket-@|N|/collects (exists) + [d] Core Docs @|testdir|/share/racket-@|N|/doc (exists) + [l] C Libraries @|testdir|/lib (exists) + [h] C headers @|testdir|/include/racket-@|N| (exists) + [o] Extra C Objs @|testdir|/lib/racket-@|N| (exists) + [m] Man Pages @|testdir|/share/man (exists) + Enter a letter to change an entry, or enter to continue. + > @i{m} + New directory (absolute or relative to @testdir): @i{m} + @|| + Target Directories: + [e] Executables @|testdir|/bin (exists) + [r] Racket Code @|testdir|/lib/racket-@|N|/collects (exists) + [d] Core Docs @|testdir|/share/racket-@|N|/doc (exists) + [l] C Libraries @|testdir|/lib (exists) + [h] C headers @|testdir|/include/racket-@|N| (exists) + [o] Extra C Objs @|testdir|/lib/racket-@|N| (exists) + [m] Man Pages @|testdir|/m (error: not a directory!) + Enter a letter to change an entry, or enter to continue. + > @i{} + *** Please fix erroneous paths to proceed + @... + Enter a letter to change an entry, or enter to continue. + > @i{m} + New directory (absolute or relative to @testdir): @i{man} + @|| + Target Directories: + [e] Executables @|testdir|/bin (exists) + [r] Racket Code @|testdir|/lib/racket-@|N|/collects (exists) + [d] Core Docs @|testdir|/share/racket-@|N|/doc (exists) + [l] C Libraries @|testdir|/lib (exists) + [h] C headers @|testdir|/include/racket-@|N| (exists) + [o] Extra C Objs @|testdir|/lib/racket-@|N| (exists) + [m] Man Pages @|testdir|/man (will be created) + Enter a letter to change an entry, or enter to continue. + > @i{} + @|| + A previous Racket uninstaller is found at + "@|testdir|/bin/racket-uninstall", + should I run it? (default: yes) @i{} + running uninstaller... done. + @|| + Checking the integrity of the binary archive... ok. + @... + Installation complete. + sh> @i{ls -mF} + bin/, include/, lib/, m, man/, share/ + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{y} + @... + > @i{4} + @... + > @i{} + @|| + A previous Racket uninstaller is found at + "@|testdir|/bin/racket-uninstall", + should I run it? (default: yes) @i{n} + Aborting installation. + sh> @i{rm -rf share} + sh> @i{sh @installer} + @... + Enter yes/no (default: no) > @i{y} + @... + > @i{4} + @... + [m] Man Pages @|testdir|/man (exists) + Enter a letter to change an entry, or enter to continue. + > @break + Error: Aborting... + sh> @i{ls -mF} + bin/, include/, lib/, m, man/ + sh> @i{exit} + @||}) + +(define (make-expect-script) + (printf "spawn sh\nproc abort {} { puts \"timeout!\\n\"; exit 1 }\n") + (printf "set timeout 60\n") + (define (tclq str) + ;; tcl uses $ and [] for variable & function call interpolation, and "}{" + ;; can confuse it; quote all of these + (regexp-replace* "[][{}$]" (format "~s" str) "\\\\&")) + (define (expect strs anchored?) + (unless (null? strs) + (define str (if (string? strs) strs (apply string-append strs))) + (let ([str (regexp-replace* "\r?\n" str "\r\n")]) + (printf "expect {\n timeout abort\n -re ~a\n}\n" + (tclq (if anchored? (string-append "^" str) str)))))) + (define (send strs) + (define str (if (string? strs) strs (apply string-append strs))) + (printf "send -- ~a\n" (tclq (string-append str "\n")))) + (let loop ([strs '()] [xs (transcript)] [anchored? #t]) + (define (do-expect) (expect (reverse strs) anchored?)) + (if (null? xs) + (do-expect) + (match (car xs) + ['... (do-expect) (loop '() (cdr xs) #f)] + [(? string? x) (loop (cons (regexp-quote x) strs) (cdr xs) anchored?)] + [`(s . ,sxs) (loop strs (append sxs (cdr xs)) anchored?)] + [`(r . ,rxs) (loop (append (reverse rxs) strs) (cdr xs) anchored?)] + [`(i . ,inps) (do-expect) (send inps) + (loop (map regexp-quote (reverse inps)) (cdr xs) #t)] + ['break (do-expect) (printf "send \"\\03\"\n") + (loop '("\\^C") (cdr xs) #t)] + [x (err "bad item in transcript: ~s" (car xs))]))) + (printf "expect eof\n")) + +(with-output-to-file "/tmp/racket-installer-expect-script" make-expect-script) +(sync-exe) ; we'll shuffle a lot of bytes, be prepared +(expect-exe "/tmp/racket-installer-expect-script") + +(delete-directory/files testdir) +(delete-file "/tmp/racket-installer-expect-script") + +(printf "\n--> All tests passed.\n") From 6efb5c1847270ed84504c61557f3841a64e93dc9 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Sun, 16 Oct 2011 16:31:50 -0400 Subject: [PATCH 404/746] on-release works without on-key; Closes PR12291 please propagate (cherry picked from commit 2a43c68dd7d5909c48f99079cb104cdcec8c5d8f) --- collects/2htdp/private/world.rkt | 11 +++++----- collects/2htdp/tests/on-release-no-key.rkt | 24 ++++++++++++++++++++++ collects/2htdp/universe.rkt | 2 +- collects/2htdp/xtest | 1 + 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 collects/2htdp/tests/on-release-no-key.rkt diff --git a/collects/2htdp/private/world.rkt b/collects/2htdp/private/world.rkt index 30a3e66e13..6216029528 100644 --- a/collects/2htdp/private/world.rkt +++ b/collects/2htdp/private/world.rkt @@ -52,8 +52,8 @@ (class* object% (start-stop<%>) (inspect #f) (init-field world0) - (init-field name state register check-with on-key on-mouse record?) - (init on-release on-receive on-draw stop-when) + (init-field name state register check-with on-key on-release on-mouse record?) + (init on-receive on-draw stop-when) ;; ----------------------------------------------------------------------- (field @@ -152,7 +152,8 @@ (show fst-scene))) (define/public (deal-with-key %) - (if (not on-key) % + (if (and (not on-key) (not on-release)) + % (class % (super-new) (define/override (on-char e) @@ -235,8 +236,8 @@ ;; ---------------------------------------------------------------------- ;; callbacks (field - (key on-key) - (release on-release) + (key (if on-key on-key (lambda (w ke) w))) + (release (if on-release on-release (lambda (w ke) w))) (mouse on-mouse) (rec on-receive)) diff --git a/collects/2htdp/tests/on-release-no-key.rkt b/collects/2htdp/tests/on-release-no-key.rkt new file mode 100644 index 0000000000..47eeadab58 --- /dev/null +++ b/collects/2htdp/tests/on-release-no-key.rkt @@ -0,0 +1,24 @@ +;; The first three lines of this file were inserted by DrRacket. They record metadata +;; about the language level of this file in a form that our tools can easily process. +#reader(lib "htdp-advanced-reader.ss" "lang")((modname on-release-no-key) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ()))) +;; Any key inflates the balloon + +(require 2htdp/image) +(require 2htdp/universe) + +(define large 50) + +(define (balloon b) + (if (<= b 10) + (text "press any key now" 22 'red) + (circle b "solid" "red"))) + +(define (blow-up b k) large) + +(define (deflate b) (max (- b 1) 1)) + +(big-bang 20 + (on-release blow-up) + (on-tick deflate) + (to-draw balloon 200 200) + (stop-when (lambda (w) (>= w large)))) diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index 01fb94b1dc..381773d2db 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -93,7 +93,7 @@ [on-key DEFAULT #f (function-with-arity 2)] ;; World KeyEvent -> World ;; on-release must specify a release event handler - [on-release DEFAULT #'K (function-with-arity 2)] + [on-release DEFAULT #f (function-with-arity 2)] ;; (U #f (World S-expression -> World)) ;; -- on-receive must specify a receive handler [on-receive DEFAULT #'#f (function-with-arity 2)] diff --git a/collects/2htdp/xtest b/collects/2htdp/xtest index 52553b9325..2efd7d3556 100755 --- a/collects/2htdp/xtest +++ b/collects/2htdp/xtest @@ -35,4 +35,5 @@ run record-stop-when.rkt run stop-when-crash.rkt run on-tick-universe-with-limit.rkt run on-tick-with-limit.rkt +run on-release-no-key.rkt From 58b46792693ec26559190cc2fc67d8b2a279a198 Mon Sep 17 00:00:00 2001 From: Rodolfo Carvalho Date: Sat, 15 Oct 2011 03:02:28 -0300 Subject: [PATCH 405/746] Add missing word 'one', clarify behavior of the 'semi-or-amp mode. (cherry picked from commit f43405543a89b2c61ccc9174cbc5657dff832653) --- collects/net/scribblings/uri-codec.scrbl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/collects/net/scribblings/uri-codec.scrbl b/collects/net/scribblings/uri-codec.scrbl index 17a8da688c..6429b238f4 100644 --- a/collects/net/scribblings/uri-codec.scrbl +++ b/collects/net/scribblings/uri-codec.scrbl @@ -131,8 +131,9 @@ associations in @racket[form-urlencoded->alist], The default value is @racket['amp-or-semi], which means that both @litchar{&} and @litchar{;} are treated as separators when parsing, -and @litchar{&} is used as a separator when encoding. The other modes -use/recognize only of the separators. +and @litchar{&} is used as a separator when encoding. The @racket['semi-or-amp] +mode is similar, but @litchar{;} is used when encoding. The other modes +use/recognize only one of the separators. @examples[ #:eval uri-codec-eval From b42223aa5d1f8f2943e7939f7ab3b7926f859099 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 17 Oct 2011 11:03:51 -0400 Subject: [PATCH 406/746] Add sqlite libraries to the `db' spec. (cherry picked from commit df4a227571b73d3970495261f6cf9a2518418af7) --- collects/meta/dist-specs.rkt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/collects/meta/dist-specs.rkt b/collects/meta/dist-specs.rkt index 4a1ae7bf04..d994a8e59c 100644 --- a/collects/meta/dist-specs.rkt +++ b/collects/meta/dist-specs.rkt @@ -686,8 +686,7 @@ mz-extras :+= (- (package: "unstable") plt-extras :+= (package: "plai/") ;; -------------------- rackunit & older schemeunit compatibility -plt-extras :+= (package: "rackunit/") -plt-extras :+= (package: "schemeunit/") +plt-extras :+= (package: "rackunit/") (package: "schemeunit/") ;; -------------------- racklog (aka schelog) plt-extras :+= (package: "racklog/") @@ -696,7 +695,7 @@ plt-extras :+= (package: "racklog/") plt-extras :+= (package: "datalog/") ;; -------------------- db -plt-extras :+= (package: "db/") +plt-extras :+= (package: "db/") (lib: "sqlite*") ;; ============================================================================ ;; Readme header From 29db510d2a30126fcb33bbec7cb8494bcedc8254 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 17 Oct 2011 11:08:23 -0400 Subject: [PATCH 407/746] Make the example `rebind' more like other rebinds in Emacs and others. (cherry picked from commit 6a323fe75e102f7cdfaa6fafb6b5497e676aa4ba) --- collects/scribblings/drracket/keybindings.scrbl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/collects/scribblings/drracket/keybindings.scrbl b/collects/scribblings/drracket/keybindings.scrbl index ac6eeb1749..71bd454679 100644 --- a/collects/scribblings/drracket/keybindings.scrbl +++ b/collects/scribblings/drracket/keybindings.scrbl @@ -239,13 +239,13 @@ name with the new keystroke you want, like this: @racketmod[ s-exp framework/keybinding-lang -(define (rebind name new) - (keybinding - new - (lambda (ed evt) - (send (send ed get-keymap) call-function name ed evt #t)))) +(define (rebind key command) + (keybinding + key + (λ (ed evt) + (send (send ed get-keymap) call-function command ed evt #t)))) -(rebind "backward-kill-word" "c:w") +(rebind "c:w" "backward-kill-word") ] Note that DrRacket does not reload keybindings files automatically when you From 6d49072822115bcf3e2b227ae66fbd07a65912f7 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 17 Oct 2011 11:45:43 -0400 Subject: [PATCH 408/746] Document `next-tab' and `prev-tab'. (cherry picked from commit 8f66afe5a6050c0ca19c6c02799d214c38f944ad) --- collects/scribblings/tools/unit.scrbl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/collects/scribblings/tools/unit.scrbl b/collects/scribblings/tools/unit.scrbl index 89caa2c932..0e7bc895ce 100644 --- a/collects/scribblings/tools/unit.scrbl +++ b/collects/scribblings/tools/unit.scrbl @@ -608,6 +608,14 @@ Returns the currently active tab. It loads that file in the definitions window of the new tab. } +@defmethod[(next-tab) void?]{ + Switches to the next tab. +} + +@defmethod[(prev-tab) void?]{ + Switches to the previous tab. +} + @defmethod[#:mode public-final (close-current-tab) void?]{ Closes the current tab, making some other tab visible. If there is only one tab open, this method does nothing. From e1ffc0dd9aa5bc9311e478733c232909eaa4e9eb Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 17 Oct 2011 11:47:41 -0400 Subject: [PATCH 409/746] Make `create-new-tab' public. (cherry picked from commit 319a158dec0052f3e4ab150405c9855342973002) --- collects/drracket/private/interface.rkt | 1 + collects/drracket/private/unit.rkt | 2 +- collects/scribblings/tools/unit.scrbl | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/collects/drracket/private/interface.rkt b/collects/drracket/private/interface.rkt index eafa17386c..c070e4db60 100644 --- a/collects/drracket/private/interface.rkt +++ b/collects/drracket/private/interface.rkt @@ -37,6 +37,7 @@ remain the same for tools that use them. execute-callback get-current-tab open-in-new-tab + create-new-tab close-current-tab on-tab-change enable-evaluation diff --git a/collects/drracket/private/unit.rkt b/collects/drracket/private/unit.rkt index 0cce7e97c9..0c5651583e 100644 --- a/collects/drracket/private/unit.rkt +++ b/collects/drracket/private/unit.rkt @@ -2770,7 +2770,7 @@ module browser threading seems wrong. ;; create-new-tab : -> void ;; creates a new tab and updates the GUI for that new tab - (define/private create-new-tab + (define/public create-new-tab (lambda ([filename #f]) (let* ([defs (new (drracket:get/extend:get-definitions-text))] [tab-count (length tabs)] diff --git a/collects/scribblings/tools/unit.scrbl b/collects/scribblings/tools/unit.scrbl index 0e7bc895ce..85fd7c1833 100644 --- a/collects/scribblings/tools/unit.scrbl +++ b/collects/scribblings/tools/unit.scrbl @@ -608,6 +608,10 @@ Returns the currently active tab. It loads that file in the definitions window of the new tab. } +@defmethod[(create-new-tab) void?]{ + Creates a new tab. +} + @defmethod[(next-tab) void?]{ Switches to the next tab. } From 1d6c344fffc0f17fd0177da8547f8a4e40e98205 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 17 Oct 2011 13:17:23 -0400 Subject: [PATCH 410/746] Add an example for old-style keys. (cherry picked from commit 016e6d771c602a163603c9a7db42f25935a99517) --- .../scribblings/drracket/keybindings.scrbl | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/collects/scribblings/drracket/keybindings.scrbl b/collects/scribblings/drracket/keybindings.scrbl index 71bd454679..319b4f4c7a 100644 --- a/collects/scribblings/drracket/keybindings.scrbl +++ b/collects/scribblings/drracket/keybindings.scrbl @@ -229,6 +229,35 @@ s-exp framework/keybinding-lang (keybinding "c:a" (λ (editor evt) (send editor insert "!"))) ] +Since the file contains plain Racket code, you can write keybindings +files that use DrRacket's @seclink[#:doc '(lib +"scribblings/tools/tools.scrbl") "implementing-tools"]{Extension API}. +For example, the following file binds ``control-t'' and ``control-='' to +a execute the program and open a new tab respectively, as they were used +before version 5.2. + +@racketmod[ +s-exp framework/keybinding-lang + +(require drracket/tool-lib) + +(define-syntax-rule (frame-key key command) + (keybinding + (format "~a:~a" + (case (get-default-shortcut-prefix) + [(ctl) "c"] [(cmd) "d"] [(alt meta) "m"] + [(shift) "s"] [(option) "a"]) + key) + (λ (ed evt) + (when (is-a? ed text:basic<%>) + (define fr (send ed get-top-level-window)) + ;; note: fr could be #f + (when fr (send fr command)))))) + +(frame-key "t" execute-callback) +(frame-key "=" create-new-tab) +] + Another example, this file rebinds ``control-w'' to delete the word behind the insertion point, but it does it by setting a new key to be an existing keyboard shortcut. If you see a key in the From 47460ac45137401328a167596e8e60610394db47 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 17 Oct 2011 14:09:26 -0400 Subject: [PATCH 411/746] Remove preference for old-style menu bindings, and instead add a sample keybindings file that does that. (This reverts most of commit 26f6c588fcfa45a1a12c275e5824aede8ba23e3e.) (cherry picked from commit c66c669ee36e106fefafd92c5cf5513accf16f7c) --- collects/drracket/private/main.rkt | 6 +----- collects/drracket/private/unit.rkt | 9 ++------- .../private/english-string-constants.rkt | 3 +-- .../string-constants/private/german-string-constants.rkt | 1 - doc/release-notes/drracket/HISTORY.txt | 9 +++++---- 5 files changed, 9 insertions(+), 19 deletions(-) diff --git a/collects/drracket/private/main.rkt b/collects/drracket/private/main.rkt index dde8826d47..10eabae455 100644 --- a/collects/drracket/private/main.rkt +++ b/collects/drracket/private/main.rkt @@ -84,7 +84,7 @@ ll)))) (drr:set-default 'drracket:module-language-first-line-special? #t boolean?) -(drr:set-default 'drracket:use-old-style-keybindings #f boolean?) + (drr:set-default 'drracket:defns-popup-sort-by-name? #f boolean?) (drr:set-default 'drracket:show-line-numbers? #f boolean?) @@ -297,10 +297,6 @@ (make-check-box 'drracket:module-language-first-line-special? (string-constant ml-always-show-#lang-line) - editor-panel) - - (make-check-box 'drracket:use-old-style-keybindings - (string-constant old-style-keybindings) editor-panel))) (preferences:add-to-editor-checkbox-panel diff --git a/collects/drracket/private/unit.rkt b/collects/drracket/private/unit.rkt index 0c5651583e..30833abb8b 100644 --- a/collects/drracket/private/unit.rkt +++ b/collects/drracket/private/unit.rkt @@ -3380,7 +3380,7 @@ module browser threading seems wrong. (set! file-menu:create-new-tab-item (new menu:can-restore-menu-item% (label (string-constant new-tab)) - (shortcut (if (preferences:get 'drracket:use-old-style-keybindings) #\= #\t)) + (shortcut #\t) (parent file-menu) (callback (λ (x y) @@ -3459,13 +3459,8 @@ module browser threading seems wrong. (preferences:get 'framework:print-output-mode))))) (super file-menu:between-print-and-close file-menu)) - (inherit edit-menu:get-replace-item) (define/override (edit-menu:between-find-and-preferences edit-menu) (super edit-menu:between-find-and-preferences edit-menu) - (when (preferences:get 'drracket:use-old-style-keybindings) - (define item (edit-menu:get-replace-item)) - (send item set-shortcut #\r) - (send item set-shortcut-prefix (get-default-shortcut-prefix))) (new menu:can-restore-menu-item% [label (string-constant complete-word)] [shortcut #\/] @@ -3676,7 +3671,7 @@ module browser threading seems wrong. (string-constant execute-menu-item-label) language-specific-menu (λ (_1 _2) (execute-callback)) - (if (preferences:get 'drracket:use-old-style-keybindings) #\t #\r) + #\r (string-constant execute-menu-item-help-string))) (make-object menu:can-restore-menu-item% (string-constant ask-quit-menu-item-label) diff --git a/collects/string-constants/private/english-string-constants.rkt b/collects/string-constants/private/english-string-constants.rkt index 95aaf54a6b..454901d4a1 100644 --- a/collects/string-constants/private/english-string-constants.rkt +++ b/collects/string-constants/private/english-string-constants.rkt @@ -492,7 +492,6 @@ please adhere to these guidelines: (show-interactions-on-execute "Automatically open interactions window when running a program") (switch-to-module-language-automatically "Automatically switch to the module language when opening a module") (interactions-beside-definitions "Put the interactions window beside the definitions window") ;; in preferences, below the checkbox one line above this one - (old-style-keybindings "Old-style keybindings (Run: -t; New-tab: -=; Replace: -r)") (show-line-numbers "Show line numbers") (show-line-numbers/menu "Show Line &Numbers") ;; just like the above, but capitalized for appearance in a menu item (hide-line-numbers/menu "Hide Line &Numbers") @@ -1395,7 +1394,7 @@ please adhere to these guidelines: ;; title of this section of the dialog (possibly the word ;; `Collection' should not be translated) (ml-cp-collection-paths "Collection Paths") - + ;; button labels (ml-cp-add "Add") (ml-cp-add-default "Add Default") diff --git a/collects/string-constants/private/german-string-constants.rkt b/collects/string-constants/private/german-string-constants.rkt index 3889fa6273..5d08555427 100644 --- a/collects/string-constants/private/german-string-constants.rkt +++ b/collects/string-constants/private/german-string-constants.rkt @@ -389,7 +389,6 @@ (open-files-in-tabs "Dateien in separaten Tabs öffnen (nicht separaten Fenstern)") (show-interactions-on-execute "Interaktionen beim Programmstart automatisch öffnen") (switch-to-module-language-automatically "Automatisch in die `module'-Sprache wechseln, wenn ein Modul geöffnet wird") - (old-style-keybindings "Historische Tastaturbelegungkeybindings (Start: -t; Neuer Tab: -=; Ersetzen: -r)") (interactions-beside-definitions "Interaktionen neben den Definitionen anzeigen") ;; in preferences, below the checkbox one line above this one (show-line-numbers "Zeilennummern einblenden") (show-line-numbers/menu "Zeilen&nummern einblenden") diff --git a/doc/release-notes/drracket/HISTORY.txt b/doc/release-notes/drracket/HISTORY.txt index 59ba90b665..6312b95b24 100644 --- a/doc/release-notes/drracket/HISTORY.txt +++ b/doc/release-notes/drracket/HISTORY.txt @@ -2,13 +2,14 @@ Version 5.2 ------------------------------ - . changed a three menu keybidings: + . changed three menu keybidings: "New Tab" is now -t "Run" is now -r "Replace" is now -shift-f - The preferences dialog (general tab) has a checkbox to - restore the old behavior. + The Keyboard Shortcuts section in the manual has a sample + keybindings file a checkbox that restores the old behavior of + the first two. . Under Windows, DrRacket now saves files, in some situations, with LF terminators. Previously, under windows, all files @@ -26,7 +27,7 @@ . removed the "open here" functionality (both from the DrRacket app and from the framework library) - . 2htdp/image: + . 2htdp/image: - shrunk the size of saved files that contain 2htdp/image bitmaps (you can get these by copying and pasting from the REPL; using "insert image" isn't affected) From 1d7e5f3cbc6a158d14b4b1172a6def36454c5cc7 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 17 Oct 2011 14:32:23 -0400 Subject: [PATCH 412/746] Remove the unneeded `require' in that example. (cherry picked from commit 7bff0e888d5866b9b884e9d153b866d5d33a8e7e) --- collects/scribblings/drracket/keybindings.scrbl | 2 -- 1 file changed, 2 deletions(-) diff --git a/collects/scribblings/drracket/keybindings.scrbl b/collects/scribblings/drracket/keybindings.scrbl index 319b4f4c7a..c0aaf1c18a 100644 --- a/collects/scribblings/drracket/keybindings.scrbl +++ b/collects/scribblings/drracket/keybindings.scrbl @@ -239,8 +239,6 @@ before version 5.2. @racketmod[ s-exp framework/keybinding-lang -(require drracket/tool-lib) - (define-syntax-rule (frame-key key command) (keybinding (format "~a:~a" From 17d0749a26614c64130121aafe6e79d3033beb99 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 17 Oct 2011 06:55:04 -0700 Subject: [PATCH 413/746] fix a type name Closes PR 12297 Merge to 5.2 (cherry picked from commit 099e4d7dad9767ed95f0e617fc627a94ac2eb899) --- src/racket/src/type.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/racket/src/type.c b/src/racket/src/type.c index 399e148266..67b2052928 100644 --- a/src/racket/src/type.c +++ b/src/racket/src/type.c @@ -300,6 +300,9 @@ scheme_init_type () set_name(scheme_place_type, ""); set_name(scheme_place_async_channel_type, ""); set_name(scheme_place_bi_channel_type, ""); + set_name(scheme_place_dead_type, ""); + + set_name(scheme_resolved_module_path_type, ""); #ifdef MZ_GC_BACKTRACE set_name(scheme_rt_meta_cont, ""); @@ -388,9 +391,14 @@ Scheme_Type scheme_make_type(const char *name) char *scheme_get_type_name(Scheme_Type t) { + char *s; if (t < 0 || t >= maxtype) return ""; - return type_names[t]; + s = type_names[t]; + if (!s) + return "???"; + else + return s; } void scheme_install_type_reader(Scheme_Type t, Scheme_Type_Reader f) From 4b46e79b55ab5f524ef73874356d2dd1cef92b47 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 17 Oct 2011 16:12:20 -0400 Subject: [PATCH 414/746] Fix typo in htdp url. Fixes PR 12282. (Which was closed prematurely.) (cherry picked from commit 3b93da83c49627625f353b1cf3bc19ae93564308) --- collects/scribblings/main/getting-started.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/main/getting-started.scrbl b/collects/scribblings/main/getting-started.scrbl index 3faf230554..a7af167473 100644 --- a/collects/scribblings/main/getting-started.scrbl +++ b/collects/scribblings/main/getting-started.scrbl @@ -8,7 +8,7 @@ through a textbook: @itemize[ - @item{@italic{@link["http:///www.htdp.org/"]{How to Design Programs}} + @item{@italic{@link["http://htdp.org/"]{How to Design Programs}} is the best place to start. Whenever the book says ``Scheme,'' you can read it as ``Racket.''} From 124688fa51074a379448a7d9b380937e8eb29bd4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 17 Oct 2011 15:52:14 -0600 Subject: [PATCH 415/746] gtk: no freeze/thaw before/after unmap Merge to 5.2 (cherry picked from commit a09543772a93ca8d7cf58fa2c4e60f3c559f031b) --- collects/mred/private/wx/gtk/canvas.rkt | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/collects/mred/private/wx/gtk/canvas.rkt b/collects/mred/private/wx/gtk/canvas.rkt index abe4cff19c..03736853ea 100644 --- a/collects/mred/private/wx/gtk/canvas.rkt +++ b/collects/mred/private/wx/gtk/canvas.rkt @@ -209,6 +209,13 @@ (when wx (send wx unrealize))))) +(define-signal-handler connect-unmap "unmap" + (_fun _GtkWidget -> _void) + (lambda (gtk) + (let ([wx (gtk->wx gtk)]) + (when wx + (send wx unrealize))))) + (define (do-value-changed gtk dir) (let ([wx (gtk->wx gtk)]) (when wx @@ -385,6 +392,7 @@ (when combo-button-gtk (connect-combo-key-and-mouse combo-button-gtk)) (connect-unrealize client-gtk) + (connect-unmap client-gtk) (when hscroll-adj (connect-value-changed-h hscroll-adj)) (when vscroll-adj (connect-value-changed-v vscroll-adj)) @@ -467,11 +475,14 @@ (define flush-win-box (mcons #f 0)) (define/public (get-flush-window) (atomically - (if (win-box-valid? flush-win-box) - flush-win-box - (begin - (set! flush-win-box (window->win-box (widget-window client-gtk))) - flush-win-box)))) + (if (zero? (bitwise-and (get-gtk-object-flags client-gtk) + GTK_MAPPED)) + (mcons #f #f) + (if (win-box-valid? flush-win-box) + flush-win-box + (begin + (set! flush-win-box (window->win-box (widget-window client-gtk))) + flush-win-box))))) (define/public (unrealize) (unrealize-win-box flush-win-box)) From 856664c7e6bd68aa1f096b41c588c729cfff00df Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 18 Oct 2011 06:33:30 -0600 Subject: [PATCH 416/746] fix cocoa `get-clipboard-string' to never return #f; fix docs Merge to 5.2 (cherry picked from commit 718229387c05daba0c2cce9f68f757e72fe0ad2d) --- collects/mred/private/wx/cocoa/clipboard.rkt | 5 +++-- collects/scribblings/gui/clipboard-intf.scrbl | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/collects/mred/private/wx/cocoa/clipboard.rkt b/collects/mred/private/wx/cocoa/clipboard.rkt index 2556146cd2..e64d9a5c89 100644 --- a/collects/mred/private/wx/cocoa/clipboard.rkt +++ b/collects/mred/private/wx/cocoa/clipboard.rkt @@ -80,8 +80,9 @@ (define/public (get-text-data) (let ([bstr (get-data "TEXT")]) - (and bstr - (bytes->string/utf-8 bstr #\?)))) + (or (and bstr + (bytes->string/utf-8 bstr #\?)) + ""))) (define/public (get-data type) (atomically diff --git a/collects/scribblings/gui/clipboard-intf.scrbl b/collects/scribblings/gui/clipboard-intf.scrbl index 1155754ff6..c2afe28627 100644 --- a/collects/scribblings/gui/clipboard-intf.scrbl +++ b/collects/scribblings/gui/clipboard-intf.scrbl @@ -29,7 +29,7 @@ Generic data is always retrieved from the clipboard as a byte @defmethod[(get-clipboard-bitmap [time exact-integer?]) - (or/c (is-a?/c bitmap%) false/c)]{ + (or/c (is-a?/c bitmap%) #f)]{ Gets the current clipboard contents as a bitmap (Windows, Mac OS X), returning @racket[#f] if the clipboard does not contain a bitmap. @@ -43,9 +43,9 @@ See @|timediscuss| for a discussion of the @racket[time] argument. If } -@defmethod[(get-clipboard-data [format string] +@defmethod[(get-clipboard-data [format string?] [time exact-integer?]) - (or/c bytes? string? false/c)]{ + (or/c bytes? string? #f)]{ Gets the current clipboard contents in a specific format, returning @racket[#f] if the clipboard does not contain data in the requested @@ -66,10 +66,10 @@ See @|timediscuss| for a discussion of the @racket[time] argument. If } @defmethod[(get-clipboard-string [time exact-integer?]) - (or/c string false/c)]{ + string?]{ Gets the current clipboard contents as simple text, returning - @racket[#f] if the clipboard does not contain any text. + @racket[""] if the clipboard does not contain any text. See @method[clipboard<%> get-clipboard-data] for information on eventspaces and the current clipboard client. @@ -117,7 +117,7 @@ See @|timediscuss| for a discussion of the @racket[time] argument. If } -@defmethod[(set-clipboard-string [new-text string] +@defmethod[(set-clipboard-string [new-text string?] [time exact-integer?]) void?]{ From 69077c6f57640fe28a6c1967a60d37fa1ceecb22 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 18 Oct 2011 06:46:30 -0600 Subject: [PATCH 417/746] update Racket history for v5.2 Merge to 5.2 (cherry picked from commit ff839d1cdac02e30a3ecbdc330496e03bb52a6dc) --- doc/release-notes/racket/HISTORY.txt | 100 +++++++++++---------------- 1 file changed, 40 insertions(+), 60 deletions(-) diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index cc8550b0c0..6d12b44577 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,77 +1,57 @@ -Version 5.1.3.12 -Removed built-in support for Honu reading and printing -racket/gui: moved set-icon method from frame% to - top-level-window<%> - -Version 5.1.3.11 -Added exn:fail:syntax:unbound -Added date*, which extends date to include nanoseconds and a - time zone name -Changed seconds->date to accept a real number return a date* -Added support for redirections to get-pure-port - -Version 5.1.3.10 -Added variable-reference->module-declare-inspector, which allows - a macro or other syntax tool to get the enclosing module's - declaration-time inspector for taint operations -Removed the Racket-to-C compiler: raco ctool -e/-c, mzc -e/-c, - compile-extensions, compile-extensions-to-c, compile-c-extensions, - compiler/cffi, compiler/comp-unit, compiler:inner^, and most - options in compiler/option - -Version 5.1.3.9 -Add syntax-shift-phase-level -errortrace: with-mark and make-st-mark now take a phase level -place:place* and dynamic place* forms now take in, out, and err named - arguments which become the standard io ports for the new place - -Version 5.1.3.8 -Add syntax-transforming-module-expression? and - variable-reference->module-base-phase - -Version 5.1.3.7 +Version 5.2, November 2011 Generalized begin-with-syntax to allow phase-N definitions, both variable and syntax, within a module for all N >= 0; removed define-values-for-syntax from fully expanded forms; added begin-with-syntax to fully expanded forms +Changed the location-creation semantics of internal definitions + and letrec-syntaxes+values (to make them more let-like) +Added support for the collection links file, including + (find-system-path 'links-file) and the raco link command +Added exn:fail:syntax:unbound +Added date*, which extends date to include nanoseconds and a + time zone name +Changed seconds->date to accept a real number return a date* +Added set-port-next-location! and changed the default prompt + read handler to use it when input and output ar terminals Changed syntax-local-module-defined-identifiers to return a table for all phases instead of just two values +Add syntax-transforming-module-expression? and + variable-reference->module-base-phase +Added variable-reference->module-declare-inspector, which allows + a macro or other syntax tool to get the enclosing module's + declaration-time inspector for taint operations +Added syntax-shift-phase-level +Removed built-in support for Honu reading and printing +racket/unsafe/ops: added unsafe-list-ref and unsafe-list-tail +ffi/unsafe: added support for C arrays and unions +ffi/unsafe: changed define-cstruct to use an interned symbol tag, + which means that it is not generative +racket/place: added place* and dynamic-place* to specify the input, + output, and error ports to use for a new place +racket/place: cpointers, file-stream ports, and TCP ports can be + sent across place channels +racket/gui: moved set-icon method from frame% to + top-level-window<%> +racket/gui: removed unsupported MDI styles and method +errortrace: with-mark and make-st-mark now take a phase level compiler/zo-structs: removed def-for-syntax, added seq-for-syntax, changed some mod fields, added field to def-syntaxes - -Version 5.1.3.6 -unsafe/ffi:Changed cstructs to not be generative. -place:cpointers and file descriptors can now be sent across - place channels. - -Version 5.1.3.4 -Add support for the collection links file, including - (find-system-path 'links-file) and the raco link command - -Version 5.1.3.3 -unsafe/ffi: added support for C arrays and unions -Fixed the planet module-name-resolver to be thread safe -mrlib/include-bitmap: Adjust include-bitmap so it does not - write to the filesystem -framework: the finder get-file & put-file dialogs no +net/url: added support for redirections to get-pure-port +planet: made the planet module-name-resolver thread-safe, and + fixed planet to use already-downloaded .plt files (when present) +framework: the finder get-file and put-file dialogs no longer normalize their results framework: added to the testing library so that tests can be run when ignoring focus information from the underlying OS - -Version 5.1.2.3 -Added set-port-next-location! and changed the default prompt - read handler to use it when input and output ar terminals -racket/gui: removed unsupported MDI styles and method compiler/cm: added support for using more powerful security-guards when writing to the filesystem -Fixed an old bug so that planet now uses the already-downloaded - .plt files (when present) - -Version 5.1.2.2 -Changed the location-creation semantics of internal definitions - and `letrec-syntaxes+values' -Added unsafe-list-ref and unsafe-list-tail +mrlib/include-bitmap: adjust include-bitmap so it does not + write to the filesystem +Removed the Racket-to-C compiler: raco ctool -e/-c, mzc -e/-c, + compile-extensions, compile-extensions-to-c, compile-c-extensions, + compiler/cffi, compiler/comp-unit, compiler:inner^, and most + options in compiler/option Version 5.1.3, August 2011 No changes From b2e1bd0645033e5fde6eae2b34148c15712339e6 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Tue, 18 Oct 2011 12:35:42 -0400 Subject: [PATCH 418/746] history for teachpacks updated; please propagate (cherry picked from commit 38b802dde454f0e6a675a10e31f86e7f05cf2f2a) --- doc/release-notes/teachpack/HISTORY.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/release-notes/teachpack/HISTORY.txt b/doc/release-notes/teachpack/HISTORY.txt index 6b3dd4925d..3af6014397 100644 --- a/doc/release-notes/teachpack/HISTORY.txt +++ b/doc/release-notes/teachpack/HISTORY.txt @@ -1,3 +1,9 @@ +------------------------------------------------------------------------ +Version 5.2 [Tue Oct 18 12:34:16 EDT 2011] + +* bug fixes in 2htdp/universe +* also, on-release now works without presence of an on-key clause + ------------------------------------------------------------------------ Version 5.1.2 [Fri Jul 22 15:27:37 EDT 2011] From 0eb11080c20797cf19b01bb5983798831ee6f394 Mon Sep 17 00:00:00 2001 From: Carl Eastlund Date: Tue, 18 Oct 2011 16:17:54 -0400 Subject: [PATCH 419/746] Fixed a typo (syntax-quote => quote-syntax). (cherry picked from commit bb828c312ffa8d63ee625b1d2492378473c531c3) --- collects/planet/scribble.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/planet/scribble.rkt b/collects/planet/scribble.rkt index f858ee6e92..a03cdf3a4a 100644 --- a/collects/planet/scribble.rkt +++ b/collects/planet/scribble.rkt @@ -86,7 +86,7 @@ (syntax-parser #:literals [unsyntax] [(~and orig (_ (unsyntax e:expr))) #'(racketmodname - (unsyntax `(planet ,(make-planet-symbol (syntax-quote orig) e))))] + (unsyntax `(planet ,(make-planet-symbol (quote-syntax orig) e))))] [(_ suffix:id/this-package) #'(racketmodname (planet suffix.planet-id))])) From 34f3b16626b3a0e50a1d5eddf8796b5ff91a7daa Mon Sep 17 00:00:00 2001 From: Carl Eastlund Date: Tue, 18 Oct 2011 16:18:32 -0400 Subject: [PATCH 420/746] Made constructed planet links force the minor version for more reliable self-reference. (cherry picked from commit cc70834024161a1f81b9c69f13a4ccdb0aad2032) --- collects/planet/syntax.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/planet/syntax.rkt b/collects/planet/syntax.rkt index 43b62fdfbb..6768d538ff 100644 --- a/collects/planet/syntax.rkt +++ b/collects/planet/syntax.rkt @@ -43,7 +43,7 @@ (match (syntax-source-planet-package stx) [(list owner name major minor) (string->symbol - (format "~a/~a:~a:~a~a" + (format "~a/~a:~a:=~a~a" owner (regexp-replace "\\.plt$" name "") major From a82a55074baf130cd2aa79d22ed9d7fe1ff0528b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 18 Oct 2011 20:41:44 -0600 Subject: [PATCH 421/746] fix a marshaling bug for syntax objects Closes PR 12300 Merge to 5.2 (cherry picked from commit a81054fef44ca0844acd35fd5ebececdde78e80a) --- collects/tests/racket/stx.rktl | 55 ++++++++++++++++++++++++++++++++++ src/racket/src/syntax.c | 17 +++++++---- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/collects/tests/racket/stx.rktl b/collects/tests/racket/stx.rktl index cb2cd2520a..a13e853602 100644 --- a/collects/tests/racket/stx.rktl +++ b/collects/tests/racket/stx.rktl @@ -1611,6 +1611,61 @@ (displayln (syntax-transforming-module-expression?)))))) (test "#t\n#f\n" get-output-string o)) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check that a common wraps encoding that is detected only +;; after simplification and encoding is shared propery. If +;; it's not shared properly in this example, a gensym for +;; the internal-definition context gets duplicated. + +(parameterize ([current-namespace (make-base-namespace)]) + (define e + (compile '(module producer racket/base + (#%module-begin + + (require (for-syntax racket/base)) + + (define-syntax (compare stx) + (syntax-case stx () + [(_ formal body) + (let () + + (define (internal-definition-context-apply ctx s) + (syntax-case (local-expand #`(quote-syntax #,s) + 'expression + (list #'quote-syntax) + ctx) () + [(qs e) #'e])) + + (define ctx (syntax-local-make-definition-context)) + (syntax-local-bind-syntaxes (list #'formal) #f ctx) + (internal-definition-context-seal ctx) + + (with-syntax ([one + (internal-definition-context-apply ctx #'formal)] + [two + (syntax-local-introduce + (internal-definition-context-apply + ctx + (syntax-local-introduce + (internal-definition-context-apply ctx #'body))))]) + + (unless (free-identifier=? #'one #'two) + (error 'before + "identifiers were never the same")) + + #'(begin-for-syntax + (unless (free-identifier=? #'one #'two) + (error 'after + "identifiers used to be the same, but now are not")))))])) + + (compare z z))))) + (let ([o (open-output-bytes)]) + (write e o) + (parameterize ([read-accept-compiled #t]) + (eval (read (open-input-bytes (get-output-bytes o)))))) + (namespace-require ''producer) + (eval 10)) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/src/racket/src/syntax.c b/src/racket/src/syntax.c index aa412dd65a..5da668595f 100644 --- a/src/racket/src/syntax.c +++ b/src/racket/src/syntax.c @@ -3764,7 +3764,7 @@ static Scheme_Object *resolve_env(Scheme_Object *a, Scheme_Object *orig_phase, scheme_write_to_string(((Scheme_Modidx *)result)->path, NULL), scheme_write_to_string(((Scheme_Modidx *)result)->base, NULL))); } else { - EXPLAIN(fprintf(stderr, "%d Result: %s\n", depth, scheme_write_to_string(result, NULL))); + EXPLAIN(fprintf(stderr, "%d Result: %s %p\n", depth, scheme_write_to_string(result, NULL), result)); } if (get_names) { EXPLAIN(fprintf(stderr, "%d phase %s\n", depth, scheme_write_to_string(get_names[3], NULL))); @@ -5075,12 +5075,17 @@ Scheme_Object *scheme_flatten_syntax_list(Scheme_Object *lst, int *islist) #define EXPLAIN_SIMP 0 #if EXPLAIN_SIMP #define EXPLAIN_S(x) if (explain_simp) x -static int explain_simp = 0; +static int explain_simp = 1; static void print_skips(Scheme_Object *skips) { while (skips) { - fprintf(stderr, " skip %s\n", scheme_write_to_string(SCHEME_CAR(skips), NULL)); - skips = SCHEME_CDR(skips); + if (SCHEME_PAIRP(skips)) { + fprintf(stderr, " skip %s\n", scheme_write_to_string(SCHEME_CAR(skips), NULL)); + skips = SCHEME_CDR(skips); + } else { + fprintf(stderr, " skip val %s\n", scheme_write_to_string(skips, NULL)); + skips = NULL; + } } } #else @@ -5273,7 +5278,7 @@ static Scheme_Object *simplify_lex_renames(Scheme_Object *wraps, Scheme_Hash_Tab EXPLAIN_S(fprintf(stderr, "[in simplify]\n")); - EXPLAIN_R(printf("Simplifying %p\n", lex_cache)); + EXPLAIN_R(printf("Simplifying %p %s\n", lex_cache, scheme_write_to_string(stx_datum, NULL))); while (!WRAP_POS_END_P(w)) { if (SCHEME_VECTORP(WRAP_POS_FIRST(w)) @@ -6224,7 +6229,6 @@ static Scheme_Object *wraps_to_datum(Scheme_Object *stx_datum, return scheme_hash_get(rns, old_key); } else { a = scheme_marshal_lookup(mt, old_key); - scheme_marshal_using_key(mt, old_key); if (!mt->same_map) { Scheme_Hash_Table *same_map; same_map = scheme_make_hash_table(SCHEME_hash_ptr); @@ -6233,6 +6237,7 @@ static Scheme_Object *wraps_to_datum(Scheme_Object *stx_datum, scheme_hash_set(mt->same_map, w_in, old_key); /* nevermind references that we saw when creating `stack': */ scheme_marshal_pop_refs(mt, 0); + scheme_marshal_using_key(mt, old_key); return a; } } From a38f02160e05a249175b82c435fcae2327f24458 Mon Sep 17 00:00:00 2001 From: Casey Klein Date: Wed, 19 Oct 2011 13:32:59 -0500 Subject: [PATCH 422/746] Updates Redex history for v5.2 Merge to release branch (cherry picked from commit 210a6f329ee19ad44bb5d321f5386a1a3cd42227) --- doc/release-notes/redex/HISTORY.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/release-notes/redex/HISTORY.txt b/doc/release-notes/redex/HISTORY.txt index 55e838c326..9c95c3cff9 100644 --- a/doc/release-notes/redex/HISTORY.txt +++ b/doc/release-notes/redex/HISTORY.txt @@ -1,3 +1,15 @@ +v5.2 + + * added define-judgment-form form + + * added define-term form + + * added with-compound-rewriters form + + * added Ariola-Felleisen by-need evaluation contexts to examples + + * improved error message for definition forms in expression contexts + v5.1.2 * added support for typsetting define-relation relations From cb6be016c63903d262ce4dd0cbfb62eecf33676c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 20 Oct 2011 14:01:26 -0600 Subject: [PATCH 423/746] CGC fix for OpenBSD x86_64 Merge to 5.2 (cherry picked from commit a4011890e17f91332753240ddb9a2d3598fe8c79) --- src/racket/gc/include/private/gcconfig.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/racket/gc/include/private/gcconfig.h b/src/racket/gc/include/private/gcconfig.h index 3eb01a4b7f..5d8ab05f8f 100644 --- a/src/racket/gc/include/private/gcconfig.h +++ b/src/racket/gc/include/private/gcconfig.h @@ -1983,8 +1983,9 @@ # define STACKBOTTOM USRSTACK # endif extern int __data_start[]; -# define DATASTART ((ptr_t)(__data_start)) - extern char _end[]; +/* PLTSCHEME: commented out these two: */ +/*# define DATASTART ((ptr_t)(__data_start)) */ +/* extern char _end[]; */ # define DATAEND ((ptr_t)(&_end)) # define DYNAMIC_LOADING # endif From 1c745c59a02e85ea647d44e7dfcf693415dd1fa9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 20 Oct 2011 14:26:07 -0600 Subject: [PATCH 424/746] fix JIT early reference to JIT generated address On x86_64, if the scratch-space address fits into 32 bits and the final place for shared code doesn't fit into a 32-bit address, then the size of the generated code could change, leading to a JIT buffer overflow. Merge to 5.2 (cherry picked from commit 35526a7bd73ad554fabbcf121822e9859fe3de59) --- src/racket/src/jitcommon.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/racket/src/jitcommon.c b/src/racket/src/jitcommon.c index 55722efadb..4658fb68bf 100644 --- a/src/racket/src/jitcommon.c +++ b/src/racket/src/jitcommon.c @@ -2597,7 +2597,8 @@ static int common10(mz_jit_state *jitter, void *_data) jit_ldxi_i(JIT_R2, JIT_V1, &((Scheme_Native_Closure_Data *)0x0)->closure_size); (void)jit_blti_i(refslow, JIT_R2, 0); /* case lambda */ jit_ldxi_p(JIT_R2, JIT_V1, &((Scheme_Native_Closure_Data *)0x0)->code); - ref_nc = jit_beqi_p(jit_forward(), JIT_R2, scheme_on_demand_jit_code); /* not yet JITted */ + jit_movi_p(JIT_V1, scheme_on_demand_jit_code); /* movi_p doesn't depends on actual address, which might change size */ + ref_nc = jit_beqr_p(jit_forward(), JIT_R2, JIT_V1); /* not yet JITted? */ jit_rshi_l(JIT_V1, JIT_R1, 1); jit_addi_l(JIT_V1, JIT_V1, 1); CHECK_LIMIT(); @@ -2614,6 +2615,7 @@ static int common10(mz_jit_state *jitter, void *_data) /* not-yet-JITted native: */ mz_patch_branch(ref_nc); + jit_ldxi_p(JIT_V1, JIT_R0, &((Scheme_Native_Closure *)0x0)->code); jit_ldxi_p(JIT_R0, JIT_V1, &((Scheme_Native_Closure_Data *)0x0)->u2.orig_code); jit_rshi_l(JIT_V1, JIT_R1, 1); jit_ldxi_i(JIT_R2, JIT_R0, &((Scheme_Closure_Data *)0x0)->num_params); From c6e1796afad27cdeafbacf4ba3afc5e47a034cd9 Mon Sep 17 00:00:00 2001 From: John Clements Date: Fri, 21 Oct 2011 02:17:03 -0700 Subject: [PATCH 425/746] updated history Merge to 5.2 (cherry picked from commit e830fb1b38e1c273e05513b1f1c68368e91f42e9) --- doc/release-notes/stepper/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes/stepper/HISTORY.txt b/doc/release-notes/stepper/HISTORY.txt index 381b630f9f..f900a225ab 100644 --- a/doc/release-notes/stepper/HISTORY.txt +++ b/doc/release-notes/stepper/HISTORY.txt @@ -1,6 +1,10 @@ Stepper ------- +Changes for v5.2: + +None. + Changes for v5.1.2: Support for 'require' in stepped programs, fixed a number of From 564f9d0062444e9b65cafc437801719e79d06e34 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Fri, 21 Oct 2011 07:26:55 -0500 Subject: [PATCH 426/746] adjust HtDP teaching languages' first and rest so that they accept circular lists. This commit fix an unintentional change introduced by this commit: c7d67f9babc2496aaf295a08264b79750785314b (and it also adds in test cases for what that commit appears to have been doing) Assuming everyone agrees that the behavior for first rest from back in 2010 is the behavior we still want (and the lack of release notes on the subject makes me believe that we do), then: Please include in 5.2. (cherry picked from commit 7acc5b78521ca86acd58e3e871af07bc2a3c716e) --- collects/deinprogramm/signature/signature-unit.rkt | 2 +- collects/tests/htdp-lang/advanced.rktl | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/collects/deinprogramm/signature/signature-unit.rkt b/collects/deinprogramm/signature/signature-unit.rkt index 2059bb7fc4..c608317da0 100644 --- a/collects/deinprogramm/signature/signature-unit.rkt +++ b/collects/deinprogramm/signature/signature-unit.rkt @@ -5,7 +5,7 @@ (require scheme/promise mzlib/struct - (only-in racket/list first rest) + (only-in mzlib/list first rest) (for-syntax scheme/base) (for-syntax stepper/private/shared)) diff --git a/collects/tests/htdp-lang/advanced.rktl b/collects/tests/htdp-lang/advanced.rktl index 0a82c83f47..dc6c8d89ba 100644 --- a/collects/tests/htdp-lang/advanced.rktl +++ b/collects/tests/htdp-lang/advanced.rktl @@ -174,6 +174,14 @@ (htdp-test 1 car (shared ([x (cons 1 x)]) x)) (htdp-test 1 cadr (shared ([x (cons 1 x)][y (cons 2 x)]) y)) (htdp-test 1 cadddr (shared ([x (cons 1 x)][y (cons 2 x)]) y)) +(htdp-test 1 first (shared ([x (cons 1 x)]) x)) +(htdp-test 1 second (shared ([x (cons 1 x)]) x)) +(htdp-test 1 third (shared ([x (cons 1 x)]) x)) +(htdp-test 1 fourth (shared ([x (cons 1 x)]) x)) +(htdp-test 1 fifth (shared ([x (cons 1 x)]) x)) +(htdp-test 1 sixth (shared ([x (cons 1 x)]) x)) +(htdp-test 1 seventh (shared ([x (cons 1 x)]) x)) +(htdp-test 1 eighth (shared ([x (cons 1 x)]) x)) (htdp-test #t (lambda (l) (eq? l (cdr l))) (shared ([x (cons 1 x)]) x)) (htdp-test #t (lambda (l) (eq? l (car l))) (shared ([x (list x x)]) x)) (htdp-test #t (lambda (l) (eq? l (cadr l))) (shared ([x (list x x)]) x)) @@ -200,6 +208,10 @@ (htdp-err/rt-test (cons 1 2) "cons: second argument must be a list or cyclic list, but received 1 and 2") (htdp-err/rt-test (append (list 1) 2) "append: last argument must be a list or cyclic list, but received 2") +(htdp-err/rt-test (first 1) "first: expected argument of type ; given 1") +(htdp-err/rt-test (rest 1) "rest: expected argument of type ; given 1") + + (htdp-test #t 'equal? (equal? (vector (list 10) 'apple) (vector (list 10) 'apple))) (htdp-test #t 'equal? (equal? (shared ([x (cons 10 x)]) x) (shared ([x (cons 10 x)]) x))) (htdp-test #t 'equal? (equal? (shared ([x (cons (vector x) x)]) x) (shared ([x (cons (vector x) x)]) x))) From 90674cf9b20daa480b6df8bec4455e214fc451ca Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Fri, 21 Oct 2011 10:54:56 -0400 Subject: [PATCH 427/746] Fix wrapping of `null' when provided as `Any'. Reported by 'dingfeng' on #racket. Please merge to 5.2. (cherry picked from commit da5b68fd4d944cef981062de5ed6d283a351fd1d) --- collects/tests/typed-racket/succeed/any-wrap-list.rkt | 11 +++++++++++ collects/typed-racket/utils/any-wrap.rkt | 3 +++ 2 files changed, 14 insertions(+) create mode 100644 collects/tests/typed-racket/succeed/any-wrap-list.rkt diff --git a/collects/tests/typed-racket/succeed/any-wrap-list.rkt b/collects/tests/typed-racket/succeed/any-wrap-list.rkt new file mode 100644 index 0000000000..9576df4b77 --- /dev/null +++ b/collects/tests/typed-racket/succeed/any-wrap-list.rkt @@ -0,0 +1,11 @@ +#lang racket/load + +(module m typed/racket + (provide f) + (define: f : Any '(a (2 3)))) + +(module n racket + (require 'm) + (list? (second f))) + +(require 'n) diff --git a/collects/typed-racket/utils/any-wrap.rkt b/collects/typed-racket/utils/any-wrap.rkt index 9974543c2e..ce72581899 100644 --- a/collects/typed-racket/utils/any-wrap.rkt +++ b/collects/typed-racket/utils/any-wrap.rkt @@ -7,12 +7,15 @@ (lambda (v p write?) (fprintf p "#" (any-wrap-val v)))) +(define undef (letrec ([x x]) x)) + (define (traverse wrap?) (define (t v) (match v [(? (lambda (e) (and (any-wrap? e) (not wrap?)))) (any-wrap-val v)] [(? (lambda (e) (or (number? e) (string? e) (char? e) (symbol? e) + (null? e) (regexp? e) (eq? undef e) (keyword? e) (bytes? e) (boolean? e) (void? e)))) v] [(cons x y) (cons (t x) (t y))] From e992a7f2b1ccc02e16cd0acf2d9587182b9910e4 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 21 Oct 2011 11:12:36 -0400 Subject: [PATCH 428/746] Fix the old-style keybinding example. (cherry picked from commit d8d79d22b2112afe583938bf7287d6b221bb9eda) --- collects/scribblings/drracket/keybindings.scrbl | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/collects/scribblings/drracket/keybindings.scrbl b/collects/scribblings/drracket/keybindings.scrbl index c0aaf1c18a..33d616707e 100644 --- a/collects/scribblings/drracket/keybindings.scrbl +++ b/collects/scribblings/drracket/keybindings.scrbl @@ -239,13 +239,17 @@ before version 5.2. @racketmod[ s-exp framework/keybinding-lang +(define modifiers + (apply string-append + (map (λ (p) + (case p + [(ctl) "c:"] [(cmd) "d:"] [(alt meta) "m:"] + [(shift) "s:"] [(option) "a:"])) + (get-default-shortcut-prefix)))) + (define-syntax-rule (frame-key key command) (keybinding - (format "~a:~a" - (case (get-default-shortcut-prefix) - [(ctl) "c"] [(cmd) "d"] [(alt meta) "m"] - [(shift) "s"] [(option) "a"]) - key) + (string-append modifiers key) (λ (ed evt) (when (is-a? ed text:basic<%>) (define fr (send ed get-top-level-window)) From 3c3633cd46ef1b2c0c5b072298ae3ec8e8975cd3 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 21 Oct 2011 11:13:02 -0400 Subject: [PATCH 429/746] Indicate repl phase level when it's not 0. (cherry picked from commit 0d642cf9763712bd557f89b767eb4a0aa75dd66b) --- collects/xrepl/xrepl.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index aef2c2cb9d..47aae02321 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -1300,7 +1300,9 @@ (define (get-prefix) (let* ([x (here-source)] [x (and x (if (symbol? x) (format "'~s" x) (get-prefix* x)))] - [x (or x (toplevel-prefix))]) + [x (or x (toplevel-prefix))] + [x (let ([ph (namespace-base-phase)]) + (if (eq? 0 ph) x (format "~a[~a]" x ph)))]) (if (eq? (current-namespace-name) default-namespace-name) x (format "~a::~a" (current-namespace-name) x)))) (define last-directory #f) From a169f7ffa712a53a23a346a5290207c79e2a9977 Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Fri, 21 Oct 2011 20:43:50 +0200 Subject: [PATCH 430/746] Unbreak "Enable signature checking". Previously, if you disabled it once, it would stay disabled. (cherry picked from commit 36d3745d4c8e1ff655bb189a5d7853690c6eb139) --- collects/deinprogramm/signature/tool.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/deinprogramm/signature/tool.rkt b/collects/deinprogramm/signature/tool.rkt index c18490472b..c943c2af92 100644 --- a/collects/deinprogramm/signature/tool.rkt +++ b/collects/deinprogramm/signature/tool.rkt @@ -37,7 +37,7 @@ (unless enabled? (set! enabled? #t) (set-label disable-label) - (preferences:set 'signatures:enable-checking? '#f))) + (preferences:set 'signatures:enable-checking? '#t))) (define/public (disable-signature-checking) (when enabled? (set! enabled? #f) From 7bdfbe11d65818f1f4ce5e912ac825833306bbb6 Mon Sep 17 00:00:00 2001 From: Eric Hanchrow Date: Sat, 22 Oct 2011 14:47:41 -0700 Subject: [PATCH 431/746] add missing word (cherry picked from commit b498d6e9e78556f790475c41ede41163aceaa615) --- collects/scribblings/guide/unit.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/guide/unit.scrbl b/collects/scribblings/guide/unit.scrbl index d464aa6862..7f7ce014da 100644 --- a/collects/scribblings/guide/unit.scrbl +++ b/collects/scribblings/guide/unit.scrbl @@ -611,7 +611,7 @@ simple application to values---that make them suitable for different purposes. The @racket[module] form is more fundamental than the others, in a -sense. After all, a program fragment cannot reliably refer to +sense. After all, a program fragment cannot reliably refer to a @racket[lambda], @racket[class], or @racket[unit] form without the namespace management provided by @racket[module]. At the same time, because namespace management is closely related to separate expansion From c1eb2733a6d208471004b0ccf8031fbee0b747a7 Mon Sep 17 00:00:00 2001 From: Eric Hanchrow Date: Sat, 22 Oct 2011 14:47:42 -0700 Subject: [PATCH 432/746] add an "s" (cherry picked from commit 723934a608703d90631b5dae5c66306201644270) --- collects/web-server/scribblings/web-server.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/web-server/scribblings/web-server.scrbl b/collects/web-server/scribblings/web-server.scrbl index 3bd19105b9..11c610c5c3 100644 --- a/collects/web-server/scribblings/web-server.scrbl +++ b/collects/web-server/scribblings/web-server.scrbl @@ -13,7 +13,7 @@ This manual describes the Racket libraries for building Web applications. @secref["servlet"] use the entire Racket language, but their continuations are stored in the Web server's memory. @secref["stateless"] use a slightly restricted Racket language, but their continuation can be stored by the Web client or on a Web server's disk. If you can, you want to use @secref["stateless"] for the improved scalability. -The @secref["http"] section describes the common library function for manipulating HTTP requests and creating HTTP responses. +The @secref["http"] section describes the common library functions for manipulating HTTP requests and creating HTTP responses. In particular, this section covers cookies, authentication, and request bindings. The final five sections (@secref["dispatch"], @secref["formlets"], @secref["templates"], @secref["page"], and @secref["test"]) cover utility libraries that ease the creation of typical Web applications. From 8400ccc456a188ea0fbb060fbc14aa672f704a4d Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Mon, 24 Oct 2011 06:50:36 -0600 Subject: [PATCH 433/746] Incorporating section from Mike W (cherry picked from commit ab45f4f1dbafed8fb09c60e33fdf541734a7e50d) --- .../web-server/scribblings/templates.scrbl | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/collects/web-server/scribblings/templates.scrbl b/collects/web-server/scribblings/templates.scrbl index d52568ad97..f9d3f8ea0f 100644 --- a/collects/web-server/scribblings/templates.scrbl +++ b/collects/web-server/scribblings/templates.scrbl @@ -256,6 +256,84 @@ issue for you called @racket[in]: }| Notice how it also avoids the absurd amount of punctuation on line two. +@section{Escaping} + +@margin-note{Thanks to Michael W. for this section.} + +Because templates are useful for many things (scripts, CSS, HTML, +etc), the Web Server does not assume that the template is for XML-like +content. Therefore when when templates are expanded, no +XML escaping is done by default. Beware of @emph{cross-site scripting} +vulnerabilities! For example, suppose a servlet serves the following +template where @racket[_some-variable] is an input string supplied by +the client: + +@verbatim[#:indent 2]|{ + + Fastest Templates in the West! + + @some-variable + + +}| + +If the servlet contains something like the following: + +@racketblock[ + (let ([some-variable (get-input-from-user)]) + (include-template "static.htm")) +] + +There is nothing to prevent an attacker from entering +@litchar[""] to make the +template expand into: + +@verbatim[#:indent 2]|{ + + Fastest Templates in the West! + + + + +}| + +Now the server will send the attacker's code to millions of innocent +users. To keep this from happening when serving HTML, use the +@racket[xexpr->string] function from the @racketmodname[xml] module. + +This can be done in the servlet: + +@racketblock[ + (require xml) + + (let ([some-variable (xexpr->string (get-input-from-user))]) + (include-template "static.htm")) +] + +Alternatively, make the template responsible for its own escaping: + +@verbatim[#:indent 2]|{ + + Fastest Templates in the West! + + @(xexpr->string some-variable) + + +}| + +The improved version renders as: + +@verbatim[#:indent 2]|{ + + Fastest Templates in the West! + + <script type=\"text/javascript\">...</script> + + +}| + +When writing templates, always remember to escape user-supplied input. + @section{HTTP Responses} The quickest way to generate an HTTP response from a template is using From f0db9180b4348bd329dbfc1ff19019b967899c02 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 29 Oct 2011 00:16:27 -0400 Subject: [PATCH 434/746] Improve unix installer tester. * The installer is a command-line argument. * Make it work in xterm too, by unsetting TERM. * Works with version-less directories, from release installers. (cherry picked from commit 1eec2b75e3c9c77e5d59a93172a34ef6ae67efba) --- .../meta/build/unix-installer/test-installer | 163 ++++++++++-------- 1 file changed, 87 insertions(+), 76 deletions(-) diff --git a/collects/meta/build/unix-installer/test-installer b/collects/meta/build/unix-installer/test-installer index 55ed825f61..4ec65c7c9a 100755 --- a/collects/meta/build/unix-installer/test-installer +++ b/collects/meta/build/unix-installer/test-installer @@ -7,12 +7,15 @@ exec racket "$0" "$@" (require racket/list racket/file racket/match racket/system) -(define testdir "/tmp/racket-installer-test") -(define installer "/tmp/r.sh") - (define (err fmt . args) (raise-user-error (format "Error: ~a" (apply format fmt args)))) +(define testdir "/tmp/racket-installer-test") +(define installer + (match (current-command-line-arguments) + [(vector installer) installer] + [(vector _ ...) (err "usage: test-installer ")])) + (define (exe name [just-path? #f]) (define path (or (find-executable-path name) (err "no `~a' executable found" name))) @@ -26,8 +29,8 @@ exec racket "$0" "$@" (when (directory-exists? testdir) (err "test directory exists: ~a" testdir)) (make-directory testdir) (current-directory testdir) -;; make identifiable prompts, predictable ls output, safe-for-play home -(void (putenv "PS1" "sh> ") (putenv "COLUMNS" "72") (putenv "HOME" testdir)) +;; plain interaction, identifiable prompts, safe-for-play home +(void (putenv "TERM" "dumb") (putenv "PS1" "sh> ") (putenv "HOME" testdir)) (define (transcript) ;; the test transcript text: @@ -35,15 +38,22 @@ exec racket "$0" "$@" ;; - `i' is for user input to send ;; - `r' is for a regexp ;; - `s' is a nested list to be spliced in - ;; - `N' is short for @r{[0-9.]+} + ;; - `N' is short for @r{(?:-?[0-9.]+)?} ;; - `...' makes the next match unanchored (so it's similar to a non-greedy ;; ".*" regexp) (define (i . xs) `(i . ,xs)) (define (r . xs) `(r . ,xs)) (define (s . xs) `(s . ,xs)) (define break 'break) - (define N @r{[0-9.]+}) + (define N @r{(?:-?[0-9.]+)?}) (define ... '...) + (define not-recommended + (let ([s (string-append + "*** This is a nightly build: such a unix-style distribution" + " is *not*\n" + "*** recommended because it cannot be used to install multiple" + " versions.\n")]) + (format "(?:~a)?" (regexp-quote s)))) @list{ @; the first few puzzling interactions are testing that we generate the @; right expect code -- which requires regexp and $-quoting. @@ -58,6 +68,8 @@ exec racket "$0" "$@" []{}blah*$x* sh> @i{pwd} @testdir + @; utilities + sh> @i{LS() { ls --width=72 -mF "$@"@""@";" }} @; proper testing begins here sh> @i{sh @installer} This program will extract and install Racket v@|N|. @@ -72,22 +84,21 @@ exec racket "$0" "$@" (movable and erasable), possibly with external links into it -- this is often more convenient, especially if you want to install multiple versions or keep it in your home directory. - *** This is a nightly build: such a unix-style distribution is *not* - *** recommended because it cannot be used to install multiple versions. + @r{@not-recommended}@; Enter yes/no (default: no) > @i{bleh} Enter yes/no (default: no) > @i{foo} Enter yes/no (default: no) > @i{} @|| - Where do you want to install the "racket-@N" directory tree? - 1 - /usr/racket-@N [default] - 2 - /usr/local/racket-@N - 3 - ~/racket-@N (@|testdir|/racket-@N) - 4 - ./racket-@N (here) + Where do you want to install the "racket@N" directory tree? + 1 - /usr/racket@N [default] + 2 - /usr/local/racket@N + 3 - ~/racket@N (@|testdir|/racket@N) + 4 - ./racket@N (here) Or enter a different "racket" directory to install in. > @i{4} @|| Checking the integrity of the binary archive... ok. - Unpacking into "@|testdir|/racket-@N" (Ctrl+C to abort)... + Unpacking into "@|testdir|/racket@N" (Ctrl+C to abort)... Done. @|| If you want to install new system links within the "bin" and @@ -98,9 +109,9 @@ exec racket "$0" "$@" (default: skip links) > @i{} @|| Installation complete. - sh> @i{ls -mF} - racket-@|N|/ - sh> @i{ls -mF racket-*} + sh> @i{LS} + racket@|N|/ + sh> @i{LS racket*} README, bin/, collects/, doc/, include/, lib/, man/ sh> @i{sh @installer} @... @@ -109,9 +120,9 @@ exec racket "$0" "$@" > @i{.} @|| Checking the integrity of the binary archive... ok. - "@|testdir|/racket-@N" exists, delete? @i{n} + "@|testdir|/racket@N" exists, delete? @i{n} Aborting installation. - sh> @i{ls -mF racket-*} + sh> @i{LS racket*} README, bin/, collects/, doc/, include/, lib/, man/ sh> @i{chmod 000 racket*} sh> @i{sh @installer} @@ -121,11 +132,11 @@ exec racket "$0" "$@" > @i{./} @|| Checking the integrity of the binary archive... ok. - "@|testdir|/racket-@N" exists, delete? @i{y} - Deleting old "@|testdir|/racket-@N"... @; - /bin/rm: cannot remove `@|testdir|/racket-@N': @; + "@|testdir|/racket@N" exists, delete? @i{y} + Deleting old "@|testdir|/racket@N"... @; + /bin/rm: cannot remove `@|testdir|/racket@N': @; Permission denied - Error: could not delete "@|testdir|/racket-@N". + Error: could not delete "@|testdir|/racket@N". sh> @i{chmod 755 racket*} sh> @i{sh @installer} @... @@ -134,8 +145,8 @@ exec racket "$0" "$@" > @i{.} @|| Checking the integrity of the binary archive... ok. - "@|testdir|/racket-@N" exists, delete? @i{y} - Deleting old "@|testdir|/racket-@N"... done. + "@|testdir|/racket@N" exists, delete? @i{y} + Deleting old "@|testdir|/racket@N"... done. @... (default: skip links) > @i{.} "@|testdir|/bin" does not exist, skipping. @@ -167,18 +178,18 @@ exec racket "$0" "$@" "@|testdir|/share/man/man1" does not exist, skipping. @|| Installation complete. - sh> @i{ls -mF .} - R/, bin/, racket-@|N|/ - sh> @i{ls -mF R} + sh> @i{LS .} + R/, bin/, racket@|N|/ + sh> @i{LS R} README, bin/, collects/, doc/, include/, lib/, man/ - sh> @i{ls -mF bin} + sh> @i{LS bin} @s|{drracket@, gracket, gracket-text@, mred@, mred-text@, mzc@, mzpp@, mzscheme@, mztext@, pdf-slatex@, planet@, plt-games@, plt-help@, plt-r5rs@, plt-r6rs@, plt-web-server@, racket@, raco@, scribble@, setup-plt@, slatex@, slideshow@, swindle@, tex2page@}| - sh> @i{ls -l bin/ra*} - lrwxrwxrwx. @... bin/racket -> @|testdir|/R/bin/racket - lrwxrwxrwx. @... bin/raco -> @|testdir|/R/bin/raco + sh> @i{LS -l bin/ra*} + lrwxrwxrwx. @... bin/racket -> @|testdir|/R/bin/racket* + lrwxrwxrwx. @... bin/raco -> @|testdir|/R/bin/raco* sh> @i{sh @installer} @... Enter yes/no (default: no) > @i{} @@ -190,8 +201,8 @@ exec racket "$0" "$@" @break Error: Aborting... (Removing installation files in @|testdir|/R1) - sh> @i{ls -mF} - R/, bin/, racket-@|N|/ + sh> @i{LS} + R/, bin/, racket@|N|/ sh> @i{sh @installer} @... Enter yes/no (default: no) > @i{} @@ -203,8 +214,8 @@ exec racket "$0" "$@" @... (default: skip links) > @break Error: Aborting... - sh> @i{ls -mF} - R/, bin/, mmm/, racket-5.2.0.1/ + sh> @i{LS} + R/, bin/, mmm/, racket@|N|/ sh> @i{sh @installer} @... Enter yes/no (default: no) > @i{} @@ -223,13 +234,13 @@ exec racket "$0" "$@" "/usr/local" is not writable, skipping links. @|| Installation complete. - sh> @i{ls -mF} + sh> @i{LS} sh> @i{cd /} sh> @i{cd @testdir} - sh> @i{ls -mF} + sh> @i{LS} README, bin/, collects/, doc/, include/, lib/, man/ sh> @i{rm -rf [a-zR]*} - sh> @i{ls -mF} + sh> @i{LS} sh> @i{sh @installer} @... Do you want a Unix-style distribution? @@ -261,11 +272,11 @@ exec racket "$0" "$@" @|| Target Directories: [e] Executables @|testdir|/bin (will be created) - [r] Racket Code @|testdir|/lib/racket-@|N|/collects (will be created) - [d] Core Docs @|testdir|/share/racket-@|N|/doc (will be created) + [r] Racket Code @|testdir|/lib/racket@|N|/collects (will be created) + [d] Core Docs @|testdir|/share/racket@|N|/doc (will be created) [l] C Libraries @|testdir|/lib (will be created) - [h] C headers @|testdir|/include/racket-@|N| (will be created) - [o] Extra C Objs @|testdir|/lib/racket-@|N| (will be created) + [h] C headers @|testdir|/include/racket@|N| (will be created) + [o] Extra C Objs @|testdir|/lib/racket@|N| (will be created) [m] Man Pages @|testdir|/share/man (will be created) Enter a letter to change an entry, or enter to continue. > @i{z} @@ -273,43 +284,43 @@ exec racket "$0" "$@" > @i{} @|| Checking the integrity of the binary archive... ok. - Unpacking into "@|testdir|/racket-@|N|-tmp-install" (Ctrl+C to abort)... + Unpacking into "@|testdir|/racket@|N|-tmp-install" (Ctrl+C to abort)... Done. Moving bin -> @|testdir|/bin - Moving collects -> @|testdir|/lib/racket-@|N|/collects - Moving doc -> @|testdir|/share/racket-@|N|/doc - Moving include -> @|testdir|/include/racket-@|N| - Moving lib -> @|testdir|/lib/racket-@|N| + Moving collects -> @|testdir|/lib/racket@|N|/collects + Moving doc -> @|testdir|/share/racket@|N|/doc + Moving include -> @|testdir|/include/racket@|N| + Moving lib -> @|testdir|/lib/racket@|N| Moving man -> @|testdir|/share/man - Moving README -> @|testdir|/share/racket-@|N|/doc/README + Moving README -> @|testdir|/share/racket@|N|/doc/README Writing uninstaller at: @|testdir|/bin/racket-uninstall... - Rewriting configuration file at: @|testdir|/lib/racket-@|N|/@; + Rewriting configuration file at: @|testdir|/lib/racket@|N|/@; collects/config/config.rkt... - Recompiling to @|testdir|/lib/racket-@|N|/@; + Recompiling to @|testdir|/lib/racket@|N|/@; collects/config/compiled/config_rkt.zo... @|| Installation complete. - sh> @i{ls -mF} + sh> @i{LS} bin/, include/, lib/, share/ - sh> @i{ls -mF bin} + sh> @i{LS bin} drracket*, gracket*, gracket-text*, mred*, mred-text*, mzc*, mzpp*, mzscheme*, mztext*, pdf-slatex*, planet*, plt-games*, plt-help*, plt-r5rs*, plt-r6rs*, plt-web-server*, racket*, racket-uninstall*, raco*, scribble*, setup-plt*, slatex*, slideshow*, swindle*, tex2page* - sh> @i{ls -mF include && ls -mF lib && ls -mF share} - racket-@|N|/ - racket-@|N|/ - man/, racket-@|N|/ - sh> @i{ls -mF include/r*} + sh> @i{LS include && LS lib && LS share} + racket@|N|/ + racket@|N|/ + man/, racket@|N|/ + sh> @i{LS include/r*} escheme.h, ext.exp, mzconfig.h, mzscheme3m.exp, scheme.h, schemef.h, schemegc2.h, schemex.h, schemexm.h, schexn.h, schgc2obj.h, schthread.h, schvers.h, sconfig.h, stypes.h, uconfig.h - sh> @i{ls -mF lib/r*} + sh> @i{LS lib/r*} buildinfo, collects/, libfit.so*, mzdyn3m.o, starter* - sh> @i{ls -mF share/r* && ls -mF share/r*/doc} + sh> @i{LS share/r* && LS share/r*/doc} doc/ README, @... xrepl/ - sh> @i{ls -mF share/man && ls -mF share/man/man1} + sh> @i{LS share/man && LS share/man/man1} man1/ drracket.1, gracket.1, mred.1, mzc.1, mzscheme.1, plt-help.1, racket.1, raco.1, setup-plt.1, tex2page.1 @@ -330,11 +341,11 @@ exec racket "$0" "$@" @|| Target Directories: [e] Executables @|testdir|/bin (exists) - [r] Racket Code @|testdir|/lib/racket-@|N|/collects (exists) - [d] Core Docs @|testdir|/share/racket-@|N|/doc (exists) + [r] Racket Code @|testdir|/lib/racket@|N|/collects (exists) + [d] Core Docs @|testdir|/share/racket@|N|/doc (exists) [l] C Libraries @|testdir|/lib (exists) - [h] C headers @|testdir|/include/racket-@|N| (exists) - [o] Extra C Objs @|testdir|/lib/racket-@|N| (exists) + [h] C headers @|testdir|/include/racket@|N| (exists) + [o] Extra C Objs @|testdir|/lib/racket@|N| (exists) [m] Man Pages @|testdir|/share/man (exists) Enter a letter to change an entry, or enter to continue. > @i{m} @@ -342,11 +353,11 @@ exec racket "$0" "$@" @|| Target Directories: [e] Executables @|testdir|/bin (exists) - [r] Racket Code @|testdir|/lib/racket-@|N|/collects (exists) - [d] Core Docs @|testdir|/share/racket-@|N|/doc (exists) + [r] Racket Code @|testdir|/lib/racket@|N|/collects (exists) + [d] Core Docs @|testdir|/share/racket@|N|/doc (exists) [l] C Libraries @|testdir|/lib (exists) - [h] C headers @|testdir|/include/racket-@|N| (exists) - [o] Extra C Objs @|testdir|/lib/racket-@|N| (exists) + [h] C headers @|testdir|/include/racket@|N| (exists) + [o] Extra C Objs @|testdir|/lib/racket@|N| (exists) [m] Man Pages @|testdir|/m (error: not a directory!) Enter a letter to change an entry, or enter to continue. > @i{} @@ -358,11 +369,11 @@ exec racket "$0" "$@" @|| Target Directories: [e] Executables @|testdir|/bin (exists) - [r] Racket Code @|testdir|/lib/racket-@|N|/collects (exists) - [d] Core Docs @|testdir|/share/racket-@|N|/doc (exists) + [r] Racket Code @|testdir|/lib/racket@|N|/collects (exists) + [d] Core Docs @|testdir|/share/racket@|N|/doc (exists) [l] C Libraries @|testdir|/lib (exists) - [h] C headers @|testdir|/include/racket-@|N| (exists) - [o] Extra C Objs @|testdir|/lib/racket-@|N| (exists) + [h] C headers @|testdir|/include/racket@|N| (exists) + [o] Extra C Objs @|testdir|/lib/racket@|N| (exists) [m] Man Pages @|testdir|/man (will be created) Enter a letter to change an entry, or enter to continue. > @i{} @@ -375,7 +386,7 @@ exec racket "$0" "$@" Checking the integrity of the binary archive... ok. @... Installation complete. - sh> @i{ls -mF} + sh> @i{LS} bin/, include/, lib/, m, man/, share/ sh> @i{sh @installer} @... @@ -400,7 +411,7 @@ exec racket "$0" "$@" Enter a letter to change an entry, or enter to continue. > @break Error: Aborting... - sh> @i{ls -mF} + sh> @i{LS} bin/, include/, lib/, m, man/ sh> @i{exit} @||}) From e3b8195afa170f6909e607ce349bb29bf3d8a65b Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 2 Nov 2011 17:40:04 -0400 Subject: [PATCH 435/746] Fix the default `sandbox-make-code-inspector'. It now creates an inspector based on the original code inspector instead of the (implicit) wrong default used by `make-inspector'. Change `sandbox-make-inspector' too, to make it explicit. (cherry picked from commit 90f7a98dd6d16686ce6874387536a6cf93671f8b) --- collects/racket/sandbox.rkt | 6 +++-- collects/scribblings/reference/sandbox.scrbl | 26 +++++++++++--------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/collects/racket/sandbox.rkt b/collects/racket/sandbox.rkt index 62cfc6b27d..02777130e5 100644 --- a/collects/racket/sandbox.rkt +++ b/collects/racket/sandbox.rkt @@ -202,9 +202,11 @@ (define sandbox-exit-handler (make-parameter default-sandbox-exit-handler)) -(define sandbox-make-inspector (make-parameter make-inspector)) +(define sandbox-make-inspector + (make-parameter (lambda () (make-inspector (current-inspector))))) -(define sandbox-make-code-inspector (make-parameter make-inspector)) +(define sandbox-make-code-inspector + (make-parameter (lambda () (make-inspector (current-code-inspector))))) (define sandbox-make-logger (make-parameter current-logger)) diff --git a/collects/scribblings/reference/sandbox.scrbl b/collects/scribblings/reference/sandbox.scrbl index ac6efcc285..3a3b6966af 100644 --- a/collects/scribblings/reference/sandbox.scrbl +++ b/collects/scribblings/reference/sandbox.scrbl @@ -676,22 +676,24 @@ other resources intact.} @defparam[sandbox-make-inspector make (-> inspector?)]{ -A parameter that determines the procedure used to create the inspector -for sandboxed evaluation. The procedure is called when initializing -an evaluator, and the default parameter value is -@racket[make-inspector].} +A parameter that determines the (nullary) procedure that is used to +create the inspector for sandboxed evaluation. The procedure is called +when initializing an evaluator. The default parameter value is +@racket[(lambda () (make-inspector (current-inspector)))].} @defparam[sandbox-make-code-inspector make (-> inspector?)]{ -A parameter that determines the procedure used to create the code -inspector for sandboxed evaluation. The procedure is called when -initializing an evaluator, and the default parameter value is -@racket[make-inspector]. The @racket[current-load/use-compiled] -handler is setup to still allow loading of bytecode files under the -original code inspector when @racket[sandbox-path-permissions] allows -it through a @racket['read-bytecode] mode symbol, to make it possible -to load libraries.} +A parameter that determines the (nullary) procedure that is used to +create the code inspector for sandboxed evaluation. The procedure is +called when initializing an evaluator. The default parameter value is +@racket[(lambda () (make-inspector (current-code-inspector)))]. + +The @racket[current-load/use-compiled] handler is setup to allow loading +of bytecode files under the original code inspector when +@racket[sandbox-path-permissions] allows it through a +@racket['read-bytecode] mode symbol, which makes loading libraries +possible.} @defparam[sandbox-make-logger make (-> logger?)]{ From 4b79e53d652889c490eb71820c5f87bba4de9c92 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 3 Nov 2011 17:08:53 -0400 Subject: [PATCH 436/746] Add a history note on the lazy change, make the TR history specify 5.2. (cherry picked from commit cfc465932e0f240ac173590f59f781bc1739fc85) --- doc/release-notes/racket/HISTORY.txt | 2 ++ doc/release-notes/typed-racket/HISTORY.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index 6d12b44577..707d391938 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -52,6 +52,8 @@ Removed the Racket-to-C compiler: raco ctool -e/-c, mzc -e/-c, compile-extensions, compile-extensions-to-c, compile-c-extensions, compiler/cffi, compiler/comp-unit, compiler:inner^, and most options in compiler/option +The The `lazy' language is now based on `racket' instead of `mzscheme'. + Specifically, it now uses modern `require's and `provide's. Version 5.1.3, August 2011 No changes diff --git a/doc/release-notes/typed-racket/HISTORY.txt b/doc/release-notes/typed-racket/HISTORY.txt index 015d098446..2ad33e3472 100644 --- a/doc/release-notes/typed-racket/HISTORY.txt +++ b/doc/release-notes/typed-racket/HISTORY.txt @@ -1,4 +1,4 @@ -5.1.3.* +5.2 - Performance work: delayed environment evaluation - Support `racket'-style optional arguments - Changes to support new-style keyword argument expansion From df779e69cb241857227a790d6019b858c4867d5d Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 3 Nov 2011 17:25:17 -0400 Subject: [PATCH 437/746] Update version number for the v5.2 release --- src/racket/src/schvers.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 288eb5b9a2..e1561cd2fd 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.1.900.1" +#define MZSCHEME_VERSION "5.2" #define MZSCHEME_VERSION_X 5 -#define MZSCHEME_VERSION_Y 1 -#define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 1 +#define MZSCHEME_VERSION_Y 2 +#define MZSCHEME_VERSION_Z 0 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 6a996b3eb7f76620a73f5970deb7d68dbace793e Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 3 Nov 2011 17:25:19 -0400 Subject: [PATCH 438/746] New Racket version 5.2. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 12 ++++++------ src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index 03c5ce0eaa..f3023fc293 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 6236d8fc68..919148f9c0 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -17,8 +17,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,900,1 - PRODUCTVERSION 5,1,900,1 + FILEVERSION 5,2,0,0 + PRODUCTVERSION 5,2,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -36,11 +36,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 1, 900, 1\0" + VALUE "FileVersion", "5, 2, 0, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 900, 1\0" + VALUE "ProductVersion", "5, 2, 0, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 531fdf55db..9ddfeb7895 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,900,1 - PRODUCTVERSION 5,1,900,1 + FILEVERSION 5,2,0,0 + PRODUCTVERSION 5,2,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 1, 900, 1" + VALUE "FileVersion", "5, 2, 0, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2011 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 1, 900, 1" + VALUE "ProductVersion", "5, 2, 0, 0" END END BLOCK "VarFileInfo" @@ -105,10 +105,10 @@ CAPTION "MzCOM" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,76,69,50,14,BS_CENTER - CTEXT "MzCOM v. 5.1",IDC_STATIC,71,8,61,8 + CTEXT "MzCOM v. 5.2",IDC_STATIC,71,8,61,8 CTEXT "Copyright (c) 2000-2011 PLT (Paul Steckler)",IDC_STATIC, 41,20,146,9 - CTEXT "Racket v. 5.1",IDC_STATIC,64,35,75,8 + CTEXT "Racket v. 5.2",IDC_STATIC,64,35,75,8 CTEXT "Copyright (c) 1995-2011 PLT Inc.",IDC_STATIC, 30,47,143,8 ICON MZICON,IDC_STATIC,11,16,20,20 diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index c9eb625c8c..734c40b476 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.1.900.1 = s 'MzObj Class' + MzCOM.MzObj.5.2.0.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.1.900.1' + CurVer = s 'MzCOM.MzObj.5.2.0.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.1.900.1' + ProgID = s 'MzCOM.MzObj.5.2.0.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index f9180cc43b..bf4c1c3854 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 75b9dfe52f..16040b3695 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -29,8 +29,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,900,1 - PRODUCTVERSION 5,1,900,1 + FILEVERSION 5,2,0,0 + PRODUCTVERSION 5,2,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -48,11 +48,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 1, 900, 1\0" + VALUE "FileVersion", "5, 2, 0, 0\0" VALUE "LegalCopyright", "Copyright 1995-2011\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 900, 1\0" + VALUE "ProductVersion", "5, 2, 0, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 9c7e5f6182..ba10fa212f 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,900,1 - PRODUCTVERSION 5,1,900,1 + FILEVERSION 5,2,0,0 + PRODUCTVERSION 5,2,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 1, 900, 1\0" + VALUE "FileVersion", "5, 2, 0, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 1, 900, 1\0" + VALUE "ProductVersion", "5, 2, 0, 0\0" END END BLOCK "VarFileInfo" From 8cbb867811809e2cf133c09e5f98b25df102ac5b Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 4 Nov 2011 19:24:38 -0400 Subject: [PATCH 439/746] Fixed version of b9bd1db5. --- collects/racket/sandbox.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/racket/sandbox.rkt b/collects/racket/sandbox.rkt index 02777130e5..1e5745199f 100644 --- a/collects/racket/sandbox.rkt +++ b/collects/racket/sandbox.rkt @@ -878,7 +878,6 @@ (;; create a sandbox context first [current-custodian user-cust] [current-thread-group (make-thread-group)] - [current-namespace (make-evaluation-namespace)] ;; set up the IO context [current-input-port (let ([inp (sandbox-input)]) @@ -917,6 +916,8 @@ [current-logger ((sandbox-make-logger))] [current-inspector ((sandbox-make-inspector))] [current-code-inspector ((sandbox-make-code-inspector))] + ;; Create the namespace under the restricted code inspector + [current-namespace (make-evaluation-namespace)] ;; The code inspector serves two purposes -- making sure that only trusted ;; byte-code is loaded, and avoiding using protected module bindings, like ;; the foreign library's `unsafe!'. We control the first through the path From 6797a444478139dd48c7b106595bbe365534b8c6 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 8 Nov 2011 12:39:16 -0800 Subject: [PATCH 440/746] Revert "Fixed version of b9bd1db5." This reverts commit 8cbb867811809e2cf133c09e5f98b25df102ac5b. --- collects/racket/sandbox.rkt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/collects/racket/sandbox.rkt b/collects/racket/sandbox.rkt index 1e5745199f..02777130e5 100644 --- a/collects/racket/sandbox.rkt +++ b/collects/racket/sandbox.rkt @@ -878,6 +878,7 @@ (;; create a sandbox context first [current-custodian user-cust] [current-thread-group (make-thread-group)] + [current-namespace (make-evaluation-namespace)] ;; set up the IO context [current-input-port (let ([inp (sandbox-input)]) @@ -916,8 +917,6 @@ [current-logger ((sandbox-make-logger))] [current-inspector ((sandbox-make-inspector))] [current-code-inspector ((sandbox-make-code-inspector))] - ;; Create the namespace under the restricted code inspector - [current-namespace (make-evaluation-namespace)] ;; The code inspector serves two purposes -- making sure that only trusted ;; byte-code is loaded, and avoiding using protected module bindings, like ;; the foreign library's `unsafe!'. We control the first through the path From e42bfe361c33bb8f770d0e3c536013d7a122006d Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 9 Nov 2011 21:55:42 -0500 Subject: [PATCH 441/746] v5.2 stuff (cherry picked from commit 794779b997589c1a951cdba0a656cb2798a3b4e3) --- collects/meta/web/download/installers.txt | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index be8d1c7853..3724d45402 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -160,3 +160,31 @@ 16095941 5.1/racket/racket-5.1-src-mac.dmg 15759982 5.1/racket/racket-5.1-src-unix.tgz 17987080 5.1/racket/racket-5.1-src-win.zip +10072568 5.2/racket-textual/racket-textual-5.2-bin-i386-linux-f12.sh +10087724 5.2/racket-textual/racket-textual-5.2-bin-i386-linux-ubuntu-karmic.sh +10419223 5.2/racket-textual/racket-textual-5.2-bin-i386-osx-mac.dmg +7639819 5.2/racket-textual/racket-textual-5.2-bin-i386-win32.exe +10001213 5.2/racket-textual/racket-textual-5.2-bin-ppc-darwin.sh +10368884 5.2/racket-textual/racket-textual-5.2-bin-ppc-osx-mac.dmg +10243046 5.2/racket-textual/racket-textual-5.2-bin-x86_64-linux-debian-lenny.sh +10256265 5.2/racket-textual/racket-textual-5.2-bin-x86_64-linux-debian-squeeze.sh +10259861 5.2/racket-textual/racket-textual-5.2-bin-x86_64-linux-f14.sh +10631349 5.2/racket-textual/racket-textual-5.2-bin-x86_64-osx-mac.dmg +7965785 5.2/racket-textual/racket-textual-5.2-bin-x86_64-win32.exe +5926754 5.2/racket-textual/racket-textual-5.2-src-mac.dmg +5806691 5.2/racket-textual/racket-textual-5.2-src-unix.tgz +6846137 5.2/racket-textual/racket-textual-5.2-src-win.zip +54306960 5.2/racket/racket-5.2-bin-i386-linux-f12.sh +54333056 5.2/racket/racket-5.2-bin-i386-linux-ubuntu-karmic.sh +56070009 5.2/racket/racket-5.2-bin-i386-osx-mac.dmg +36205596 5.2/racket/racket-5.2-bin-i386-win32.exe +54161422 5.2/racket/racket-5.2-bin-ppc-darwin.sh +57109008 5.2/racket/racket-5.2-bin-ppc-osx-mac.dmg +54654394 5.2/racket/racket-5.2-bin-x86_64-linux-debian-lenny.sh +54678069 5.2/racket/racket-5.2-bin-x86_64-linux-debian-squeeze.sh +54685565 5.2/racket/racket-5.2-bin-x86_64-linux-f14.sh +56380421 5.2/racket/racket-5.2-bin-x86_64-osx-mac.dmg +36902485 5.2/racket/racket-5.2-bin-x86_64-win32.exe +16601808 5.2/racket/racket-5.2-src-mac.dmg +16260740 5.2/racket/racket-5.2-src-unix.tgz +19575041 5.2/racket/racket-5.2-src-win.zip From 5f2e956d7df15d71a4caca1c52c7bf3abb06e57c Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sun, 8 Jan 2012 23:40:56 -0700 Subject: [PATCH 442/746] Alpha version number for the v5.2.1 release --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 06e2086da4..7239db6207 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.2.0.7" +#define MZSCHEME_VERSION "5.2.0.900" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 7 +#define MZSCHEME_VERSION_W 900 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From e09fd80080d1e4f91532b9f468cf741ecee2b1e9 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 9 Jan 2012 02:04:11 -0500 Subject: [PATCH 443/746] New Racket version 5.2.0.900. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index 6954076211..c4f30ca2a5 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 88afb7aa5d..0c61323393 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,7 - PRODUCTVERSION 5,2,0,7 + FILEVERSION 5,2,0,900 + PRODUCTVERSION 5,2,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 2, 0, 7\0" + VALUE "FileVersion", "5, 2, 0, 900\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 0, 7\0" + VALUE "ProductVersion", "5, 2, 0, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index a3e7e2f2d5..5cc7691169 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,7 - PRODUCTVERSION 5,2,0,7 + FILEVERSION 5,2,0,900 + PRODUCTVERSION 5,2,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 2, 0, 7" + VALUE "FileVersion", "5, 2, 0, 900" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2012 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 2, 0, 7" + VALUE "ProductVersion", "5, 2, 0, 900" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index d999a5e5d7..c9f9a4ffb7 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.2.0.7 = s 'MzObj Class' + MzCOM.MzObj.5.2.0.900 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.2.0.7' + CurVer = s 'MzCOM.MzObj.5.2.0.900' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.2.0.7' + ProgID = s 'MzCOM.MzObj.5.2.0.900' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index f70d91a273..117439e38d 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 8923c151f3..311915509b 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,7 - PRODUCTVERSION 5,2,0,7 + FILEVERSION 5,2,0,900 + PRODUCTVERSION 5,2,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 2, 0, 7\0" + VALUE "FileVersion", "5, 2, 0, 900\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 0, 7\0" + VALUE "ProductVersion", "5, 2, 0, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index b9f9e325c5..11ebb5035c 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,7 - PRODUCTVERSION 5,2,0,7 + FILEVERSION 5,2,0,900 + PRODUCTVERSION 5,2,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 2, 0, 7\0" + VALUE "FileVersion", "5, 2, 0, 900\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 0, 7\0" + VALUE "ProductVersion", "5, 2, 0, 900\0" END END BLOCK "VarFileInfo" From becd6bad7b6cd394bcfef72c1b258da4fe382d94 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 8 Jan 2012 22:27:37 -0500 Subject: [PATCH 444/746] ntoronto is responsible for images. (cherry picked from commit 536f89926f18a40ee0b831e55c1fbad1c88bf82e) --- collects/meta/props | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/meta/props b/collects/meta/props index b2ac8ab3f3..65e3c7da96 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -967,6 +967,7 @@ path/s is either such a string or a list of them. "collects/icons" responsible (ntoronto) "collects/icons/private/mkheart.rkt" drdr:command-line #f "collects/icons/private/svg/render-png.rkt" drdr:command-line #f +"collects/images" responsible (ntoronto) "collects/lang" responsible (mflatt robby matthias) "collects/lang/htdp-langs.rkt" drdr:command-line (gracket-text "-t" *) "collects/lang/plt-pretty-big.rkt" drdr:command-line (gracket-text "-t" *) From e83af6c94bb1bcd0196bb56e13b3f46c4163f022 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 9 Jan 2012 07:36:05 -0500 Subject: [PATCH 445/746] * Fix showing branch in non-master builds. * Show error in last status, so it's visible later. * `show' can get a `-s' flag too. * Remove unused `append_dots'. (cherry picked from commit d53979289507dc6a1eadf8ac0472b12978559f9d) --- collects/meta/build/build | 22 ++++++++------------ collects/meta/build/current-build-status.cgi | 9 +++++++- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index 4e9b661f3b..d0691965f9 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -373,12 +373,12 @@ no_exit_on_error="no" exit_error() { echo "" echo "<<>> (Working on $machine($platform))" 1>&2 - echo "$@" 1>&2 + echo "$*" 1>&2 if [[ "$no_exit_on_error" = "yes" ]]; then echo "" else echo "Aborting" 1>&2 - write_status "Build error, aborted" + write_status "Build error, aborted: $*" exit 1 fi } @@ -477,17 +477,18 @@ else fi show() { + if [[ "x$1" = "x-s" ]]; then shift; write_status "$*"; fi if [[ "$verbose" = "yes" ]]; then echo "" case "$platform" in ( *"-linux"* | "sparc-solaris" | *"-win32" ) - echo ">>>" "$@" | fmt -t -w 79 + echo ">>> $*" | fmt -t -w 79 ;; ( *"-freebsd" | *"-osx-mac" | *"-darwin" ) - echo ">>>" "$@" | fmt -w 79 + echo ">>> $*" | fmt -w 79 ;; ( * ) - echo ">>>" "$@" | fmt + echo ">>> $*" | fmt ;; esac fi @@ -704,11 +705,6 @@ git_get() { # inputs: git repository, git branch, path in $maindir _cd "$maindir" } -append_dots() { # inputs: width, string - local line="............................................................" - echo "${2}${line:0:$(( ${1} - ${#2} ))}" -} - base_status="" write_status() { local message="$*" @@ -720,10 +716,10 @@ write_status() { touch "$statusfile" chcon --type=httpd_sys_content_t "$statusfile" fi - echo "$*" > "$statusfile" + echo "$message" > "$statusfile" else # greppable lines for status, filtered out in final log (see below) - echo "### <<< $* >>>" + echo "### <<< $message >>>" fi } @@ -1092,7 +1088,7 @@ MAIN_BUILD() { # and now wait for all builds if is_yes make_bins; then - show "Waiting for remote jobs to finish" + show -s "Waiting for remote jobs to finish" wait for m in "${machines[@]}"; do machine="$m" diff --git a/collects/meta/build/current-build-status.cgi b/collects/meta/build/current-build-status.cgi index 596d23b356..94b72c16b3 100644 --- a/collects/meta/build/current-build-status.cgi +++ b/collects/meta/build/current-build-status.cgi @@ -34,6 +34,7 @@ elif [[ "$S" = "Y" ]]; then printf '\n%s build jobs running:\n' "$(ls "$bglogfile"* | wc -l)" for bg in "$bglogfile"*; do s="$(grep "^### <<< .* >>>" "$bg" | tail -1 \ + | sed -e 's/([^()]* build) //' \ | sed -e 's/^### <<< \(.*\) >>>/\1/')" if [[ "x$s" = "x" ]]; then printf ' %s: (just starting)\n' "${bg#$bglogfile-}" @@ -53,8 +54,14 @@ else last="${last#Done (}" last="${last%)}" printf 'Last build successfully ended at %s\n' "$last" + elif [[ "x$last" = "x("*" build) Done ("*")" ]]; then + last="${last#(}" + build="${last% build) Done*}" + last="${last#*) Done (}" + last="${last%)}" + printf 'Last %s build successfully ended at %s\n' "$build" "$last" else - printf 'Last build was unsuccessful (while: %s)\n' "$last" + printf 'Last build was unsuccessful (%s)\n' "$last" fi fi if [[ "$L" = "Y" ]]; then From 11155494082ac7d40a012a9d2cb88fdd2fdd7749 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 8 Jan 2012 16:24:01 -0600 Subject: [PATCH 446/746] added a cycle check to define-language so grammars like this one: (define-language L (e e)) are rejected as syntax errors (cherry picked from commit 93c21e34de767a0989f18a20a93ac77c76c3ebfa) --- collects/redex/private/cycle-check.rkt | 49 +++++++++++++++++++ .../redex/private/reduction-semantics.rkt | 8 ++- 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 collects/redex/private/cycle-check.rkt diff --git a/collects/redex/private/cycle-check.rkt b/collects/redex/private/cycle-check.rkt new file mode 100644 index 0000000000..e47e8c12c6 --- /dev/null +++ b/collects/redex/private/cycle-check.rkt @@ -0,0 +1,49 @@ +#lang racket/base +(require racket/match) + +(provide check-for-cycles) + +;; doesn't check for cycles via things like: +;; a ::= hole +;; b ::= (in-hole a b) +(define (check-for-cycles stx ntss/stx prodss/stx) + + (define ntss (syntax->datum ntss/stx)) + (define prodss (syntax->datum prodss/stx)) + + ;; hash[sym[nt] -o> (listof sym[nt]) + (define table (make-hash)) + + ;; build the graph + (for ([nts (in-list ntss)] + [prods (in-list prodss)]) + (define base-nt (car nts)) + (for ([nt (in-list (cdr nts))]) + (hash-set! table nt (list base-nt))) + (hash-set! table base-nt '()) + (for ([prod (in-list prods)]) + (match prod + [`(nt ,name) + (hash-set! table base-nt (cons name (hash-ref table base-nt)))] + [_ (void)]))) + + ;; traverse the graph looking for cycles + (define cycle + (for/or ([(nt neighbors) (in-hash table)]) + (define visited (make-hash)) + (for/or ([neighbor (in-list neighbors)]) + (let loop ([current-node neighbor]) + (cond + [(eq? current-node nt) nt] + [(hash-ref visited current-node #f) #f] + [else + (hash-set! visited current-node #t) + (for/or ([neighbor (in-list (hash-ref table current-node))]) + (loop neighbor))]))))) + + (when cycle + (raise-syntax-error 'define-language + (format + "found a cycle that includes the non-terminal ~a" + cycle) + stx))) \ No newline at end of file diff --git a/collects/redex/private/reduction-semantics.rkt b/collects/redex/private/reduction-semantics.rkt index a5dcfff531..b9fec26f41 100644 --- a/collects/redex/private/reduction-semantics.rkt +++ b/collects/redex/private/reduction-semantics.rkt @@ -6,6 +6,7 @@ "fresh.rkt" "loc-wrapper.rkt" "error.rkt" + (for-syntax "cycle-check.rkt") racket/trace racket/contract racket/list @@ -2369,7 +2370,7 @@ (let ([non-terms (parse-non-terminals #'nt-defs stx)]) (with-syntax ([((names prods ...) ...) non-terms] [(all-names ...) (apply append (map car non-terms))]) - (syntax/loc stx + (quasisyntax/loc stx (begin (define-syntax lang-name (make-set!-transformer @@ -2383,10 +2384,12 @@ (identifier? #'x) #'define-language-name])) '(all-names ...)))) - (define define-language-name (language form-name lang-name (all-names ...) (names prods ...) ...))))))))])) + (define define-language-name + #,(syntax/loc stx (language form-name lang-name (all-names ...) (names prods ...) ...)))))))))])) (define-struct binds (source binds)) + (define-syntax (language stx) (syntax-case stx () [(_ form-name lang-id (all-names ...) (name rhs ...) ...) @@ -2420,6 +2423,7 @@ (append (loop (car stx)) (loop (cdr stx)))] [else '()]))]) + (check-for-cycles stx #'(name ...) #'((r-rhs ...) ...)) (with-syntax ([(the-stx ...) (cdr (syntax-e stx))] [(all-names ...) all-names] [((uniform-names ...) ...) From 0b65f9989f366e0477cf63b6272564542d0d2611 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 8 Jan 2012 21:37:47 -0600 Subject: [PATCH 447/746] redex: adjust the test suites to clean up a few things; also make the hole and the-not-hole equal? to each other (like they used to be) (cherry picked from commit 2afda360d0f63a32c0c1726297e13e1c7c6428b5) --- collects/redex/private/matcher.rkt | 6 ++++-- collects/redex/tests/rg-test.rkt | 6 +++--- collects/redex/tests/tl-test.rkt | 8 ++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/collects/redex/private/matcher.rkt b/collects/redex/private/matcher.rkt index 0023279327..5a0de5ccd7 100644 --- a/collects/redex/private/matcher.rkt +++ b/collects/redex/private/matcher.rkt @@ -973,7 +973,7 @@ See match-a-pattern.rkt for more details [(2) (memoize/2 f w/hole)] [else (error 'memoize "unknown arity for ~s" f)])) -(define cache-size 63) +(define cache-size 255 #;63) (define (set-cache-size! cs) (set! cache-size cs)) ;; original version, but without closure allocation in hash lookup @@ -1821,7 +1821,9 @@ See match-a-pattern.rkt for more details (define (context? x) #t) (define-values (the-hole the-not-hole hole?) (let () - (define-struct hole (id) #:inspector #f) + (define-struct hole (id) + #:property prop:equal+hash (list (λ (x y recur) #t) (λ (v recur) 255) (λ (v recur) 65535)) + #:inspector #f) (define the-hole (make-hole 'the-hole)) (define the-not-hole (make-hole 'the-not-hole)) (values the-hole the-not-hole hole?))) diff --git a/collects/redex/tests/rg-test.rkt b/collects/redex/tests/rg-test.rkt index 08f03dc908..58dc19182d 100644 --- a/collects/redex/tests/rg-test.rkt +++ b/collects/redex/tests/rg-test.rkt @@ -92,7 +92,7 @@ (variable-except y) (name x 1) (name y 1)) - (y y)) + (y 12)) (test (hash-ref (base-cases-non-cross (find-base-cases L)) 'x) '(0 0 0 0))) @@ -666,7 +666,7 @@ (let () (define-language lang (d 5) - (e e 4) + (e 17 4) (n number)) (test (let ([checked 0]) @@ -884,7 +884,7 @@ (define-language L (e (+ e ...) number) (E (+ number ... E* e ...)) - (E* hole E*) + (E* hole) (n 4)) (let ([R (reduction-relation diff --git a/collects/redex/tests/tl-test.rkt b/collects/redex/tests/tl-test.rkt index f4d8f04caf..36f8086ca5 100644 --- a/collects/redex/tests/tl-test.rkt +++ b/collects/redex/tests/tl-test.rkt @@ -1,7 +1,7 @@ #lang racket (require "../reduction-semantics.rkt" "test-util.rkt" - (only-in "../private/matcher.rkt" make-bindings make-bind the-not-hole) + (only-in "../private/matcher.rkt" make-bindings make-bind) racket/match racket/trace "../private/struct.rkt") @@ -313,7 +313,7 @@ L (in-hole (cross e) e) (term (cont (1 hole)))) - (((e (cont (1 ,the-not-hole)))) + (((e (cont (1 hole)))) ((e 1))))) (let () (define-language L @@ -338,10 +338,10 @@ (in-hole (cross e) e) (term ((cont ((λ (x) x) hole)) (λ (y) y)))) (((e x)) - ((e ((cont ((λ (x) x) ,the-not-hole)) (λ (y) y)))) + ((e ((cont ((λ (x) x) hole)) (λ (y) y)))) ((e y)) ((e (λ (y) y))) - ((e (cont ((λ (x) x) ,the-not-hole))))))) + ((e (cont ((λ (x) x) hole))))))) ;; test caching (let () From 8bba1f245571cd6df51f21cf66222e80425d361b Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 8 Jan 2012 10:38:11 -0600 Subject: [PATCH 448/746] tweak the compiled representation of lw structs so they take less space this shrinks the size of redex/examples/r6rs/r6rs.rkt's .zo file by about 25% (cherry picked from commit 4fab7f76af520db59fb0486f28a33d90e7bfba90) --- collects/redex/pict.rkt | 22 +---- collects/redex/private/loc-wrapper-ct.rkt | 112 +++++++++++----------- collects/redex/private/loc-wrapper-rt.rkt | 56 ++++++++++- collects/redex/tests/lw-test.rkt | 2 +- 4 files changed, 112 insertions(+), 80 deletions(-) diff --git a/collects/redex/pict.rkt b/collects/redex/pict.rkt index e925afb820..e7055f2ea1 100644 --- a/collects/redex/pict.rkt +++ b/collects/redex/pict.rkt @@ -116,25 +116,9 @@ (require (prefix-in lw/ct: "private/loc-wrapper-ct.rkt") (prefix-in lw/rt: "private/loc-wrapper-rt.rkt")) (define (to-lw/stx stx) - (let loop ([stx (lw/ct:to-lw/proc stx)]) - (syntax-case stx (init-loc-wrapper make-lw add-spans list quote) - [(make-lw arg ...) - (apply make-lw (map loop (syntax->list #'(arg ...))))] - [(init-loc-wrapper arg ...) - (apply lw/rt:init-loc-wrapper (map loop (syntax->list #'(arg ...))))] - [(add-spans arg ...) - (apply lw/rt:add-spans (map loop (syntax->list #'(arg ...))))] - [(list arg ...) - (apply list (map loop (syntax->list #'(arg ...))))] - [(quote arg) - (syntax->datum #'arg)] - [_ - (let ([x (syntax-e stx)]) - (unless (or (number? x) - (string? x) - (boolean? x)) - (error 'to-lw/stx "unk thing: ~s\n" (syntax->datum stx))) - x)]))) + (lw/rt:add-spans/interp-lws + (syntax->datum + (lw/ct:to-lw/proc stx #f)))) (provide/contract [just-before (-> (or/c pict? string? symbol?) lw? lw?)] diff --git a/collects/redex/private/loc-wrapper-ct.rkt b/collects/redex/private/loc-wrapper-ct.rkt index fd259c277e..e17058638a 100644 --- a/collects/redex/private/loc-wrapper-ct.rkt +++ b/collects/redex/private/loc-wrapper-ct.rkt @@ -6,6 +6,7 @@ (define (process-arg stx quote-depth) (define quoted? (quote-depth . > . 0)) + (define init-loc-wrapper/q? (if quoted? 'init-loc-wrapper/quoted 'init-loc-wrapper/unquoted)) (define-values (op cl) (if (syntax? stx) (case (syntax-property stx 'paren-shape) @@ -14,79 +15,78 @@ [else (values "(" ")")]) (values #f #f))) (define (reader-shorthand arg qd-delta mrk) - #`(init-loc-wrapper - (list (init-loc-wrapper #,mrk - #,(syntax-line stx) - #,(syntax-column stx) - #,quoted?) - 'spring - #,(process-arg arg (+ quote-depth qd-delta))) - #,(syntax-line stx) - #,(syntax-column stx) - #,quoted?)) + #`#(#,init-loc-wrapper/q? + #(list #(#,init-loc-wrapper/q? #,mrk + #,(syntax-line stx) + #,(syntax-column stx)) + 'spring + #,(process-arg arg (+ quote-depth qd-delta))) + #,(syntax-line stx) + #,(syntax-column stx))) (define (handle-sequence qd-delta) - #`(init-loc-wrapper - (list (init-loc-wrapper #,op #,(syntax-line stx) #,(syntax-column stx) #,quoted?) - #,@(map (λ (x) (process-arg x (+ qd-delta quote-depth))) (syntax->list stx)) - (init-loc-wrapper #,cl #f #f #,quoted?)) - #,(syntax-line stx) - #,(syntax-column stx) - #,quoted?)) + (with-syntax ([(others ...) (map (λ (x) (process-arg x (+ qd-delta quote-depth))) (syntax->list stx))]) + #`#(#,(if quoted? + 'init-loc-wrapper-sequence/quoted + 'init-loc-wrapper-sequence/unquoted) + #,op #,(syntax-line stx) #,(syntax-column stx) + others ...))) (syntax-case* stx (name unquote quote unquote-splicing term) (λ (x y) (eq? (syntax-e x) (syntax-e y))) ['a (reader-shorthand #'a +1 (if (= quote-depth 0) "" "'"))] [,a (reader-shorthand #'a -1 (if (= quote-depth 1) "" ","))] [,@a (reader-shorthand #'a -1 (if (= quote-depth 1) "" ",@"))] [(term a) (if (= quote-depth 0) - #`(init-loc-wrapper - (list (init-loc-wrapper "" #,(syntax-line stx) #,(syntax-column stx) #,quoted?) - 'spring - #,(process-arg (cadr (syntax->list stx)) (+ quote-depth 1))) - #,(syntax-line stx) - #,(syntax-column stx) - #,quoted?) + #`#(#,init-loc-wrapper/q? + #(list #(#,init-loc-wrapper/q? "" #,(syntax-line stx) #,(syntax-column stx)) + 'spring + #,(process-arg (cadr (syntax->list stx)) (+ quote-depth 1))) + #,(syntax-line stx) + #,(syntax-column stx)) (handle-sequence +1))] [(a ...) (handle-sequence 0)] [(a b ... . c) - #`(init-loc-wrapper - (list (init-loc-wrapper #,op #,(syntax-line stx) #,(syntax-column stx) #,quoted?) - #,@(map (λ (x) (process-arg x quote-depth)) (syntax->list (syntax (a b ...)))) - (init-loc-wrapper #," . " #f #f #,quoted?) - #,(process-arg #'c quote-depth) - (init-loc-wrapper #,cl #f #f #,quoted?)) - #,(syntax-line stx) - #,(syntax-column stx) - #,quoted?)] + #`#(#,init-loc-wrapper/q? + #(list #(#,init-loc-wrapper/q? #,op #,(syntax-line stx) #,(syntax-column stx)) + #,@(map (λ (x) (process-arg x quote-depth)) (syntax->list (syntax (a b ...)))) + #(i,init-loc-wrapper/q? #," . " #f #f) + #,(process-arg #'c quote-depth) + #(#,init-loc-wrapper/q? #,cl #f #f)) + #,(syntax-line stx) + #,(syntax-column stx))] [x (and (identifier? #'x) (and (syntax-transforming?) (or (term-fn? (syntax-local-value #'x (λ () #f))) (judgment-form? (syntax-local-value #'x (λ () #f)))))) - #`(make-lw - '#,(syntax-e #'x) - #,(syntax-line stx) - #f - #,(syntax-column stx) - #f - #f - #t)] + #`#(make-lw + '#,(syntax-e #'x) + #,(syntax-line stx) + #f + #,(syntax-column stx) + #f + #f + #t)] [x (identifier? #'x) - #`(init-loc-wrapper - '#,(syntax-e #'x) - #,(syntax-line stx) - #,(syntax-column stx) - #,quoted?)] + #`#(#,init-loc-wrapper/q? + '#,(syntax-e #'x) + #,(syntax-line stx) + #,(syntax-column stx))] [x - #`(init-loc-wrapper - #,(let ([base (syntax-e #'x)]) - (if (string? base) - #`(rewrite-quotes #,(format "~s" base)) - (format "~s" (syntax-e #'x)))) - #,(syntax-line stx) - #,(syntax-column stx) - #,quoted?)])) + #`#(#,init-loc-wrapper/q? + #,(let ([base (syntax-e #'x)]) + (if (string? base) + #`#(rewrite-quotes #,(format "~s" base)) + (format "~s" (syntax-e #'x)))) + #,(syntax-line stx) + #,(syntax-column stx))])) -(define (to-lw/proc stx) #`(add-spans #,(process-arg stx 1))) -(define (to-lw/uq/proc stx) #`(add-spans #,(process-arg stx 0))) +(define (to-lw/proc stx [add-add-spans? #t]) + (if add-add-spans? + #`(add-spans/interp-lws #,(process-arg stx 1)) + (process-arg stx 1))) +(define (to-lw/uq/proc stx [add-add-spans? #t]) + (if add-add-spans? + #`(add-spans/interp-lws #,(process-arg stx 0)) + (process-arg stx 0))) diff --git a/collects/redex/private/loc-wrapper-rt.rkt b/collects/redex/private/loc-wrapper-rt.rkt index e3f285e9a9..2f61659c04 100644 --- a/collects/redex/private/loc-wrapper-rt.rkt +++ b/collects/redex/private/loc-wrapper-rt.rkt @@ -1,15 +1,22 @@ -#lang scheme/base +#lang racket/base ;; this is the runtime code for loc-wrapper-ct.rkt. ;; it isn't really its own module, but separated ;; out in order to get the phases right. (provide (all-defined-out)) -(require mzlib/etc +(require racket/match "term.rkt") (define (init-loc-wrapper e line column quoted?) - (make-lw e line #f column #f (not quoted?) #f)) + (if quoted? + (make-lw e line #f column #f #f #f) + (make-lw e line #f column #f #t #f))) + +(define (init-loc-wrapper/unquoted e line column) + (init-loc-wrapper e line column #f)) +(define (init-loc-wrapper/quoted e line column) + (init-loc-wrapper e line column #t)) ;; lw = (union 'spring loc-wrapper) @@ -32,6 +39,48 @@ "”") s)) +(define (add-spans/interp-lws arg) + (add-spans + (let loop ([arg arg]) + (match arg + [(vector 'init-loc-wrapper/quoted e line column) + (init-loc-wrapper/quoted (loop e) (loop line) (loop column))] + [(vector 'init-loc-wrapper/unquoted e line column) + (init-loc-wrapper/unquoted (loop e) (loop line) (loop column))] + [(vector 'make-lw e line line-span column column-span unq? metafunction?) + (make-lw (loop e) (loop line) (loop line-span) (loop column) + (loop column-span) (loop unq?) (loop metafunction?))] + [(vector 'rewrite-quotes arg) + (rewrite-quotes (loop arg))] + [(vector 'list x ...) + (map loop x)] + [(vector (and (or 'init-loc-wrapper-sequence/quoted + 'init-loc-wrapper-sequence/unquoted) + kwd) + open line col args ...) + (define quoted? (eq? 'init-loc-wrapper-sequence/quoted kwd)) + (define l-line (loop line)) + (define l-col (loop col)) + (init-loc-wrapper + (cons (init-loc-wrapper open l-line l-col quoted?) + (append (map loop args) + (list (init-loc-wrapper (open->close open) #f #f quoted?)))) + l-line l-col quoted?)] + [`(quote ,x) x] + [(? number?) arg] + [(? boolean?) arg] + [(? string?) arg] + [(? symbol?) arg] + [else + (error 'add-spans/interp-lws "unk ~s" arg)])))) + +(define (open->close open) + (cond + [(equal? open "(") ")"] + [(equal? open "[") "]"] + [(equal? open "{") "}"] + [(equal? open #f) #f] + [else (error 'open->close "unk ~s" open)])) (define (add-spans lw) (define line-seen-so-far 0) @@ -93,4 +142,3 @@ [b b] [else 0])) - diff --git a/collects/redex/tests/lw-test.rkt b/collects/redex/tests/lw-test.rkt index 1cc6bc67d2..31cfe3cd29 100644 --- a/collects/redex/tests/lw-test.rkt +++ b/collects/redex/tests/lw-test.rkt @@ -60,7 +60,7 @@ (test (normalize-lw (to-lw ())) (build-lw (list (build-lw "(" 0 0 0 1) (build-lw ")" 0 0 1 1)) - 0 0 0 2)) + 0 0 0 2)) (test (normalize-lw (to-lw "x")) (build-lw "“x”" 0 0 0 3)) From 7949ede5d55b192d9916fc701fcab6e95152a1ef Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 9 Jan 2012 12:17:48 -0600 Subject: [PATCH 449/746] removed ambiguity from the cont-mark-transform's "a" non-terminal Redex no longer has extra checks to eliminate redundant matches (as those checks are prohibitively expensive for the lambdajs model) so redundancy in the grammar can, when combined with context decomposition or named patterns, lead to significant slowdowns (cherry picked from commit 0c6e0a11cfe876ad2f447e3a1043d03f9f8deef8) --- collects/redex/examples/cont-mark-transform/SL-syntax.rkt | 2 ++ collects/redex/examples/cont-mark-transform/TL-syntax.rkt | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/collects/redex/examples/cont-mark-transform/SL-syntax.rkt b/collects/redex/examples/cont-mark-transform/SL-syntax.rkt index 8c1fad5977..b40fdff2b1 100644 --- a/collects/redex/examples/cont-mark-transform/SL-syntax.rkt +++ b/collects/redex/examples/cont-mark-transform/SL-syntax.rkt @@ -9,6 +9,8 @@ (call/cc w)) (v .... (κ (hide-hole E))) + (a .... + (κ (hide-hole E))) (D (w-c-m v v D) hole diff --git a/collects/redex/examples/cont-mark-transform/TL-syntax.rkt b/collects/redex/examples/cont-mark-transform/TL-syntax.rkt index bd036956e0..767bed49fb 100644 --- a/collects/redex/examples/cont-mark-transform/TL-syntax.rkt +++ b/collects/redex/examples/cont-mark-transform/TL-syntax.rkt @@ -13,7 +13,9 @@ (abort e)) (l [(K x ...) e]) - (a w + (a (λ (x ...) e) + σ + x (K a ...)) (w v x) @@ -28,3 +30,6 @@ (Σ [σ ↦ v])) (K string)) + + + From a8cf31779f9477ccf20c1a6f7710ec7008a34635 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 9 Jan 2012 12:21:11 -0600 Subject: [PATCH 450/746] redex: misc cleanups: - remove cache instrumentation code - make hole->not-hole parsimonous - change the cache size back to 63 (cherry picked from commit a12df9cea6a11b3a6c174a3907382b2157f5e0aa) --- collects/redex/private/matcher.rkt | 64 +++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/collects/redex/private/matcher.rkt b/collects/redex/private/matcher.rkt index 5a0de5ccd7..d57a830826 100644 --- a/collects/redex/private/matcher.rkt +++ b/collects/redex/private/matcher.rkt @@ -809,7 +809,9 @@ See match-a-pattern.rkt for more details (lambda (exp hole-info) (let ([matches (match-pat exp #f)]) (and matches - (map (λ (match) (make-mtch (mtch-bindings match) (hole->not-hole (mtch-context match)) none)) + (map (λ (match) (make-mtch (mtch-bindings match) + (hole->not-hole (mtch-context match)) + none)) matches))))] [else (lambda (exp hole-info) @@ -926,7 +928,7 @@ See match-a-pattern.rkt for more details (equal? pattern exp)))])])) ;; simple-match : (any -> bool) -> (values boolean boolean) - ;; does a match based on a built-in Scheme predicate + ;; does a match based on a predicate (define (simple-match pred) (values (lambda (exp) (pred exp)) #f @@ -973,7 +975,7 @@ See match-a-pattern.rkt for more details [(2) (memoize/2 f w/hole)] [else (error 'memoize "unknown arity for ~s" f)])) -(define cache-size 255 #;63) +(define cache-size 63) (define (set-cache-size! cs) (set! cache-size cs)) ;; original version, but without closure allocation in hash lookup @@ -1025,15 +1027,17 @@ See match-a-pattern.rkt for more details (cond [(not (caching-enabled?)) (f args ...)] [else - (record-cache-test! statsbox) + ;(record-cache-test! statsbox) + ;(when (zero? (modulo (cache-stats-hits statsbox) 1000)) + ; (record-cache-size! statsbox (cons ans-vec key-vec))) (let* ([key key-exp] [index (modulo (equal-hash-code key) this-cache-size)]) (cond [(equal? (vector-ref key-vec index) key) (vector-ref ans-vec index)] [else - (record-cache-miss! statsbox) - (when (eq? uniq (vector-ref key-vec index)) (record-cache-clobber! statsbox)) + ;(record-cache-miss! statsbox) + (unless (eq? uniq (vector-ref key-vec index)) (record-cache-clobber! statsbox)) (let ([ans (f args ...)]) (vector-set! key-vec index key) (vector-set! ans-vec index ans) @@ -1223,12 +1227,25 @@ See match-a-pattern.rkt for more details (define (record-cache-clobber! statsbox) (set-cache-stats-clobber-hits! statsbox (add1 (cache-stats-clobber-hits statsbox)))) -(define-struct cache-stats (name misses hits clobber-hits) #:mutable) -(define (new-cache-stats name) (make-cache-stats name 0 0 0)) +(define-struct cache-stats (name misses hits clobber-hits sizes) #:mutable) +(define (new-cache-stats name) (make-cache-stats name 0 0 0 '())) (define w/hole (new-cache-stats "hole")) (define nohole (new-cache-stats "no-hole")) +(define (record-cache-size! cache-stats cache) + (define size + (let loop ([cache cache]) + (cond + [(vector? cache) + (for/fold ([size (vector-length cache)]) + ([ele (in-vector cache)]) + (+ size (loop ele)))] + [(pair? cache) + (+ 1 (loop (car cache)) (loop (cdr cache)))] + [else 1]))) + (set-cache-stats-sizes! cache-stats (cons size (cache-stats-sizes cache-stats)))) + (define (print-stats) (let ((stats (list w/hole nohole))) (for-each @@ -1250,7 +1267,13 @@ See match-a-pattern.rkt for more details (when (> (+ overall-hits overall-miss) 0) (printf "Overall miss rate: ~a%\n" (floor (* 100 (/ overall-miss (+ overall-hits overall-miss)))))) - (printf "Overall clobbering hits: ~a\n" overall-clobber-hits)))) + (printf "Overall clobbering hits: ~a\n" overall-clobber-hits)) + + (let* ([sizes (apply append (map cache-stats-sizes stats))] + [len (length sizes)]) + (unless (zero? len) + (let ([avg (/ (apply + 0.0 sizes) len)]) + (printf "Average cache size ~s; ~a samples\n" avg len)))))) ;; match-hole : compiled-pattern (define match-hole @@ -1828,12 +1851,23 @@ See match-a-pattern.rkt for more details (define the-not-hole (make-hole 'the-not-hole)) (values the-hole the-not-hole hole?))) -(define hole->not-hole - (match-lambda - [(? hole?) the-not-hole] - [(list-rest f r) - (cons (hole->not-hole f) (hole->not-hole r))] - [x x])) +(define (hole->not-hole exp) + (let loop ([exp exp]) + (cond + [(pair? exp) + (define old-car (car exp)) + (define new-car (loop old-car)) + (cond + [(eq? new-car old-car) + (define old-cdr (cdr exp)) + (define new-cdr (loop old-cdr)) + (if (eq? new-cdr old-cdr) + exp + (cons new-car new-cdr))] + [else (cons new-car (cdr exp))])] + [(eq? exp the-hole) + the-not-hole] + [else exp]))) (define (build-flat-context exp) exp) (define (build-cons-context e1 e2) (cons e1 e2)) From 8df51241ff25f75bd5defcf92d9bfb90c245ed0e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 9 Jan 2012 12:55:57 -0600 Subject: [PATCH 451/746] add check-redundancy, a parameter that causes redex to print some debugging information about ambiguous matching (when the ambiguity matters) (cherry picked from commit 6cacd57ebc47b0931e849c99b0aba671b2b8c945) --- collects/redex/private/matcher.rkt | 18 ++++++++++++++++-- collects/redex/redex.scrbl | 12 +++++++++++- collects/redex/reduction-semantics.rkt | 3 ++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/collects/redex/private/matcher.rkt b/collects/redex/private/matcher.rkt index d57a830826..a2be03894e 100644 --- a/collects/redex/private/matcher.rkt +++ b/collects/redex/private/matcher.rkt @@ -1624,7 +1624,18 @@ See match-a-pattern.rkt for more details [(null? rhss) (if (null? ans) #f - ans)] + (begin + (when (check-redudancy) + (let ([rd (remove-duplicates ans)]) + (unless (= (length rd) (length ans)) + (eprintf "found redundancy when matching the non-terminal ~s against:\n~s~a" + nt + term + (apply + string-append + (map (λ (x) (format "\n ~s" x)) + ans)))))) + ans))] [else (let ([mth (call-nt-proc/bindings (car rhss) term hole-info)]) (cond @@ -1644,6 +1655,8 @@ See match-a-pattern.rkt for more details (or (call-nt-proc/bindings (car rhss) term hole-info) (loop (cdr rhss)))])))) +(define check-redudancy (make-parameter #f)) + (define (match-nt/boolean list-rhs non-list-rhs nt term) (let loop ([rhss (if (or (null? term) (pair? term)) list-rhs @@ -1956,4 +1969,5 @@ See match-a-pattern.rkt for more details the-not-hole the-hole hole? rewrite-ellipses build-compatible-context-language - caching-enabled?) + caching-enabled? + check-redudancy) diff --git a/collects/redex/redex.scrbl b/collects/redex/redex.scrbl index 18ce506ad9..134dcdcb58 100644 --- a/collects/redex/redex.scrbl +++ b/collects/redex/redex.scrbl @@ -389,7 +389,17 @@ nested lists. } @defproc[(set-cache-size! [size positive-integer?]) void?]{ -Changes the size of the per-pattern and per-metafunction caches. The default size is @racket[350]. +Changes the size of the per-pattern and per-metafunction caches. + +The default size is @racket[350]. +} + +@defparam[check-redudancy check? boolean?]{ + Ambiguous patterns can slow down + Redex's pattern matching implementation significantly. To help debug + such performance issues, set the @racket[check-redundancy] + parameter to @racket[#t]. This causes Redex to, at runtime, + report any redundant matches that it encounters. } @section{Terms} diff --git a/collects/redex/reduction-semantics.rkt b/collects/redex/reduction-semantics.rkt index ab13796c2d..27bae98c19 100644 --- a/collects/redex/reduction-semantics.rkt +++ b/collects/redex/reduction-semantics.rkt @@ -33,7 +33,8 @@ judgment-holds in-domain? caching-enabled? - make-coverage) + make-coverage + check-redudancy) (provide (rename-out [test-match redex-match]) term-match From 883ddb5bec25ca937178bdf71e90ce5012325c6a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 9 Jan 2012 14:01:44 -0700 Subject: [PATCH 452/746] collapse Racket HISTORY.txt for v5.2.1 Merge to 5.2.1 (cherry picked from commit 0d47cea848343694c9a2cc05121a4a1bfee15a27) --- doc/release-notes/racket/HISTORY.txt | 43 +++++++++++----------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index 65bccc5923..ed07f524c8 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,39 +1,28 @@ -Version 5.2.0.7 -Intern strings, etc., only in read-syntax mode, not read mode -racket/draw: add text-outline to dc-path% -net/mime: allow any subtype in input; made exception structs a - subtype of exn:fail - -Version 5.2.0.6 -Added pseudo-random-generator-vector? - -Version 5.2.0.5 -Cross-module inlining of trivial functions, plus map, for-each, +Version 5.2.1, January 2012 +Changed I/O scheduling to use epoll()/kqueue() when available +Cross-module inline trivial functions, plus map, for-each, andmap, and ormap; 'compiler-hint:cross-module-inline hint -Generalize gcd and lcm to work on rationals -compiler/zo-structs: added inline-variant -racket/stream: added stream constructor - -Version 5.2.0.4 +Intern numbers, characters, strings, byte strings, and regexps in + read and datum->syntax +Added datum-intern-literal Regexps are `equal?' when they have the same source [byte] string and mode -Numbers, characters, strings, byte strings, and regexps are interned by - read and datum->syntax -Added read-intern-literal +Added pseudo-random-generator-vector? +Added port-closed-evt +Generalized gcd and lcm to work on rationals +Added module-predefined? +Changed the racket -k command-line flag racket/class: added send/keyword-apply and dynamic-send racket/draw: added get-names to color-database<%> mzlib/pconvert: added add-make-prefix-to-constructor parameter, which changes the default constructor-style printing in DrRacket to avoid a make- prefix; the HtDP languages set the parameter to #t at-exp, scribble: dropped distinctness of @{}-introduced newline strings - -Version 5.2.0.3 -Added module-predefined? -Changed the raacket -k command-line flag - -Version 5.2.0.2 -Added port-closed-evt -Changed I/O scheduling to use epoll()/kqueue() when available +racket/draw: add text-outline to dc-path% +net/mime: allow any subtype in input; made exception structs a + subtype of exn:fail +compiler/zo-structs: added inline-variant +racket/stream: added stream constructor Version 5.2, November 2011 Generalized begin-with-syntax to allow phase-N definitions, From 8a17b5bf3268c66499c3e8868de3812109e622f8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 9 Jan 2012 16:31:45 -0700 Subject: [PATCH 453/746] add `#:fail' option to `collection-file-path' and `collection-path' This is mostly the same as commit 23010fc4956b2b7dc91b468fd7b6ed8365d0d47e, but the version-number and "cstartup.inc" changes have been adjusted to work with the release branch. --- collects/mzscheme/mzscheme.scrbl | 16 +- collects/racket/private/pre-base.rkt | 27 +- collects/scheme/mzscheme.rkt | 27 +- collects/scribblings/reference/collects.scrbl | 37 +- collects/tests/racket/module.rktl | 14 + doc/release-notes/racket/HISTORY.txt | 2 + src/racket/src/cstartup.inc | 1807 +++++++++-------- src/racket/src/schvers.h | 4 +- src/racket/src/startup.inc | 56 +- src/racket/src/startup.rktl | 101 +- 10 files changed, 1094 insertions(+), 997 deletions(-) diff --git a/collects/mzscheme/mzscheme.scrbl b/collects/mzscheme/mzscheme.scrbl index d748d30168..6074000da3 100644 --- a/collects/mzscheme/mzscheme.scrbl +++ b/collects/mzscheme/mzscheme.scrbl @@ -25,7 +25,8 @@ base-if base-cond base-case base-top-interaction base-open-input-file base-apply base-prop:procedure base-free-identifier=? base-free-template-identifier=? - base-free-transformer-identifier=? base-free-label-identifier=?) + base-free-transformer-identifier=? base-free-label-identifier=? + base-collection-file-path base-collection-path) (begin (require (for-label scheme/base)) (define base-define (racket define)) @@ -42,12 +43,15 @@ (define base-free-identifier=? (racket free-identifier=?)) (define base-free-template-identifier=? (racket free-template-identifier=?)) (define base-free-transformer-identifier=? (racket free-transformer-identifier=?)) - (define base-free-label-identifier=? (racket free-label-identifier=?)))) + (define base-free-label-identifier=? (racket free-label-identifier=?)) + (define base-collection-file-path (racket collection-file-path)) + (define base-collection-path (racket collection-path)))) @(def-base base-define base-define-syntax base-define-for-syntax base-define-struct base-if base-cond base-case base-top-interaction base-open-input-file base-apply base-prop:procedure base-free-identifier=? base-free-template-identifier=? - base-free-transformer-identifier=? base-free-label-identifier=?) + base-free-transformer-identifier=? base-free-label-identifier=? + base-collection-file-path base-collection-path) @(define-syntax-rule (additionals racket/base id ...) (begin @@ -430,7 +434,13 @@ The same as @racket[cleanse-path].} The same as @racket[list].} +@deftogether[( +@defproc[(collection-file-path [file path-string?] [collection path-string?] ...+) path?] +@defproc[(collection-path [collection path-string?] ...+) path?] +)]{ +Like @base-collection-file-path and @base-collection-path, but without +the @racket[#:fail] option.} @; ---------------------------------------- diff --git a/collects/racket/private/pre-base.rkt b/collects/racket/private/pre-base.rkt index ae50fd37ea..19c962a8de 100644 --- a/collects/racket/private/pre-base.rkt +++ b/collects/racket/private/pre-base.rkt @@ -106,8 +106,31 @@ (define-values (double-flonum?) ; for symmetry with single-flonum? (lambda (x) (flonum? x))) + (define-values (new:collection-path) + (let ([collection-path (new-lambda (collection + #:fail [fail (lambda (s) + (raise + (exn:fail:filesystem + (string-append "collection-path: " s) + (current-continuation-marks))))] + . collections) + (apply collection-path fail collection collections))]) + collection-path)) + + (define-values (new:collection-file-path) + (let ([collection-file-path (new-lambda (file-name + collection + #:fail [fail (lambda (s) + (raise + (exn:fail:filesystem + (string-append "collection-file-path: " s) + (current-continuation-marks))))] + . collections) + (apply collection-file-path fail file-name collection collections))]) + collection-file-path)) + (#%provide (all-from-except "more-scheme.rkt" old-case fluid-let) - (all-from "misc.rkt") + (all-from-except "misc.rkt" collection-path collection-file-path) (all-from "define.rkt") (all-from-except "letstx-scheme.rkt" -define -define-syntax -define-struct old-cond) (rename new-lambda lambda) @@ -130,6 +153,8 @@ (rename new:procedure-rename procedure-rename) (rename new:chaperone-procedure chaperone-procedure) (rename new:impersonate-procedure impersonate-procedure) + (rename new:collection-path collection-path) + (rename new:collection-file-path collection-file-path) (all-from-except '#%kernel lambda λ #%app #%module-begin apply prop:procedure procedure-arity procedure-reduce-arity raise-arity-error procedure->method procedure-rename diff --git a/collects/scheme/mzscheme.rkt b/collects/scheme/mzscheme.rkt index a629f1eaa6..b03edd02ee 100644 --- a/collects/scheme/mzscheme.rkt +++ b/collects/scheme/mzscheme.rkt @@ -27,13 +27,38 @@ racket/udp '#%builtin) ; so it's attached + (define new:collection-path + (let ([collection-path (lambda (collection . collections) + (apply collection-path + (lambda (s) + (raise + (exn:fail:filesystem + (string-append "collection-path: " s) + (current-continuation-marks)))) + collection collections))]) + collection-path)) + + (define new:collection-file-path + (let ([collection-file-path (lambda (file-name collection . collections) + (apply collection-file-path + (lambda (s) + (raise + (exn:fail:filesystem + (string-append "collection-file-path: " s) + (current-continuation-marks)))) + file-name collection collections))]) + collection-file-path)) + + (#%provide require require-for-syntax require-for-template require-for-label provide provide-for-syntax provide-for-label (all-from-except racket/private/more-scheme case old-case log-fatal log-error log-warning log-info log-debug hash-update hash-update!) (rename old-case case) - (all-from racket/private/misc) + (all-from-except racket/private/misc collection-path collection-file-path) + (rename new:collection-path collection-path) + (rename new:collection-file-path collection-file-path) (all-from-except racket/private/stxcase-scheme _ datum datum-case with-datum) (all-from-except racket/private/letstx-scheme -define -define-syntax -define-struct diff --git a/collects/scribblings/reference/collects.scrbl b/collects/scribblings/reference/collects.scrbl index af4daf00d9..c0c2c90b91 100644 --- a/collects/scribblings/reference/collects.scrbl +++ b/collects/scribblings/reference/collects.scrbl @@ -124,21 +124,38 @@ Produces a list of paths as follows: ]} -@defproc[(collection-file-path [file path-string?] [collection path-string?] ...+) path?]{ +@defproc*[([(collection-file-path [file path-string?] [collection path-string?] ...+) + path?] + [(collection-file-path [file path-string?] [collection path-string?] ...+ + [#:fail fail-proc (string? . -> . any)]) + any])]{ Returns the path to the file indicated by @racket[file] in the collection specified by the @racket[collection]s, where the second -@racket[collection] (if any) names a sub-collection, and so on. If -@racket[file] is not found, but @racket[file] ends in @filepath{.rkt} -and a file with the suffix @filepath{.ss} exists, then the directory -of the @filepath{.ss} file is used. If @racket[file] is not found and -the @filepath{.rkt}/@filepath{.ss} conversion does not apply, but a -directory corresponding to the @racket[collection]s is found, then a -path using the first such directory is returned. Finally, if the -collection is not found, the @exnraise[exn:fail:filesystem].} +@racket[collection] (if any) names a sub-collection, and so on. + +If @racket[file] is not found, but @racket[file] ends in +@filepath{.rkt} and a file with the suffix @filepath{.ss} exists, then +the directory of the @filepath{.ss} file is used. If @racket[file] is +not found and the @filepath{.rkt}/@filepath{.ss} conversion does not +apply, but a directory corresponding to the @racket[collection]s is +found, then a path using the first such directory is +returned. + +Finally, if the collection is not found, and if @racket[fail-proc] is +provided, then @racket[fail-proc] is applied to an error message (that +does not start @scheme["collection-file-path:"] or otherwise claim a +source), and its result is the result of +@racket[collection-file-path]. If @racket[fail-proc] is not provided +and the collection is not found, then the +@exnraise[exn:fail:filesystem].} -@defproc[(collection-path [collection path-string?] ...+) path?]{ +@defproc*[([(collection-path [collection path-string?] ...+) + path?] + [(collection-path [collection path-string?] ...+ + [#:fail fail-proc (string? . -> . any)]) + any])]{ Like @racket[collection-file-path], but without a specified file name, so that the first directory indicated by @racket[collection]s is diff --git a/collects/tests/racket/module.rktl b/collects/tests/racket/module.rktl index d5ea51aae3..7da0c33d65 100644 --- a/collects/tests/racket/module.rktl +++ b/collects/tests/racket/module.rktl @@ -465,6 +465,20 @@ (test #t module-path? '(planet "foo.rkt" ("robby" "redex.plt") "sub" "deeper")) (test #t module-path? '(planet "foo%2e.rkt" ("robby%2e" "redex%2e.plt") "sub%2e" "%2edeeper")) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; check collection-path details + +(test-values '(not there) (lambda () + (collection-path "nonesuch" + #:fail (lambda (s) + (test #t string? s) + (values 'not 'there))))) +(test-values '(1 2) (lambda () + (collection-file-path "none.rkt" "nonesuch" + #:fail (lambda (s) + (test #t string? s) + (values 1 2))))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check 'module-language, `module-compiled-language-info', and `module->language-info' diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index ed07f524c8..0aefd6ab6f 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -11,6 +11,8 @@ Added pseudo-random-generator-vector? Added port-closed-evt Generalized gcd and lcm to work on rationals Added module-predefined? +Added optional #:fail argument to collection-file-path and + collection-path Changed the racket -k command-line flag racket/class: added send/keyword-apply and dynamic-send racket/draw: added get-names to color-database<%> diff --git a/src/racket/src/cstartup.inc b/src/racket/src/cstartup.inc index 741000df87..52343679e3 100644 --- a/src/racket/src/cstartup.inc +++ b/src/racket/src/cstartup.inc @@ -1,794 +1,798 @@ { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,50,46,48,46,54,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,51,0,0,0,1,0,0,10,0,13,0,18, -0,25,0,30,0,33,0,46,0,53,0,58,0,62,0,66,0,73,0,82,0, -85,0,91,0,105,0,119,0,122,0,128,0,132,0,134,0,145,0,147,0,161, -0,168,0,190,0,192,0,206,0,17,1,46,1,57,1,68,1,93,1,126,1, -159,1,218,1,17,2,95,2,150,2,155,2,175,2,68,3,88,3,140,3,206, -3,95,4,237,4,34,5,45,5,124,5,0,0,83,7,0,0,69,35,37,109, -105,110,45,115,116,120,29,11,11,64,119,104,101,110,66,100,101,102,105,110,101, -64,99,111,110,100,62,111,114,72,112,97,114,97,109,101,116,101,114,105,122,101, -66,108,101,116,114,101,99,64,108,101,116,42,63,108,101,116,63,97,110,100,66, -117,110,108,101,115,115,68,104,101,114,101,45,115,116,120,29,11,11,65,113,117, -111,116,101,29,94,2,15,68,35,37,107,101,114,110,101,108,11,29,94,2,15, -68,35,37,112,97,114,97,109,122,11,62,105,102,65,98,101,103,105,110,63,115, -116,120,61,115,70,108,101,116,45,118,97,108,117,101,115,61,120,73,108,101,116, -114,101,99,45,118,97,108,117,101,115,66,108,97,109,98,100,97,1,20,112,97, -114,97,109,101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,61,118,73, -100,101,102,105,110,101,45,118,97,108,117,101,115,97,36,11,8,240,152,76,0, -0,95,159,2,17,36,36,159,2,16,36,36,159,2,16,36,36,16,20,2,3, -2,2,2,4,2,2,2,5,2,2,2,6,2,2,2,7,2,2,2,8,2, -2,2,9,2,2,2,10,2,2,2,11,2,2,2,12,2,2,97,37,11,8, -240,152,76,0,0,93,159,2,16,36,37,16,2,2,13,161,2,2,37,2,13, -2,2,2,13,96,38,11,8,240,152,76,0,0,16,0,96,11,11,8,240,152, -76,0,0,16,0,18,98,64,104,101,114,101,13,16,5,36,2,14,2,2,11, -11,8,32,8,31,8,30,8,29,27,248,22,156,4,195,249,22,149,4,80,158, -39,36,251,22,83,2,18,248,22,98,199,12,249,22,73,2,19,248,22,100,201, -27,248,22,156,4,195,249,22,149,4,80,158,39,36,251,22,83,2,18,248,22, -98,199,249,22,73,2,19,248,22,100,201,12,27,248,22,75,248,22,156,4,196, -28,248,22,81,193,20,14,159,37,36,37,28,248,22,81,248,22,75,194,248,22, -74,193,249,22,149,4,80,158,39,36,251,22,83,2,18,248,22,74,199,249,22, -73,2,11,248,22,75,201,11,18,100,10,13,16,5,36,2,14,2,2,11,11, -8,32,8,31,8,30,8,29,16,4,11,11,2,20,3,1,8,101,110,118,49, -53,48,49,54,16,4,11,11,2,21,3,1,8,101,110,118,49,53,48,49,55, -27,248,22,75,248,22,156,4,196,28,248,22,81,193,20,14,159,37,36,37,28, -248,22,81,248,22,75,194,248,22,74,193,249,22,149,4,80,158,39,36,250,22, -83,2,22,248,22,83,249,22,83,248,22,83,2,23,248,22,74,201,251,22,83, -2,18,2,23,2,23,249,22,73,2,6,248,22,75,204,18,100,11,13,16,5, -36,2,14,2,2,11,11,8,32,8,31,8,30,8,29,16,4,11,11,2,20, -3,1,8,101,110,118,49,53,48,49,57,16,4,11,11,2,21,3,1,8,101, -110,118,49,53,48,50,48,248,22,156,4,193,27,248,22,156,4,194,249,22,73, -248,22,83,248,22,74,196,248,22,75,195,27,248,22,75,248,22,156,4,23,197, -1,249,22,149,4,80,158,39,36,28,248,22,58,248,22,150,4,248,22,74,23, -198,2,27,249,22,2,32,0,88,163,8,36,37,43,11,9,222,33,40,248,22, -156,4,248,22,98,23,200,2,250,22,83,2,24,248,22,83,249,22,83,248,22, -83,248,22,74,23,204,2,250,22,84,2,25,249,22,2,22,74,23,204,2,248, -22,100,23,206,2,249,22,73,248,22,74,23,202,1,249,22,2,22,98,23,200, -1,250,22,84,2,22,249,22,2,32,0,88,163,8,36,37,47,11,9,222,33, -41,248,22,156,4,248,22,74,201,248,22,75,198,27,248,22,156,4,194,249,22, -73,248,22,83,248,22,74,196,248,22,75,195,27,248,22,75,248,22,156,4,23, -197,1,249,22,149,4,80,158,39,36,250,22,84,2,24,249,22,2,32,0,88, -163,8,36,37,47,11,9,222,33,43,248,22,156,4,248,22,74,201,248,22,75, -198,27,248,22,75,248,22,156,4,196,27,248,22,156,4,248,22,74,195,249,22, -149,4,80,158,40,36,28,248,22,81,195,250,22,84,2,22,9,248,22,75,199, -250,22,83,2,10,248,22,83,248,22,74,199,250,22,84,2,9,248,22,75,201, -248,22,75,202,27,248,22,75,248,22,156,4,23,197,1,27,249,22,1,22,87, -249,22,2,22,156,4,248,22,156,4,248,22,74,199,248,22,176,4,249,22,149, -4,80,158,41,36,251,22,83,1,22,119,105,116,104,45,99,111,110,116,105,110, -117,97,116,105,111,110,45,109,97,114,107,2,26,250,22,84,1,23,101,120,116, -101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,21, -95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109,97,114,107,45, -115,101,116,45,102,105,114,115,116,11,2,26,202,250,22,84,2,22,9,248,22, -75,204,27,248,22,75,248,22,156,4,196,28,248,22,81,193,20,14,159,37,36, -37,249,22,149,4,80,158,39,36,27,248,22,156,4,248,22,74,197,28,249,22, -140,9,62,61,62,248,22,150,4,248,22,98,196,250,22,83,2,22,248,22,83, -249,22,83,21,93,2,27,248,22,74,199,250,22,84,2,5,249,22,83,2,27, -249,22,83,248,22,107,203,2,27,248,22,75,202,251,22,83,2,18,28,249,22, -140,9,248,22,150,4,248,22,74,200,64,101,108,115,101,10,248,22,74,197,250, -22,84,2,22,9,248,22,75,200,249,22,73,2,5,248,22,75,202,99,13,16, -5,36,2,14,2,2,11,11,8,32,8,31,8,30,8,29,16,4,11,11,2, -20,3,1,8,101,110,118,49,53,48,52,50,16,4,11,11,2,21,3,1,8, -101,110,118,49,53,48,52,51,18,158,94,10,64,118,111,105,100,8,48,27,248, -22,75,248,22,156,4,196,249,22,149,4,80,158,39,36,28,248,22,58,248,22, -150,4,248,22,74,197,250,22,83,2,28,248,22,83,248,22,74,199,248,22,98, -198,27,248,22,150,4,248,22,74,197,250,22,83,2,28,248,22,83,248,22,74, -197,250,22,84,2,25,248,22,75,199,248,22,75,202,159,36,20,113,159,36,16, -1,11,16,0,20,26,146,2,1,2,1,2,2,11,11,11,10,36,80,158,36, -36,20,113,159,36,16,0,16,0,38,39,36,16,0,36,16,0,36,11,11,11, -16,10,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2,11,2, -12,16,10,11,11,11,11,11,11,11,11,11,11,16,10,2,3,2,4,2,5, -2,6,2,7,2,8,2,9,2,10,2,11,2,12,36,46,37,16,0,36,16, -1,2,13,37,11,11,11,16,0,16,0,16,0,36,36,11,12,11,11,16,0, -16,0,16,0,36,36,16,11,16,5,11,20,15,16,2,20,14,159,36,36,37, -80,158,36,36,36,20,113,159,36,16,1,2,13,16,1,33,33,10,16,5,2, -12,88,163,8,36,37,53,37,9,223,0,33,34,36,20,113,159,36,16,1,2, -13,16,0,11,16,5,2,3,88,163,8,36,37,53,37,9,223,0,33,35,36, -20,113,159,36,16,1,2,13,16,0,11,16,5,2,11,88,163,8,36,37,53, -37,9,223,0,33,36,36,20,113,159,36,16,1,2,13,16,1,33,37,11,16, -5,2,6,88,163,8,36,37,56,37,9,223,0,33,38,36,20,113,159,36,16, -1,2,13,16,1,33,39,11,16,5,2,10,88,163,8,36,37,58,37,9,223, -0,33,42,36,20,113,159,36,16,1,2,13,16,0,11,16,5,2,8,88,163, -8,36,37,53,37,9,223,0,33,44,36,20,113,159,36,16,1,2,13,16,0, -11,16,5,2,9,88,163,8,36,37,54,37,9,223,0,33,45,36,20,113,159, -36,16,1,2,13,16,0,11,16,5,2,7,88,163,8,36,37,56,37,9,223, -0,33,46,36,20,113,159,36,16,1,2,13,16,0,11,16,5,2,5,88,163, -8,36,37,58,37,9,223,0,33,47,36,20,113,159,36,16,1,2,13,16,1, -33,49,11,16,5,2,4,88,163,8,36,37,54,37,9,223,0,33,50,36,20, -113,159,36,16,1,2,13,16,0,11,16,0,94,2,16,2,17,93,2,16,9, -9,36,0}; - EVAL_ONE_SIZED_STR((char *)expr, 2018); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,53,46,50,46,48,46,57,48,49,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,51,0,0,0,1,0,0,10,0,13, +0,20,0,25,0,29,0,32,0,37,0,50,0,57,0,61,0,66,0,73,0, +82,0,85,0,91,0,105,0,119,0,122,0,128,0,132,0,134,0,145,0,147, +0,161,0,168,0,190,0,192,0,206,0,17,1,46,1,57,1,68,1,93,1, +126,1,159,1,218,1,17,2,95,2,150,2,155,2,175,2,68,3,88,3,140, +3,206,3,95,4,237,4,34,5,45,5,124,5,0,0,83,7,0,0,69,35, +37,109,105,110,45,115,116,120,29,11,11,66,108,101,116,114,101,99,64,108,101, +116,42,63,97,110,100,62,111,114,64,119,104,101,110,72,112,97,114,97,109,101, +116,101,114,105,122,101,66,100,101,102,105,110,101,63,108,101,116,64,99,111,110, +100,66,117,110,108,101,115,115,68,104,101,114,101,45,115,116,120,29,11,11,65, +113,117,111,116,101,29,94,2,15,68,35,37,107,101,114,110,101,108,11,29,94, +2,15,68,35,37,112,97,114,97,109,122,11,62,105,102,65,98,101,103,105,110, +63,115,116,120,61,115,70,108,101,116,45,118,97,108,117,101,115,61,120,73,108, +101,116,114,101,99,45,118,97,108,117,101,115,66,108,97,109,98,100,97,1,20, +112,97,114,97,109,101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,61, +118,73,100,101,102,105,110,101,45,118,97,108,117,101,115,97,36,11,8,240,73, +77,0,0,95,159,2,17,36,36,159,2,16,36,36,159,2,16,36,36,16,20, +2,3,2,2,2,4,2,2,2,5,2,2,2,6,2,2,2,7,2,2,2, +8,2,2,2,9,2,2,2,10,2,2,2,11,2,2,2,12,2,2,97,37, +11,8,240,73,77,0,0,93,159,2,16,36,37,16,2,2,13,161,2,2,37, +2,13,2,2,2,13,96,38,11,8,240,73,77,0,0,16,0,96,11,11,8, +240,73,77,0,0,16,0,18,98,64,104,101,114,101,13,16,5,36,2,14,2, +2,11,11,8,32,8,31,8,30,8,29,27,248,22,156,4,195,249,22,149,4, +80,158,39,36,251,22,83,2,18,248,22,98,199,12,249,22,73,2,19,248,22, +100,201,27,248,22,156,4,195,249,22,149,4,80,158,39,36,251,22,83,2,18, +248,22,98,199,249,22,73,2,19,248,22,100,201,12,27,248,22,75,248,22,156, +4,196,28,248,22,81,193,20,14,159,37,36,37,28,248,22,81,248,22,75,194, +248,22,74,193,249,22,149,4,80,158,39,36,251,22,83,2,18,248,22,74,199, +249,22,73,2,5,248,22,75,201,11,18,100,10,13,16,5,36,2,14,2,2, +11,11,8,32,8,31,8,30,8,29,16,4,11,11,2,20,3,1,8,101,110, +118,49,53,49,56,51,16,4,11,11,2,21,3,1,8,101,110,118,49,53,49, +56,52,27,248,22,75,248,22,156,4,196,28,248,22,81,193,20,14,159,37,36, +37,28,248,22,81,248,22,75,194,248,22,74,193,249,22,149,4,80,158,39,36, +250,22,83,2,22,248,22,83,249,22,83,248,22,83,2,23,248,22,74,201,251, +22,83,2,18,2,23,2,23,249,22,73,2,6,248,22,75,204,18,100,11,13, +16,5,36,2,14,2,2,11,11,8,32,8,31,8,30,8,29,16,4,11,11, +2,20,3,1,8,101,110,118,49,53,49,56,54,16,4,11,11,2,21,3,1, +8,101,110,118,49,53,49,56,55,248,22,156,4,193,27,248,22,156,4,194,249, +22,73,248,22,83,248,22,74,196,248,22,75,195,27,248,22,75,248,22,156,4, +23,197,1,249,22,149,4,80,158,39,36,28,248,22,58,248,22,150,4,248,22, +74,23,198,2,27,249,22,2,32,0,88,163,8,36,37,43,11,9,222,33,40, +248,22,156,4,248,22,98,23,200,2,250,22,83,2,24,248,22,83,249,22,83, +248,22,83,248,22,74,23,204,2,250,22,84,2,25,249,22,2,22,74,23,204, +2,248,22,100,23,206,2,249,22,73,248,22,74,23,202,1,249,22,2,22,98, +23,200,1,250,22,84,2,22,249,22,2,32,0,88,163,8,36,37,47,11,9, +222,33,41,248,22,156,4,248,22,74,201,248,22,75,198,27,248,22,156,4,194, +249,22,73,248,22,83,248,22,74,196,248,22,75,195,27,248,22,75,248,22,156, +4,23,197,1,249,22,149,4,80,158,39,36,250,22,84,2,24,249,22,2,32, +0,88,163,8,36,37,47,11,9,222,33,43,248,22,156,4,248,22,74,201,248, +22,75,198,27,248,22,75,248,22,156,4,196,27,248,22,156,4,248,22,74,195, +249,22,149,4,80,158,40,36,28,248,22,81,195,250,22,84,2,22,9,248,22, +75,199,250,22,83,2,10,248,22,83,248,22,74,199,250,22,84,2,4,248,22, +75,201,248,22,75,202,27,248,22,75,248,22,156,4,23,197,1,27,249,22,1, +22,87,249,22,2,22,156,4,248,22,156,4,248,22,74,199,248,22,176,4,249, +22,149,4,80,158,41,36,251,22,83,1,22,119,105,116,104,45,99,111,110,116, +105,110,117,97,116,105,111,110,45,109,97,114,107,2,26,250,22,84,1,23,101, +120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116,105,111, +110,21,95,1,27,99,111,110,116,105,110,117,97,116,105,111,110,45,109,97,114, +107,45,115,101,116,45,102,105,114,115,116,11,2,26,202,250,22,84,2,22,9, +248,22,75,204,27,248,22,75,248,22,156,4,196,28,248,22,81,193,20,14,159, +37,36,37,249,22,149,4,80,158,39,36,27,248,22,156,4,248,22,74,197,28, +249,22,140,9,62,61,62,248,22,150,4,248,22,98,196,250,22,83,2,22,248, +22,83,249,22,83,21,93,2,27,248,22,74,199,250,22,84,2,11,249,22,83, +2,27,249,22,83,248,22,107,203,2,27,248,22,75,202,251,22,83,2,18,28, +249,22,140,9,248,22,150,4,248,22,74,200,64,101,108,115,101,10,248,22,74, +197,250,22,84,2,22,9,248,22,75,200,249,22,73,2,11,248,22,75,202,99, +13,16,5,36,2,14,2,2,11,11,8,32,8,31,8,30,8,29,16,4,11, +11,2,20,3,1,8,101,110,118,49,53,50,48,57,16,4,11,11,2,21,3, +1,8,101,110,118,49,53,50,49,48,18,158,94,10,64,118,111,105,100,8,48, +27,248,22,75,248,22,156,4,196,249,22,149,4,80,158,39,36,28,248,22,58, +248,22,150,4,248,22,74,197,250,22,83,2,28,248,22,83,248,22,74,199,248, +22,98,198,27,248,22,150,4,248,22,74,197,250,22,83,2,28,248,22,83,248, +22,74,197,250,22,84,2,25,248,22,75,199,248,22,75,202,159,36,20,113,159, +36,16,1,11,16,0,20,26,146,2,1,2,1,2,2,11,11,11,10,36,80, +158,36,36,20,113,159,36,16,0,16,0,38,39,36,16,0,36,16,0,36,11, +11,11,16,10,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,10,2, +11,2,12,16,10,11,11,11,11,11,11,11,11,11,11,16,10,2,3,2,4, +2,5,2,6,2,7,2,8,2,9,2,10,2,11,2,12,36,46,37,16,0, +36,16,1,2,13,37,11,11,11,16,0,16,0,16,0,36,36,11,12,11,11, +16,0,16,0,16,0,36,36,16,11,16,5,11,20,15,16,2,20,14,159,36, +36,37,80,158,36,36,36,20,113,159,36,16,1,2,13,16,1,33,33,10,16, +5,2,12,88,163,8,36,37,53,37,9,223,0,33,34,36,20,113,159,36,16, +1,2,13,16,0,11,16,5,2,7,88,163,8,36,37,53,37,9,223,0,33, +35,36,20,113,159,36,16,1,2,13,16,0,11,16,5,2,5,88,163,8,36, +37,53,37,9,223,0,33,36,36,20,113,159,36,16,1,2,13,16,1,33,37, +11,16,5,2,6,88,163,8,36,37,56,37,9,223,0,33,38,36,20,113,159, +36,16,1,2,13,16,1,33,39,11,16,5,2,10,88,163,8,36,37,58,37, +9,223,0,33,42,36,20,113,159,36,16,1,2,13,16,0,11,16,5,2,3, +88,163,8,36,37,53,37,9,223,0,33,44,36,20,113,159,36,16,1,2,13, +16,0,11,16,5,2,4,88,163,8,36,37,54,37,9,223,0,33,45,36,20, +113,159,36,16,1,2,13,16,0,11,16,5,2,8,88,163,8,36,37,56,37, +9,223,0,33,46,36,20,113,159,36,16,1,2,13,16,0,11,16,5,2,11, +88,163,8,36,37,58,37,9,223,0,33,47,36,20,113,159,36,16,1,2,13, +16,1,33,49,11,16,5,2,9,88,163,8,36,37,54,37,9,223,0,33,50, +36,20,113,159,36,16,1,2,13,16,0,11,16,0,94,2,16,2,17,93,2, +16,9,9,36,0}; + EVAL_ONE_SIZED_STR((char *)expr, 2020); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,50,46,48,46,54,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,108,0,0,0,1,0,0,8,0,21,0,26, -0,43,0,65,0,94,0,109,0,127,0,143,0,157,0,179,0,195,0,212,0, -234,0,245,0,251,0,4,1,11,1,18,1,30,1,46,1,70,1,102,1,120, -1,140,1,156,1,174,1,205,1,219,1,224,1,234,1,23,2,31,2,40,2, -42,2,70,2,102,2,115,2,121,2,166,2,169,2,173,2,197,2,236,2,250, -2,4,3,15,3,182,3,26,5,144,5,6,6,47,6,77,7,100,7,117,7, -65,9,168,9,182,9,86,10,15,12,24,12,33,12,47,12,57,12,98,13,200, -13,30,14,116,14,216,14,44,15,58,15,172,15,0,16,14,16,223,16,231,16, -81,17,144,17,146,17,2,18,62,18,67,18,190,18,201,18,81,19,91,19,14, -21,36,21,45,21,38,22,56,22,70,22,29,23,48,23,242,25,102,30,16,31, -161,31,146,32,128,33,135,33,142,33,223,33,50,34,135,34,161,34,34,35,0, -0,148,39,0,0,67,35,37,117,116,105,108,115,72,112,97,116,104,45,115,116, -114,105,110,103,63,64,98,115,98,115,76,110,111,114,109,97,108,45,99,97,115, -101,45,112,97,116,104,1,20,102,105,110,100,45,101,120,101,99,117,116,97,98, -108,101,45,112,97,116,104,1,27,112,97,116,104,45,108,105,115,116,45,115,116, -114,105,110,103,45,62,112,97,116,104,45,108,105,115,116,74,45,99,104,101,99, -107,45,114,101,108,112,97,116,104,77,45,99,104,101,99,107,45,99,111,108,108, -101,99,116,105,111,110,75,99,111,108,108,101,99,116,105,111,110,45,112,97,116, -104,73,102,105,110,100,45,99,111,108,45,102,105,108,101,1,20,99,111,108,108, -101,99,116,105,111,110,45,102,105,108,101,45,112,97,116,104,75,117,115,101,114, -45,108,105,110,107,115,45,112,97,116,104,76,117,115,101,114,45,108,105,110,107, -115,45,99,97,99,104,101,1,20,117,115,101,114,45,108,105,110,107,115,45,116, -105,109,101,115,116,97,109,112,70,108,105,110,107,115,45,112,97,116,104,65,113, -117,111,116,101,68,35,37,112,97,114,97,109,122,29,94,2,16,2,17,11,29, -94,2,16,2,17,11,71,108,105,110,107,115,45,99,97,99,104,101,75,108,105, -110,107,115,45,116,105,109,101,115,116,97,109,112,1,22,103,101,116,45,108,105, -110,107,101,100,45,99,111,108,108,101,99,116,105,111,110,115,1,30,110,111,114, -109,97,108,105,122,101,45,99,111,108,108,101,99,116,105,111,110,45,114,101,102, -101,114,101,110,99,101,77,99,104,101,99,107,45,115,117,102,102,105,120,45,99, -97,108,108,79,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102,102, -105,120,75,112,97,116,104,45,97,100,100,45,115,117,102,102,105,120,77,108,111, -97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,1,29,102,105,110,100, -45,108,105,98,114,97,114,121,45,99,111,108,108,101,99,116,105,111,110,45,112, -97,116,104,115,73,101,109,98,101,100,100,101,100,45,108,111,97,100,64,108,111, -111,112,69,101,120,101,99,45,102,105,108,101,6,42,42,112,97,116,104,32,40, -102,111,114,32,97,110,121,32,115,121,115,116,101,109,41,32,111,114,32,118,97, -108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,67,119,105,110,100,111, -119,115,68,114,101,108,97,116,105,118,101,5,0,6,25,25,112,97,116,104,32, -111,114,32,118,97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,6, -29,29,126,97,58,32,105,110,118,97,108,105,100,32,114,101,108,97,116,105,118, -101,32,112,97,116,104,58,32,126,115,72,99,111,108,108,101,99,116,115,45,100, -105,114,65,101,114,114,111,114,6,42,42,101,114,114,111,114,32,114,101,97,100, -105,110,103,32,99,111,108,108,101,99,116,105,111,110,32,108,105,110,107,115,32, -102,105,108,101,32,126,115,58,32,126,97,6,0,0,6,1,1,47,6,21,21, -115,116,114,105,110,103,32,111,114,32,98,121,116,101,32,115,116,114,105,110,103, -6,36,36,99,97,110,110,111,116,32,97,100,100,32,97,32,115,117,102,102,105, -120,32,116,111,32,97,32,114,111,111,116,32,112,97,116,104,58,32,6,11,11, -80,76,84,67,79,76,76,69,67,84,83,69,97,100,100,111,110,45,100,105,114, -6,8,8,99,111,108,108,101,99,116,115,27,20,13,159,80,159,37,51,37,250, -80,159,40,52,37,249,22,27,11,80,159,42,51,37,22,130,14,10,248,22,129, -6,23,196,2,28,248,22,189,6,23,194,2,12,86,94,248,22,148,9,23,194, -1,27,20,13,159,80,159,38,51,37,250,80,159,41,52,37,249,22,27,11,80, -159,43,51,37,22,130,14,10,248,22,129,6,23,197,2,28,248,22,189,6,23, -194,2,12,86,94,248,22,148,9,23,194,1,27,20,13,159,80,159,39,51,37, -250,80,159,42,52,37,249,22,27,11,80,159,44,51,37,22,130,14,10,248,22, -129,6,23,198,2,28,248,22,189,6,23,194,2,12,86,94,248,22,148,9,23, -194,1,248,80,159,40,8,31,39,197,28,248,22,81,23,195,2,9,27,248,22, -74,23,196,2,27,28,248,22,180,14,23,195,2,23,194,1,28,248,22,179,14, -23,195,2,249,22,181,14,23,196,1,250,80,159,43,39,39,248,22,132,15,2, -31,11,10,250,80,159,41,39,39,248,22,132,15,2,31,23,197,1,10,28,23, -193,2,249,22,73,248,22,183,14,249,22,181,14,23,198,1,247,22,133,15,27, -248,22,75,23,200,1,28,248,22,81,23,194,2,9,27,248,22,74,23,195,2, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,53,46,50,46,48,46,57,48,49,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,109,0,0,0,1,0,0,8,0,21, +0,26,0,43,0,65,0,94,0,109,0,127,0,139,0,155,0,169,0,191,0, +207,0,224,0,246,0,1,1,7,1,16,1,23,1,30,1,42,1,58,1,82, +1,114,1,132,1,152,1,168,1,186,1,217,1,231,1,236,1,246,1,35,2, +43,2,52,2,54,2,82,2,114,2,136,2,149,2,155,2,200,2,203,2,207, +2,231,2,14,3,28,3,38,3,49,3,216,3,60,5,178,5,40,6,81,6, +111,7,134,7,151,7,99,9,202,9,216,9,120,10,49,12,58,12,67,12,81, +12,91,12,132,13,234,13,64,14,150,14,250,14,15,15,99,15,221,15,49,16, +241,16,249,16,99,17,162,17,164,17,20,18,80,18,85,18,208,18,219,18,99, +19,109,19,35,21,57,21,66,21,59,22,77,22,91,22,50,23,69,23,7,26, +121,30,32,31,177,31,162,32,144,33,151,33,158,33,239,33,66,34,151,34,177, +34,50,35,0,0,186,39,0,0,67,35,37,117,116,105,108,115,72,112,97,116, +104,45,115,116,114,105,110,103,63,64,98,115,98,115,76,110,111,114,109,97,108, +45,99,97,115,101,45,112,97,116,104,1,20,102,105,110,100,45,101,120,101,99, +117,116,97,98,108,101,45,112,97,116,104,1,27,112,97,116,104,45,108,105,115, +116,45,115,116,114,105,110,103,45,62,112,97,116,104,45,108,105,115,116,74,45, +99,104,101,99,107,45,114,101,108,112,97,116,104,77,45,99,104,101,99,107,45, +99,111,108,108,101,99,116,105,111,110,71,45,99,104,101,99,107,45,102,97,105, +108,75,99,111,108,108,101,99,116,105,111,110,45,112,97,116,104,73,102,105,110, +100,45,99,111,108,45,102,105,108,101,1,20,99,111,108,108,101,99,116,105,111, +110,45,102,105,108,101,45,112,97,116,104,75,117,115,101,114,45,108,105,110,107, +115,45,112,97,116,104,76,117,115,101,114,45,108,105,110,107,115,45,99,97,99, +104,101,1,20,117,115,101,114,45,108,105,110,107,115,45,116,105,109,101,115,116, +97,109,112,70,108,105,110,107,115,45,112,97,116,104,65,113,117,111,116,101,68, +35,37,112,97,114,97,109,122,29,94,2,17,2,18,11,29,94,2,17,2,18, +11,71,108,105,110,107,115,45,99,97,99,104,101,75,108,105,110,107,115,45,116, +105,109,101,115,116,97,109,112,1,22,103,101,116,45,108,105,110,107,101,100,45, +99,111,108,108,101,99,116,105,111,110,115,1,30,110,111,114,109,97,108,105,122, +101,45,99,111,108,108,101,99,116,105,111,110,45,114,101,102,101,114,101,110,99, +101,77,99,104,101,99,107,45,115,117,102,102,105,120,45,99,97,108,108,79,112, +97,116,104,45,114,101,112,108,97,99,101,45,115,117,102,102,105,120,75,112,97, +116,104,45,97,100,100,45,115,117,102,102,105,120,77,108,111,97,100,47,117,115, +101,45,99,111,109,112,105,108,101,100,1,29,102,105,110,100,45,108,105,98,114, +97,114,121,45,99,111,108,108,101,99,116,105,111,110,45,112,97,116,104,115,73, +101,109,98,101,100,100,101,100,45,108,111,97,100,64,108,111,111,112,69,101,120, +101,99,45,102,105,108,101,6,42,42,112,97,116,104,32,40,102,111,114,32,97, +110,121,32,115,121,115,116,101,109,41,32,111,114,32,118,97,108,105,100,45,112, +97,116,104,32,115,116,114,105,110,103,67,119,105,110,100,111,119,115,68,114,101, +108,97,116,105,118,101,5,0,6,25,25,112,97,116,104,32,111,114,32,118,97, +108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,6,29,29,126,97,58, +32,105,110,118,97,108,105,100,32,114,101,108,97,116,105,118,101,32,112,97,116, +104,58,32,126,115,6,19,19,112,114,111,99,101,100,117,114,101,32,40,97,114, +105,116,121,32,49,41,72,99,111,108,108,101,99,116,115,45,100,105,114,65,101, +114,114,111,114,6,42,42,101,114,114,111,114,32,114,101,97,100,105,110,103,32, +99,111,108,108,101,99,116,105,111,110,32,108,105,110,107,115,32,102,105,108,101, +32,126,115,58,32,126,97,6,0,0,6,1,1,47,6,21,21,115,116,114,105, +110,103,32,111,114,32,98,121,116,101,32,115,116,114,105,110,103,6,36,36,99, +97,110,110,111,116,32,97,100,100,32,97,32,115,117,102,102,105,120,32,116,111, +32,97,32,114,111,111,116,32,112,97,116,104,58,32,6,11,11,80,76,84,67, +79,76,76,69,67,84,83,69,97,100,100,111,110,45,100,105,114,6,8,8,99, +111,108,108,101,99,116,115,27,20,13,159,80,159,37,52,37,250,80,159,40,53, +37,249,22,27,11,80,159,42,52,37,22,130,14,10,248,22,129,6,23,196,2, +28,248,22,189,6,23,194,2,12,86,94,248,22,148,9,23,194,1,27,20,13, +159,80,159,38,52,37,250,80,159,41,53,37,249,22,27,11,80,159,43,52,37, +22,130,14,10,248,22,129,6,23,197,2,28,248,22,189,6,23,194,2,12,86, +94,248,22,148,9,23,194,1,27,20,13,159,80,159,39,52,37,250,80,159,42, +53,37,249,22,27,11,80,159,44,52,37,22,130,14,10,248,22,129,6,23,198, +2,28,248,22,189,6,23,194,2,12,86,94,248,22,148,9,23,194,1,248,80, +159,40,8,32,39,197,28,248,22,81,23,195,2,9,27,248,22,74,23,196,2, 27,28,248,22,180,14,23,195,2,23,194,1,28,248,22,179,14,23,195,2,249, -22,181,14,23,196,1,250,80,159,48,39,39,248,22,132,15,2,31,11,10,250, -80,159,46,39,39,248,22,132,15,2,31,23,197,1,10,28,23,193,2,249,22, -73,248,22,183,14,249,22,181,14,23,198,1,247,22,133,15,248,80,159,46,8, -30,39,248,22,75,23,199,1,86,94,23,193,1,248,80,159,44,8,30,39,248, -22,75,23,197,1,86,94,23,193,1,27,248,22,75,23,198,1,28,248,22,81, -23,194,2,9,27,248,22,74,23,195,2,27,28,248,22,180,14,23,195,2,23, -194,1,28,248,22,179,14,23,195,2,249,22,181,14,23,196,1,250,80,159,46, -39,39,248,22,132,15,2,31,11,10,250,80,159,44,39,39,248,22,132,15,2, -31,23,197,1,10,28,23,193,2,249,22,73,248,22,183,14,249,22,181,14,23, -198,1,247,22,133,15,248,80,159,44,8,30,39,248,22,75,23,199,1,248,80, -159,42,8,30,39,248,22,75,196,28,248,22,81,23,195,2,9,27,248,22,74, -23,196,2,27,28,248,22,180,14,23,195,2,23,194,1,28,248,22,179,14,23, -195,2,249,22,181,14,23,196,1,250,80,159,43,39,39,248,22,132,15,2,31, -11,10,250,80,159,41,39,39,248,22,132,15,2,31,23,197,1,10,28,23,193, -2,249,22,73,248,22,183,14,249,22,181,14,23,198,1,247,22,133,15,248,80, -159,41,8,29,39,248,22,75,23,200,1,248,80,159,39,8,29,39,248,22,75, -197,28,248,22,81,23,195,2,9,27,248,22,74,23,196,2,27,28,248,22,180, -14,23,195,2,23,194,1,28,248,22,179,14,23,195,2,249,22,181,14,23,196, -1,250,80,159,43,39,39,248,22,132,15,2,31,11,10,250,80,159,41,39,39, -248,22,132,15,2,31,23,197,1,10,28,23,193,2,249,22,73,248,22,183,14, -249,22,181,14,23,198,1,247,22,133,15,248,80,159,41,8,28,39,248,22,75, -23,200,1,248,80,159,39,8,28,39,248,22,75,197,27,248,22,156,14,23,195, -2,28,23,193,2,192,86,94,23,193,1,28,248,22,130,7,23,195,2,27,248, -22,178,14,195,28,192,192,248,22,179,14,195,11,86,94,28,28,248,22,157,14, -23,195,2,10,28,248,22,156,14,23,195,2,10,28,248,22,130,7,23,195,2, +22,181,14,23,196,1,250,80,159,43,39,39,248,22,132,15,2,32,11,10,250, +80,159,41,39,39,248,22,132,15,2,32,23,197,1,10,28,23,193,2,249,22, +73,248,22,183,14,249,22,181,14,23,198,1,247,22,133,15,27,248,22,75,23, +200,1,28,248,22,81,23,194,2,9,27,248,22,74,23,195,2,27,28,248,22, +180,14,23,195,2,23,194,1,28,248,22,179,14,23,195,2,249,22,181,14,23, +196,1,250,80,159,48,39,39,248,22,132,15,2,32,11,10,250,80,159,46,39, +39,248,22,132,15,2,32,23,197,1,10,28,23,193,2,249,22,73,248,22,183, +14,249,22,181,14,23,198,1,247,22,133,15,248,80,159,46,8,31,39,248,22, +75,23,199,1,86,94,23,193,1,248,80,159,44,8,31,39,248,22,75,23,197, +1,86,94,23,193,1,27,248,22,75,23,198,1,28,248,22,81,23,194,2,9, +27,248,22,74,23,195,2,27,28,248,22,180,14,23,195,2,23,194,1,28,248, +22,179,14,23,195,2,249,22,181,14,23,196,1,250,80,159,46,39,39,248,22, +132,15,2,32,11,10,250,80,159,44,39,39,248,22,132,15,2,32,23,197,1, +10,28,23,193,2,249,22,73,248,22,183,14,249,22,181,14,23,198,1,247,22, +133,15,248,80,159,44,8,31,39,248,22,75,23,199,1,248,80,159,42,8,31, +39,248,22,75,196,28,248,22,81,23,195,2,9,27,248,22,74,23,196,2,27, +28,248,22,180,14,23,195,2,23,194,1,28,248,22,179,14,23,195,2,249,22, +181,14,23,196,1,250,80,159,43,39,39,248,22,132,15,2,32,11,10,250,80, +159,41,39,39,248,22,132,15,2,32,23,197,1,10,28,23,193,2,249,22,73, +248,22,183,14,249,22,181,14,23,198,1,247,22,133,15,248,80,159,41,8,30, +39,248,22,75,23,200,1,248,80,159,39,8,30,39,248,22,75,197,28,248,22, +81,23,195,2,9,27,248,22,74,23,196,2,27,28,248,22,180,14,23,195,2, +23,194,1,28,248,22,179,14,23,195,2,249,22,181,14,23,196,1,250,80,159, +43,39,39,248,22,132,15,2,32,11,10,250,80,159,41,39,39,248,22,132,15, +2,32,23,197,1,10,28,23,193,2,249,22,73,248,22,183,14,249,22,181,14, +23,198,1,247,22,133,15,248,80,159,41,8,29,39,248,22,75,23,200,1,248, +80,159,39,8,29,39,248,22,75,197,27,248,22,156,14,23,195,2,28,23,193, +2,192,86,94,23,193,1,28,248,22,130,7,23,195,2,27,248,22,178,14,195, +28,192,192,248,22,179,14,195,11,86,94,28,28,248,22,157,14,23,195,2,10, +28,248,22,156,14,23,195,2,10,28,248,22,130,7,23,195,2,28,248,22,178, +14,23,195,2,10,248,22,179,14,23,195,2,11,12,250,22,176,9,76,110,111, +114,109,97,108,45,112,97,116,104,45,99,97,115,101,2,33,23,197,2,28,28, +248,22,157,14,23,195,2,249,22,140,9,248,22,158,14,23,197,2,2,34,249, +22,140,9,247,22,152,8,2,34,27,28,248,22,130,7,23,196,2,23,195,2, +248,22,142,8,248,22,161,14,23,197,2,28,249,22,148,15,0,21,35,114,120, +34,94,91,92,92,93,91,92,92,93,91,63,93,91,92,92,93,34,23,195,2, +28,248,22,130,7,195,248,22,164,14,195,194,27,248,22,169,7,23,195,1,249, +22,165,14,248,22,145,8,250,22,156,15,0,6,35,114,120,34,47,34,28,249, +22,148,15,0,22,35,114,120,34,91,47,92,92,93,91,46,32,93,43,91,47, +92,92,93,42,36,34,23,201,2,23,199,1,250,22,156,15,0,19,35,114,120, +34,91,32,46,93,43,40,91,47,92,92,93,42,41,36,34,23,202,1,6,2, +2,92,49,80,159,44,37,38,2,34,28,248,22,130,7,194,248,22,164,14,194, +193,32,56,88,163,8,36,39,53,11,70,102,111,117,110,100,45,101,120,101,99, +222,33,59,32,57,88,163,8,36,40,58,11,64,110,101,120,116,222,33,58,27, +248,22,182,14,23,196,2,28,249,22,142,9,23,195,2,23,197,1,11,28,248, +22,178,14,23,194,2,27,249,22,174,14,23,197,1,23,196,1,28,23,197,2, +90,159,39,11,89,161,39,36,11,248,22,177,14,23,197,2,86,95,23,195,1, +23,194,1,27,28,23,202,2,27,248,22,182,14,23,199,2,28,249,22,142,9, +23,195,2,23,200,2,11,28,248,22,178,14,23,194,2,250,2,56,23,205,2, +23,206,2,249,22,174,14,23,200,2,23,198,1,250,2,56,23,205,2,23,206, +2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,156,14, +23,196,2,27,249,22,174,14,23,198,2,23,205,2,28,28,248,22,169,14,193, +10,248,22,168,14,193,192,11,11,28,23,193,2,192,86,94,23,193,1,28,23, +203,2,11,27,248,22,182,14,23,200,2,28,249,22,142,9,23,195,2,23,201, +1,11,28,248,22,178,14,23,194,2,250,2,56,23,206,1,23,207,1,249,22, +174,14,23,201,1,23,198,1,250,2,56,205,206,195,192,86,94,23,194,1,28, +23,196,2,90,159,39,11,89,161,39,36,11,248,22,177,14,23,197,2,86,95, +23,195,1,23,194,1,27,28,23,201,2,27,248,22,182,14,23,199,2,28,249, +22,142,9,23,195,2,23,200,2,11,28,248,22,178,14,23,194,2,250,2,56, +23,204,2,23,205,2,249,22,174,14,23,200,2,23,198,1,250,2,56,23,204, +2,23,205,2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28,248, +22,156,14,23,196,2,27,249,22,174,14,23,198,2,23,204,2,28,28,248,22, +169,14,193,10,248,22,168,14,193,192,11,11,28,23,193,2,192,86,94,23,193, +1,28,23,202,2,11,27,248,22,182,14,23,200,2,28,249,22,142,9,23,195, +2,23,201,1,11,28,248,22,178,14,23,194,2,250,2,56,23,205,1,23,206, +1,249,22,174,14,23,201,1,23,198,1,250,2,56,204,205,195,192,28,23,193, +2,90,159,39,11,89,161,39,36,11,248,22,177,14,23,199,2,86,95,23,195, +1,23,194,1,27,28,23,198,2,251,2,57,23,198,2,23,203,2,23,201,2, +23,202,2,11,28,23,193,2,192,86,94,23,193,1,27,28,248,22,156,14,195, +27,249,22,174,14,197,200,28,28,248,22,169,14,193,10,248,22,168,14,193,192, +11,11,28,192,192,28,198,11,251,2,57,198,203,201,202,194,32,60,88,163,8, +36,40,58,11,2,31,222,33,61,28,248,22,81,23,197,2,11,27,248,22,181, +14,248,22,74,23,199,2,27,249,22,174,14,23,196,1,23,197,2,28,248,22, +168,14,23,194,2,250,2,56,198,199,195,86,94,23,193,1,27,248,22,75,23, +200,1,28,248,22,81,23,194,2,11,27,248,22,181,14,248,22,74,23,196,2, +27,249,22,174,14,23,196,1,23,200,2,28,248,22,168,14,23,194,2,250,2, +56,201,202,195,86,94,23,193,1,27,248,22,75,23,197,1,28,248,22,81,23, +194,2,11,27,248,22,181,14,248,22,74,195,27,249,22,174,14,23,196,1,202, +28,248,22,168,14,193,250,2,56,204,205,195,251,2,60,204,205,206,248,22,75, +199,86,95,28,28,248,22,156,14,23,195,2,10,28,248,22,130,7,23,195,2, 28,248,22,178,14,23,195,2,10,248,22,179,14,23,195,2,11,12,250,22,176, -9,76,110,111,114,109,97,108,45,112,97,116,104,45,99,97,115,101,2,32,23, -197,2,28,28,248,22,157,14,23,195,2,249,22,140,9,248,22,158,14,23,197, -2,2,33,249,22,140,9,247,22,152,8,2,33,27,28,248,22,130,7,23,196, -2,23,195,2,248,22,142,8,248,22,161,14,23,197,2,28,249,22,148,15,0, -21,35,114,120,34,94,91,92,92,93,91,92,92,93,91,63,93,91,92,92,93, -34,23,195,2,28,248,22,130,7,195,248,22,164,14,195,194,27,248,22,169,7, -23,195,1,249,22,165,14,248,22,145,8,250,22,156,15,0,6,35,114,120,34, -47,34,28,249,22,148,15,0,22,35,114,120,34,91,47,92,92,93,91,46,32, -93,43,91,47,92,92,93,42,36,34,23,201,2,23,199,1,250,22,156,15,0, -19,35,114,120,34,91,32,46,93,43,40,91,47,92,92,93,42,41,36,34,23, -202,1,6,2,2,92,49,80,159,44,37,38,2,33,28,248,22,130,7,194,248, -22,164,14,194,193,32,54,88,163,8,36,39,53,11,70,102,111,117,110,100,45, -101,120,101,99,222,33,57,32,55,88,163,8,36,40,58,11,64,110,101,120,116, -222,33,56,27,248,22,182,14,23,196,2,28,249,22,142,9,23,195,2,23,197, -1,11,28,248,22,178,14,23,194,2,27,249,22,174,14,23,197,1,23,196,1, -28,23,197,2,90,159,39,11,89,161,39,36,11,248,22,177,14,23,197,2,86, -95,23,195,1,23,194,1,27,28,23,202,2,27,248,22,182,14,23,199,2,28, -249,22,142,9,23,195,2,23,200,2,11,28,248,22,178,14,23,194,2,250,2, -54,23,205,2,23,206,2,249,22,174,14,23,200,2,23,198,1,250,2,54,23, -205,2,23,206,2,23,196,1,11,28,23,193,2,192,86,94,23,193,1,27,28, -248,22,156,14,23,196,2,27,249,22,174,14,23,198,2,23,205,2,28,28,248, -22,169,14,193,10,248,22,168,14,193,192,11,11,28,23,193,2,192,86,94,23, -193,1,28,23,203,2,11,27,248,22,182,14,23,200,2,28,249,22,142,9,23, -195,2,23,201,1,11,28,248,22,178,14,23,194,2,250,2,54,23,206,1,23, -207,1,249,22,174,14,23,201,1,23,198,1,250,2,54,205,206,195,192,86,94, -23,194,1,28,23,196,2,90,159,39,11,89,161,39,36,11,248,22,177,14,23, -197,2,86,95,23,195,1,23,194,1,27,28,23,201,2,27,248,22,182,14,23, -199,2,28,249,22,142,9,23,195,2,23,200,2,11,28,248,22,178,14,23,194, -2,250,2,54,23,204,2,23,205,2,249,22,174,14,23,200,2,23,198,1,250, -2,54,23,204,2,23,205,2,23,196,1,11,28,23,193,2,192,86,94,23,193, -1,27,28,248,22,156,14,23,196,2,27,249,22,174,14,23,198,2,23,204,2, -28,28,248,22,169,14,193,10,248,22,168,14,193,192,11,11,28,23,193,2,192, -86,94,23,193,1,28,23,202,2,11,27,248,22,182,14,23,200,2,28,249,22, -142,9,23,195,2,23,201,1,11,28,248,22,178,14,23,194,2,250,2,54,23, -205,1,23,206,1,249,22,174,14,23,201,1,23,198,1,250,2,54,204,205,195, -192,28,23,193,2,90,159,39,11,89,161,39,36,11,248,22,177,14,23,199,2, -86,95,23,195,1,23,194,1,27,28,23,198,2,251,2,55,23,198,2,23,203, -2,23,201,2,23,202,2,11,28,23,193,2,192,86,94,23,193,1,27,28,248, -22,156,14,195,27,249,22,174,14,197,200,28,28,248,22,169,14,193,10,248,22, -168,14,193,192,11,11,28,192,192,28,198,11,251,2,55,198,203,201,202,194,32, -58,88,163,8,36,40,58,11,2,30,222,33,59,28,248,22,81,23,197,2,11, -27,248,22,181,14,248,22,74,23,199,2,27,249,22,174,14,23,196,1,23,197, -2,28,248,22,168,14,23,194,2,250,2,54,198,199,195,86,94,23,193,1,27, -248,22,75,23,200,1,28,248,22,81,23,194,2,11,27,248,22,181,14,248,22, -74,23,196,2,27,249,22,174,14,23,196,1,23,200,2,28,248,22,168,14,23, -194,2,250,2,54,201,202,195,86,94,23,193,1,27,248,22,75,23,197,1,28, -248,22,81,23,194,2,11,27,248,22,181,14,248,22,74,195,27,249,22,174,14, -23,196,1,202,28,248,22,168,14,193,250,2,54,204,205,195,251,2,58,204,205, -206,248,22,75,199,86,95,28,28,248,22,156,14,23,195,2,10,28,248,22,130, -7,23,195,2,28,248,22,178,14,23,195,2,10,248,22,179,14,23,195,2,11, -12,250,22,176,9,2,5,6,25,25,112,97,116,104,32,111,114,32,115,116,114, -105,110,103,32,40,115,97,110,115,32,110,117,108,41,23,197,2,28,28,23,195, -2,28,28,248,22,156,14,23,196,2,10,28,248,22,130,7,23,196,2,28,248, -22,178,14,23,196,2,10,248,22,179,14,23,196,2,11,248,22,178,14,23,196, -2,11,10,12,250,22,176,9,2,5,6,29,29,35,102,32,111,114,32,114,101, -108,97,116,105,118,101,32,112,97,116,104,32,111,114,32,115,116,114,105,110,103, -23,198,2,28,28,248,22,178,14,23,195,2,90,159,39,11,89,161,39,36,11, -248,22,177,14,23,198,2,249,22,140,9,194,2,34,11,27,248,22,150,8,6, -4,4,80,65,84,72,27,28,23,194,2,27,249,80,158,41,40,23,197,1,9, -28,249,22,140,9,247,22,152,8,2,33,249,22,73,248,22,165,14,5,1,46, -194,192,86,94,23,194,1,9,28,248,22,81,23,194,2,11,27,248,22,181,14, -248,22,74,23,196,2,27,249,22,174,14,23,196,1,23,200,2,28,248,22,168, -14,23,194,2,250,2,54,201,202,195,86,94,23,193,1,27,248,22,75,23,197, -1,28,248,22,81,23,194,2,11,27,248,22,181,14,248,22,74,23,196,2,27, -249,22,174,14,23,196,1,23,203,2,28,248,22,168,14,23,194,2,250,2,54, -204,205,195,86,94,23,193,1,27,248,22,75,23,197,1,28,248,22,81,23,194, -2,11,27,248,22,181,14,248,22,74,195,27,249,22,174,14,23,196,1,205,28, -248,22,168,14,193,250,2,54,23,15,23,16,195,251,2,58,23,15,23,16,23, -17,248,22,75,199,27,248,22,181,14,23,196,1,28,248,22,168,14,193,250,2, -54,198,199,195,11,250,80,159,39,39,39,196,197,11,250,80,159,39,39,39,196, -11,11,32,63,88,163,8,36,39,57,11,2,30,222,33,65,0,8,35,114,120, -35,34,92,34,34,27,249,22,144,15,23,197,2,23,198,2,28,23,193,2,86, -94,23,196,1,27,248,22,98,23,195,2,27,27,248,22,107,23,197,1,27,249, -22,144,15,23,201,2,23,196,2,28,23,193,2,86,94,23,194,1,27,248,22, -98,23,195,2,27,250,2,63,23,203,2,23,204,1,248,22,107,23,199,1,28, -249,22,191,7,23,196,2,2,35,249,22,87,23,202,2,194,249,22,73,248,22, -165,14,28,249,22,140,9,247,22,152,8,2,33,250,22,156,15,2,64,23,200, -1,2,35,23,197,1,194,86,95,23,199,1,23,193,1,28,249,22,191,7,23, -196,2,2,35,249,22,87,23,200,2,9,249,22,73,248,22,165,14,28,249,22, -140,9,247,22,152,8,2,33,250,22,156,15,2,64,23,200,1,2,35,23,197, -1,9,28,249,22,191,7,23,196,2,2,35,249,22,87,197,194,86,94,23,196, -1,249,22,73,248,22,165,14,28,249,22,140,9,247,22,152,8,2,33,250,22, -156,15,2,64,23,200,1,2,35,23,197,1,194,86,94,23,193,1,28,249,22, -191,7,23,198,2,2,35,249,22,87,195,9,86,94,23,194,1,249,22,73,248, -22,165,14,28,249,22,140,9,247,22,152,8,2,33,250,22,156,15,2,64,23, -202,1,2,35,23,199,1,9,86,95,28,28,248,22,183,7,194,10,248,22,130, -7,194,12,250,22,176,9,2,6,6,21,21,98,121,116,101,32,115,116,114,105, -110,103,32,111,114,32,115,116,114,105,110,103,196,28,28,248,22,82,195,249,22, -4,22,156,14,196,11,12,250,22,176,9,2,6,6,13,13,108,105,115,116,32, -111,102,32,112,97,116,104,115,197,250,2,63,197,195,28,248,22,130,7,197,248, -22,144,8,197,196,86,94,28,28,248,22,156,14,23,195,2,10,28,248,22,130, -7,23,195,2,28,248,22,178,14,23,195,2,10,248,22,179,14,23,195,2,11, -12,250,22,176,9,23,196,2,2,36,23,197,2,28,248,22,178,14,23,195,2, -12,248,22,170,12,249,22,173,11,248,22,159,7,250,22,178,7,2,37,23,200, -1,23,201,1,247,22,23,86,94,28,28,248,22,156,14,23,195,2,10,28,248, +9,2,5,6,25,25,112,97,116,104,32,111,114,32,115,116,114,105,110,103,32, +40,115,97,110,115,32,110,117,108,41,23,197,2,28,28,23,195,2,28,28,248, +22,156,14,23,196,2,10,28,248,22,130,7,23,196,2,28,248,22,178,14,23, +196,2,10,248,22,179,14,23,196,2,11,248,22,178,14,23,196,2,11,10,12, +250,22,176,9,2,5,6,29,29,35,102,32,111,114,32,114,101,108,97,116,105, +118,101,32,112,97,116,104,32,111,114,32,115,116,114,105,110,103,23,198,2,28, +28,248,22,178,14,23,195,2,90,159,39,11,89,161,39,36,11,248,22,177,14, +23,198,2,249,22,140,9,194,2,35,11,27,248,22,150,8,6,4,4,80,65, +84,72,27,28,23,194,2,27,249,80,158,41,40,23,197,1,9,28,249,22,140, +9,247,22,152,8,2,34,249,22,73,248,22,165,14,5,1,46,194,192,86,94, +23,194,1,9,28,248,22,81,23,194,2,11,27,248,22,181,14,248,22,74,23, +196,2,27,249,22,174,14,23,196,1,23,200,2,28,248,22,168,14,23,194,2, +250,2,56,201,202,195,86,94,23,193,1,27,248,22,75,23,197,1,28,248,22, +81,23,194,2,11,27,248,22,181,14,248,22,74,23,196,2,27,249,22,174,14, +23,196,1,23,203,2,28,248,22,168,14,23,194,2,250,2,56,204,205,195,86, +94,23,193,1,27,248,22,75,23,197,1,28,248,22,81,23,194,2,11,27,248, +22,181,14,248,22,74,195,27,249,22,174,14,23,196,1,205,28,248,22,168,14, +193,250,2,56,23,15,23,16,195,251,2,60,23,15,23,16,23,17,248,22,75, +199,27,248,22,181,14,23,196,1,28,248,22,168,14,193,250,2,56,198,199,195, +11,250,80,159,39,39,39,196,197,11,250,80,159,39,39,39,196,11,11,32,65, +88,163,8,36,39,57,11,2,31,222,33,67,0,8,35,114,120,35,34,92,34, +34,27,249,22,144,15,23,197,2,23,198,2,28,23,193,2,86,94,23,196,1, +27,248,22,98,23,195,2,27,27,248,22,107,23,197,1,27,249,22,144,15,23, +201,2,23,196,2,28,23,193,2,86,94,23,194,1,27,248,22,98,23,195,2, +27,250,2,65,23,203,2,23,204,1,248,22,107,23,199,1,28,249,22,191,7, +23,196,2,2,36,249,22,87,23,202,2,194,249,22,73,248,22,165,14,28,249, +22,140,9,247,22,152,8,2,34,250,22,156,15,2,66,23,200,1,2,36,23, +197,1,194,86,95,23,199,1,23,193,1,28,249,22,191,7,23,196,2,2,36, +249,22,87,23,200,2,9,249,22,73,248,22,165,14,28,249,22,140,9,247,22, +152,8,2,34,250,22,156,15,2,66,23,200,1,2,36,23,197,1,9,28,249, +22,191,7,23,196,2,2,36,249,22,87,197,194,86,94,23,196,1,249,22,73, +248,22,165,14,28,249,22,140,9,247,22,152,8,2,34,250,22,156,15,2,66, +23,200,1,2,36,23,197,1,194,86,94,23,193,1,28,249,22,191,7,23,198, +2,2,36,249,22,87,195,9,86,94,23,194,1,249,22,73,248,22,165,14,28, +249,22,140,9,247,22,152,8,2,34,250,22,156,15,2,66,23,202,1,2,36, +23,199,1,9,86,95,28,28,248,22,183,7,194,10,248,22,130,7,194,12,250, +22,176,9,2,6,6,21,21,98,121,116,101,32,115,116,114,105,110,103,32,111, +114,32,115,116,114,105,110,103,196,28,28,248,22,82,195,249,22,4,22,156,14, +196,11,12,250,22,176,9,2,6,6,13,13,108,105,115,116,32,111,102,32,112, +97,116,104,115,197,250,2,65,197,195,28,248,22,130,7,197,248,22,144,8,197, +196,86,94,28,28,248,22,156,14,23,195,2,10,28,248,22,130,7,23,195,2, +28,248,22,178,14,23,195,2,10,248,22,179,14,23,195,2,11,12,250,22,176, +9,23,196,2,2,37,23,197,2,28,248,22,178,14,23,195,2,12,248,22,170, +12,249,22,173,11,248,22,159,7,250,22,178,7,2,38,23,200,1,23,201,1, +247,22,23,86,94,28,28,248,22,156,14,23,195,2,10,28,248,22,130,7,23, +195,2,28,248,22,178,14,23,195,2,10,248,22,179,14,23,195,2,11,12,250, +22,176,9,23,196,2,2,37,23,197,2,28,248,22,178,14,23,195,2,12,248, +22,170,12,249,22,173,11,248,22,159,7,250,22,178,7,2,38,23,200,1,23, +201,1,247,22,23,86,94,86,94,28,28,248,22,156,14,23,195,2,10,28,248, 22,130,7,23,195,2,28,248,22,178,14,23,195,2,10,248,22,179,14,23,195, -2,11,12,250,22,176,9,23,196,2,2,36,23,197,2,28,248,22,178,14,23, -195,2,12,248,22,170,12,249,22,173,11,248,22,159,7,250,22,178,7,2,37, -23,200,1,23,201,1,247,22,23,86,94,86,94,28,28,248,22,156,14,23,195, -2,10,28,248,22,130,7,23,195,2,28,248,22,178,14,23,195,2,10,248,22, -179,14,23,195,2,11,12,250,22,176,9,195,2,36,23,197,2,28,248,22,178, -14,23,195,2,12,248,22,170,12,249,22,173,11,248,22,159,7,250,22,178,7, -2,37,199,23,201,1,247,22,23,249,22,3,88,163,8,36,37,50,11,9,223, -2,33,68,196,86,94,28,28,248,22,156,14,23,194,2,10,28,248,22,130,7, -23,194,2,28,248,22,178,14,23,194,2,10,248,22,179,14,23,194,2,11,12, -250,22,176,9,2,9,2,36,23,196,2,28,248,22,178,14,23,194,2,12,248, -22,170,12,249,22,173,11,248,22,159,7,250,22,178,7,2,37,2,9,23,200, -1,247,22,23,248,22,170,12,249,22,145,12,23,196,1,247,22,23,86,94,86, -94,86,94,28,28,248,22,156,14,194,10,28,248,22,130,7,194,28,248,22,178, -14,194,10,248,22,179,14,194,11,12,250,22,176,9,2,9,2,36,196,28,248, -22,178,14,194,12,248,22,170,12,249,22,173,11,248,22,159,7,250,22,178,7, -2,37,2,9,200,247,22,23,249,22,3,32,0,88,163,8,36,37,49,11,9, -222,33,70,196,252,80,158,41,44,2,9,32,0,88,163,8,36,37,45,11,9, -222,33,71,198,199,11,86,94,28,28,248,22,156,14,23,194,2,10,28,248,22, -130,7,23,194,2,28,248,22,178,14,23,194,2,10,248,22,179,14,23,194,2, -11,12,250,22,176,9,2,11,2,36,23,196,2,28,248,22,178,14,23,194,2, -12,248,22,170,12,249,22,173,11,248,22,159,7,250,22,178,7,2,37,2,11, -23,200,1,247,22,23,248,22,170,12,249,22,145,12,23,196,1,247,22,23,86, -95,86,94,28,28,248,22,156,14,194,10,28,248,22,130,7,194,28,248,22,178, -14,194,10,248,22,179,14,194,11,12,250,22,176,9,2,11,2,36,196,28,248, -22,178,14,194,12,248,22,170,12,249,22,173,11,248,22,159,7,250,22,178,7, -2,37,2,11,200,247,22,23,86,94,86,94,28,28,248,22,156,14,23,196,2, -10,28,248,22,130,7,23,196,2,28,248,22,178,14,23,196,2,10,248,22,179, -14,23,196,2,11,12,250,22,176,9,2,11,2,36,23,198,2,28,248,22,178, -14,23,196,2,12,248,22,170,12,249,22,173,11,248,22,159,7,250,22,178,7, -2,37,2,11,23,202,2,247,22,23,249,22,3,32,0,88,163,8,36,37,49, -11,9,222,33,73,23,198,2,249,22,174,14,252,80,158,43,44,2,11,32,0, -88,163,8,36,37,45,11,9,222,33,74,23,202,1,23,203,1,200,195,0,6, -45,105,110,102,46,48,27,248,22,132,15,2,38,27,28,248,22,179,14,23,195, -2,193,20,13,159,80,159,38,51,37,250,80,159,41,52,37,249,22,27,11,80, -159,43,51,37,22,133,15,248,22,132,15,68,111,114,105,103,45,100,105,114,27, -248,22,132,15,2,31,250,80,159,42,39,39,23,196,1,23,198,1,11,28,192, -250,22,174,14,195,6,6,6,99,111,110,102,105,103,6,10,10,108,105,110,107, -115,46,114,107,116,100,11,86,94,27,247,22,131,10,28,249,22,188,9,23,195, -2,2,39,251,22,191,9,23,197,1,2,39,250,22,178,7,2,40,28,23,202, -1,80,159,46,46,38,80,159,46,49,38,248,22,165,11,23,205,1,247,22,23, -12,248,193,247,22,133,2,2,76,86,95,27,247,22,131,10,28,249,22,188,9, -23,195,2,2,39,251,22,191,9,23,197,1,2,39,250,22,178,7,2,40,28, -202,80,159,47,46,38,80,159,47,49,38,248,22,165,11,23,206,1,247,22,23, -12,28,192,28,194,86,94,20,18,159,11,80,158,39,47,247,22,133,2,20,18, -159,11,80,158,39,48,192,86,94,20,18,159,11,80,158,39,53,247,22,133,2, -20,18,159,11,80,158,39,54,192,12,248,194,247,22,133,2,20,20,94,248,22, -129,6,23,194,2,28,248,22,189,6,248,22,129,6,23,195,1,12,248,22,173, -9,6,30,30,101,120,112,101,99,116,101,100,32,97,32,115,105,110,103,108,101, -32,83,45,101,120,112,114,101,115,115,105,111,110,248,22,181,5,193,28,248,22, -82,23,194,2,28,28,249,22,184,3,38,248,22,86,23,196,2,10,249,22,184, -3,39,248,22,86,23,196,2,28,28,248,22,130,7,248,22,74,23,195,2,10, -249,22,140,9,64,114,111,111,116,248,22,74,23,196,2,28,27,248,22,98,194, -28,248,22,156,14,23,194,2,10,28,248,22,130,7,23,194,2,28,248,22,178, -14,23,194,2,10,248,22,179,14,23,194,1,11,27,248,22,81,248,22,100,195, -28,192,192,248,22,157,15,248,22,107,195,11,11,11,11,250,22,151,2,196,197, -249,22,73,197,200,28,28,248,22,81,248,22,100,23,197,2,10,249,22,148,15, -248,22,107,23,198,2,247,22,148,8,27,248,22,183,14,249,22,181,14,248,22, -98,23,200,2,23,198,1,28,248,22,58,248,22,74,23,198,2,86,94,23,196, -1,86,94,28,250,22,153,2,196,11,11,12,250,22,151,2,196,11,9,249,22, -157,2,195,88,163,8,36,38,50,11,9,224,3,2,33,84,27,248,22,61,248, -22,74,23,199,1,250,22,151,2,23,198,2,23,196,2,249,22,73,248,22,125, -23,200,1,250,22,153,2,23,203,1,23,201,1,9,12,250,22,151,2,195,196, -248,22,88,198,20,13,159,80,159,37,56,37,88,163,36,37,54,8,128,144,9, -225,1,0,2,33,78,27,250,22,191,14,28,23,197,2,80,159,41,46,38,80, -159,41,49,38,11,32,0,88,163,8,36,36,41,11,9,222,33,79,28,249,22, -186,3,23,195,2,28,23,196,2,80,158,40,48,80,158,40,54,20,13,159,80, -159,38,56,37,20,20,94,88,163,36,37,55,8,240,0,60,6,0,9,226,2, -1,3,0,33,80,23,196,1,20,13,159,80,159,38,51,37,26,29,80,159,8, -31,52,37,249,22,27,11,80,159,8,33,51,37,22,190,13,10,22,191,13,10, -22,128,14,10,22,131,14,10,22,130,14,10,22,132,14,10,22,129,14,10,22, -133,14,10,22,134,14,10,22,135,14,10,22,136,14,10,22,137,14,10,22,138, -14,11,22,188,13,11,27,249,22,172,5,28,196,80,159,41,46,38,80,159,41, -49,38,66,98,105,110,97,114,121,27,250,22,40,22,31,88,163,8,36,36,44, -11,9,223,4,33,81,20,20,94,88,163,36,36,43,11,9,223,4,33,82,23, -197,1,86,94,28,28,248,22,82,23,194,2,249,22,4,32,0,88,163,8,36, -37,45,11,9,222,33,83,23,195,2,11,12,248,22,173,9,6,18,18,105,108, -108,45,102,111,114,109,101,100,32,99,111,110,116,101,110,116,27,247,22,133,2, -27,90,159,39,11,89,161,39,36,11,248,22,177,14,28,201,80,159,46,46,38, -80,159,46,49,38,192,86,96,249,22,3,20,20,94,88,163,8,36,37,54,11, -9,224,2,3,33,85,23,195,1,23,197,1,249,22,157,2,195,88,163,8,36, -38,48,11,9,223,3,33,86,28,197,86,94,20,18,159,11,80,158,42,47,193, -20,18,159,11,80,158,42,48,196,86,94,20,18,159,11,80,158,42,53,193,20, -18,159,11,80,158,42,54,196,193,28,193,80,158,38,47,80,158,38,53,248,22, -9,88,163,8,32,37,8,40,8,240,0,188,23,0,9,224,1,2,33,87,0, -7,35,114,120,34,47,43,34,28,248,22,130,7,23,195,2,27,249,22,146,15, -2,89,196,28,192,28,249,22,184,3,248,22,97,195,248,22,174,3,248,22,133, -7,198,249,22,7,250,22,152,7,199,36,248,22,97,198,197,249,22,7,250,22, -152,7,199,36,248,22,97,198,249,22,73,249,22,152,7,200,248,22,99,199,199, -249,22,7,196,197,90,159,39,11,89,161,39,36,11,248,22,177,14,23,198,1, -86,94,23,195,1,28,249,22,140,9,23,195,2,2,34,249,22,7,195,199,27, -249,22,73,23,197,1,23,201,1,28,248,22,130,7,23,195,2,27,249,22,146, -15,2,89,196,28,192,28,249,22,184,3,248,22,97,195,248,22,174,3,248,22, -133,7,198,249,22,7,250,22,152,7,199,36,248,22,97,198,195,249,22,7,250, -22,152,7,199,36,248,22,97,198,249,22,73,249,22,152,7,200,248,22,99,199, -197,249,22,7,196,195,90,159,39,11,89,161,39,36,11,248,22,177,14,23,198, -1,28,249,22,140,9,194,2,34,249,22,7,195,197,249,80,159,45,57,39,194, -249,22,73,197,199,32,91,88,163,36,44,8,36,11,65,99,108,111,111,112,222, -33,96,32,92,88,163,8,36,37,55,11,2,30,222,33,93,28,248,22,81,248, -22,75,23,195,2,248,22,83,27,248,22,74,23,196,1,28,248,22,156,14,23, -194,2,248,22,160,14,23,194,1,192,250,22,84,27,248,22,74,23,198,2,28, -248,22,156,14,23,194,2,248,22,160,14,23,194,1,192,2,42,27,248,22,75, -23,198,1,28,248,22,81,248,22,75,23,195,2,248,22,83,27,248,22,74,23, -196,1,28,248,22,156,14,23,194,2,248,22,160,14,23,194,1,192,250,22,84, -27,248,22,74,23,198,2,28,248,22,156,14,23,194,2,248,22,160,14,23,194, -1,192,2,42,27,248,22,75,23,198,1,28,248,22,81,248,22,75,23,195,2, -248,22,83,27,248,22,74,23,196,1,28,248,22,156,14,23,194,2,248,22,160, -14,23,194,1,192,250,22,84,27,248,22,74,23,198,2,28,248,22,156,14,23, -194,2,248,22,160,14,23,194,1,192,2,42,248,2,92,248,22,75,23,198,1, -32,94,88,163,8,36,38,57,11,66,102,105,108,116,101,114,222,33,95,28,248, -22,81,23,195,2,9,28,248,23,194,2,248,22,74,23,196,2,249,22,73,248, -22,74,23,197,2,27,248,22,75,23,198,1,28,248,22,81,23,194,2,9,28, -248,23,197,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,27,248, -22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,200,2,248,22,74, -23,195,2,249,22,73,248,22,74,23,196,2,27,248,22,75,23,197,1,28,248, -22,81,23,194,2,9,28,248,23,203,2,248,22,74,23,195,2,249,22,73,248, -22,74,23,196,2,249,2,94,23,206,1,248,22,75,23,198,1,249,2,94,23, -204,1,248,22,75,23,196,1,27,248,22,75,23,195,1,28,248,22,81,23,194, -2,9,28,248,23,201,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196, -2,249,2,94,23,204,1,248,22,75,23,198,1,249,2,94,23,202,1,248,22, -75,23,196,1,27,248,22,75,23,195,1,28,248,22,81,23,194,2,9,28,248, -23,198,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,27,248,22, -75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,201,2,248,22,74,23, -195,2,249,22,73,248,22,74,23,196,2,249,2,94,23,204,1,248,22,75,23, -198,1,249,2,94,23,202,1,248,22,75,23,196,1,27,248,22,75,23,195,1, -28,248,22,81,23,194,2,9,28,248,23,199,2,248,22,74,23,195,2,249,22, -73,248,22,74,23,196,2,249,2,94,23,202,1,248,22,75,23,198,1,249,2, -94,23,200,1,248,22,75,23,196,1,27,248,22,75,23,196,1,28,248,22,81, -23,194,2,9,28,248,23,195,2,248,22,74,23,195,2,249,22,73,248,22,74, -23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,23, -198,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,27,248,22,75, -23,197,1,28,248,22,81,23,194,2,9,28,248,23,201,2,248,22,74,23,195, -2,249,22,73,248,22,74,23,196,2,249,2,94,23,204,1,248,22,75,23,198, -1,249,2,94,23,202,1,248,22,75,23,196,1,27,248,22,75,23,195,1,28, -248,22,81,23,194,2,9,28,248,23,199,2,248,22,74,23,195,2,249,22,73, -248,22,74,23,196,2,249,2,94,23,202,1,248,22,75,23,198,1,249,2,94, -23,200,1,248,22,75,23,196,1,27,248,22,75,23,195,1,28,248,22,81,23, -194,2,9,28,248,23,196,2,248,22,74,23,195,2,249,22,73,248,22,74,23, -196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,199, -2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,23,202, -1,248,22,75,23,198,1,249,2,94,23,200,1,248,22,75,23,196,1,27,248, -22,75,23,195,1,28,248,22,81,23,194,2,9,28,248,23,197,2,248,22,74, -23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,23,200,1,248,22,75, -23,198,1,249,2,94,197,248,22,75,195,28,248,22,81,23,200,2,86,95,23, -199,1,23,198,1,28,23,200,2,199,86,94,23,200,1,27,28,248,22,81,23, -197,2,2,41,249,22,1,22,153,7,248,2,92,23,199,2,248,23,199,1,252, -22,178,7,6,44,44,126,97,58,32,99,111,108,108,101,99,116,105,111,110,32, -110,111,116,32,102,111,117,110,100,58,32,126,115,32,105,110,32,97,110,121,32, -111,102,58,32,126,115,126,97,23,203,1,28,248,22,81,23,203,1,28,248,22, -156,14,23,202,2,248,22,160,14,23,202,1,23,201,1,250,22,153,7,28,248, -22,156,14,23,205,2,248,22,160,14,23,205,1,23,204,1,2,42,23,202,2, -28,248,22,81,23,201,2,9,28,248,22,156,14,248,22,74,23,202,2,249,22, -73,248,22,74,23,203,2,27,248,22,75,23,204,2,28,248,22,81,23,194,2, -9,28,248,22,156,14,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2, -27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,22,156,14,248, -22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,22,156,14,248, -22,75,23,198,1,249,2,94,22,156,14,248,22,75,23,196,1,27,248,22,75, -23,195,1,28,248,22,81,23,194,2,9,28,248,22,156,14,248,22,74,23,195, -2,249,22,73,248,22,74,23,196,2,249,2,94,22,156,14,248,22,75,23,198, -1,249,2,94,22,156,14,248,22,75,23,196,1,27,248,22,75,23,202,2,28, -248,22,81,23,194,2,9,28,248,22,156,14,248,22,74,23,195,2,249,22,73, +2,11,12,250,22,176,9,195,2,37,23,197,2,28,248,22,178,14,23,195,2, +12,248,22,170,12,249,22,173,11,248,22,159,7,250,22,178,7,2,38,199,23, +201,1,247,22,23,249,22,3,88,163,8,36,37,50,11,9,223,2,33,70,196, +28,28,248,22,0,194,249,22,44,195,37,11,12,250,22,176,9,195,2,39,196, +86,94,28,28,248,22,156,14,23,194,2,10,28,248,22,130,7,23,194,2,28, +248,22,178,14,23,194,2,10,248,22,179,14,23,194,2,11,12,250,22,176,9, +2,10,2,37,23,196,2,28,248,22,178,14,23,194,2,12,248,22,170,12,249, +22,173,11,248,22,159,7,250,22,178,7,2,38,2,10,23,200,1,247,22,23, +86,95,86,94,86,94,28,28,248,22,156,14,195,10,28,248,22,130,7,195,28, +248,22,178,14,195,10,248,22,179,14,195,11,12,250,22,176,9,2,10,2,37, +197,28,248,22,178,14,195,12,248,22,170,12,249,22,173,11,248,22,159,7,250, +22,178,7,2,38,2,10,201,247,22,23,249,22,3,32,0,88,163,8,36,37, +49,11,9,222,33,73,197,28,28,248,22,0,194,249,22,44,195,37,11,12,250, +22,176,9,2,10,2,39,196,251,80,158,40,45,197,198,199,11,86,94,28,28, +248,22,156,14,23,194,2,10,28,248,22,130,7,23,194,2,28,248,22,178,14, +23,194,2,10,248,22,179,14,23,194,2,11,12,250,22,176,9,2,12,2,37, +23,196,2,28,248,22,178,14,23,194,2,12,248,22,170,12,249,22,173,11,248, +22,159,7,250,22,178,7,2,38,2,12,23,200,1,247,22,23,86,96,86,94, +28,28,248,22,156,14,195,10,28,248,22,130,7,195,28,248,22,178,14,195,10, +248,22,179,14,195,11,12,250,22,176,9,2,12,2,37,197,28,248,22,178,14, +195,12,248,22,170,12,249,22,173,11,248,22,159,7,250,22,178,7,2,38,2, +12,201,247,22,23,86,94,86,94,28,28,248,22,156,14,196,10,28,248,22,130, +7,196,28,248,22,178,14,196,10,248,22,179,14,196,11,12,250,22,176,9,2, +12,2,37,198,28,248,22,178,14,196,12,248,22,170,12,249,22,173,11,248,22, +159,7,250,22,178,7,2,38,2,12,202,247,22,23,249,22,3,32,0,88,163, +8,36,37,49,11,9,222,33,75,198,28,28,248,22,0,194,249,22,44,195,37, +11,12,250,22,176,9,2,12,2,39,196,251,80,158,40,45,197,199,200,198,0, +6,45,105,110,102,46,48,27,248,22,132,15,2,40,27,28,248,22,179,14,23, +195,2,193,20,13,159,80,159,38,52,37,250,80,159,41,53,37,249,22,27,11, +80,159,43,52,37,22,133,15,248,22,132,15,68,111,114,105,103,45,100,105,114, +27,248,22,132,15,2,32,250,80,159,42,39,39,23,196,1,23,198,1,11,28, +192,250,22,174,14,195,6,6,6,99,111,110,102,105,103,6,10,10,108,105,110, +107,115,46,114,107,116,100,11,86,94,27,247,22,131,10,28,249,22,188,9,23, +195,2,2,41,251,22,191,9,23,197,1,2,41,250,22,178,7,2,42,28,23, +202,1,80,159,46,47,38,80,159,46,50,38,248,22,165,11,23,205,1,247,22, +23,12,248,193,247,22,133,2,2,77,86,95,27,247,22,131,10,28,249,22,188, +9,23,195,2,2,41,251,22,191,9,23,197,1,2,41,250,22,178,7,2,42, +28,202,80,159,47,47,38,80,159,47,50,38,248,22,165,11,23,206,1,247,22, +23,12,28,192,28,194,86,94,20,18,159,11,80,158,39,48,247,22,133,2,20, +18,159,11,80,158,39,49,192,86,94,20,18,159,11,80,158,39,54,247,22,133, +2,20,18,159,11,80,158,39,55,192,12,248,194,247,22,133,2,20,20,94,248, +22,129,6,23,194,2,28,248,22,189,6,248,22,129,6,23,195,1,12,248,22, +173,9,6,30,30,101,120,112,101,99,116,101,100,32,97,32,115,105,110,103,108, +101,32,83,45,101,120,112,114,101,115,115,105,111,110,248,22,181,5,193,28,248, +22,82,23,194,2,28,28,249,22,184,3,38,248,22,86,23,196,2,10,249,22, +184,3,39,248,22,86,23,196,2,28,28,248,22,130,7,248,22,74,23,195,2, +10,249,22,140,9,64,114,111,111,116,248,22,74,23,196,2,28,27,248,22,98, +194,28,248,22,156,14,23,194,2,10,28,248,22,130,7,23,194,2,28,248,22, +178,14,23,194,2,10,248,22,179,14,23,194,1,11,27,248,22,81,248,22,100, +195,28,192,192,248,22,157,15,248,22,107,195,11,11,11,11,250,22,151,2,196, +197,249,22,73,197,200,28,28,248,22,81,248,22,100,23,197,2,10,249,22,148, +15,248,22,107,23,198,2,247,22,148,8,27,248,22,183,14,249,22,181,14,248, +22,98,23,200,2,23,198,1,28,248,22,58,248,22,74,23,198,2,86,94,23, +196,1,86,94,28,250,22,153,2,196,11,11,12,250,22,151,2,196,11,9,249, +22,157,2,195,88,163,8,36,38,50,11,9,224,3,2,33,85,27,248,22,61, +248,22,74,23,199,1,250,22,151,2,23,198,2,23,196,2,249,22,73,248,22, +125,23,200,1,250,22,153,2,23,203,1,23,201,1,9,12,250,22,151,2,195, +196,248,22,88,198,20,13,159,80,159,37,57,37,88,163,36,37,54,8,240,0, +72,0,0,9,225,1,0,2,33,79,27,250,22,191,14,28,23,197,2,80,159, +41,47,38,80,159,41,50,38,11,32,0,88,163,8,36,36,41,11,9,222,33, +80,28,249,22,186,3,23,195,2,28,23,196,2,80,158,40,49,80,158,40,55, +20,13,159,80,159,38,57,37,20,20,94,88,163,36,37,55,8,240,0,120,12, +0,9,226,2,1,3,0,33,81,23,196,1,20,13,159,80,159,38,52,37,26, +29,80,159,8,31,53,37,249,22,27,11,80,159,8,33,52,37,22,190,13,10, +22,191,13,10,22,128,14,10,22,131,14,10,22,130,14,10,22,132,14,10,22, +129,14,10,22,133,14,10,22,134,14,10,22,135,14,10,22,136,14,10,22,137, +14,10,22,138,14,11,22,188,13,11,27,249,22,172,5,28,196,80,159,41,47, +38,80,159,41,50,38,66,98,105,110,97,114,121,27,250,22,40,22,31,88,163, +8,36,36,44,11,9,223,4,33,82,20,20,94,88,163,36,36,43,11,9,223, +4,33,83,23,197,1,86,94,28,28,248,22,82,23,194,2,249,22,4,32,0, +88,163,8,36,37,45,11,9,222,33,84,23,195,2,11,12,248,22,173,9,6, +18,18,105,108,108,45,102,111,114,109,101,100,32,99,111,110,116,101,110,116,27, +247,22,133,2,27,90,159,39,11,89,161,39,36,11,248,22,177,14,28,201,80, +159,46,47,38,80,159,46,50,38,192,86,96,249,22,3,20,20,94,88,163,8, +36,37,54,11,9,224,2,3,33,86,23,195,1,23,197,1,249,22,157,2,195, +88,163,8,36,38,48,11,9,223,3,33,87,28,197,86,94,20,18,159,11,80, +158,42,48,193,20,18,159,11,80,158,42,49,196,86,94,20,18,159,11,80,158, +42,54,193,20,18,159,11,80,158,42,55,196,193,28,193,80,158,38,48,80,158, +38,54,248,22,9,88,163,8,32,37,8,40,8,240,0,120,47,0,9,224,1, +2,33,88,0,7,35,114,120,34,47,43,34,28,248,22,130,7,23,195,2,27, +249,22,146,15,2,90,196,28,192,28,249,22,184,3,248,22,97,195,248,22,174, +3,248,22,133,7,198,249,22,7,250,22,152,7,199,36,248,22,97,198,197,249, +22,7,250,22,152,7,199,36,248,22,97,198,249,22,73,249,22,152,7,200,248, +22,99,199,199,249,22,7,196,197,90,159,39,11,89,161,39,36,11,248,22,177, +14,23,198,1,86,94,23,195,1,28,249,22,140,9,23,195,2,2,35,249,22, +7,195,199,27,249,22,73,23,197,1,23,201,1,28,248,22,130,7,23,195,2, +27,249,22,146,15,2,90,196,28,192,28,249,22,184,3,248,22,97,195,248,22, +174,3,248,22,133,7,198,249,22,7,250,22,152,7,199,36,248,22,97,198,195, +249,22,7,250,22,152,7,199,36,248,22,97,198,249,22,73,249,22,152,7,200, +248,22,99,199,197,249,22,7,196,195,90,159,39,11,89,161,39,36,11,248,22, +177,14,23,198,1,28,249,22,140,9,194,2,35,249,22,7,195,197,249,80,159, +45,58,39,194,249,22,73,197,199,32,92,88,163,36,43,8,34,11,65,99,108, +111,111,112,222,33,97,32,93,88,163,8,36,37,55,11,2,31,222,33,94,28, +248,22,81,248,22,75,23,195,2,248,22,83,27,248,22,74,23,196,1,28,248, +22,156,14,23,194,2,248,22,160,14,23,194,1,192,250,22,84,27,248,22,74, +23,198,2,28,248,22,156,14,23,194,2,248,22,160,14,23,194,1,192,2,44, +27,248,22,75,23,198,1,28,248,22,81,248,22,75,23,195,2,248,22,83,27, +248,22,74,23,196,1,28,248,22,156,14,23,194,2,248,22,160,14,23,194,1, +192,250,22,84,27,248,22,74,23,198,2,28,248,22,156,14,23,194,2,248,22, +160,14,23,194,1,192,2,44,27,248,22,75,23,198,1,28,248,22,81,248,22, +75,23,195,2,248,22,83,27,248,22,74,23,196,1,28,248,22,156,14,23,194, +2,248,22,160,14,23,194,1,192,250,22,84,27,248,22,74,23,198,2,28,248, +22,156,14,23,194,2,248,22,160,14,23,194,1,192,2,44,248,2,93,248,22, +75,23,198,1,32,95,88,163,8,36,38,57,11,66,102,105,108,116,101,114,222, +33,96,28,248,22,81,23,195,2,9,28,248,23,194,2,248,22,74,23,196,2, +249,22,73,248,22,74,23,197,2,27,248,22,75,23,198,1,28,248,22,81,23, +194,2,9,28,248,23,197,2,248,22,74,23,195,2,249,22,73,248,22,74,23, +196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,200, +2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,27,248,22,75,23, +197,1,28,248,22,81,23,194,2,9,28,248,23,203,2,248,22,74,23,195,2, +249,22,73,248,22,74,23,196,2,249,2,95,23,206,1,248,22,75,23,198,1, +249,2,95,23,204,1,248,22,75,23,196,1,27,248,22,75,23,195,1,28,248, +22,81,23,194,2,9,28,248,23,201,2,248,22,74,23,195,2,249,22,73,248, +22,74,23,196,2,249,2,95,23,204,1,248,22,75,23,198,1,249,2,95,23, +202,1,248,22,75,23,196,1,27,248,22,75,23,195,1,28,248,22,81,23,194, +2,9,28,248,23,198,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196, +2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,201,2, +248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,95,23,204,1, +248,22,75,23,198,1,249,2,95,23,202,1,248,22,75,23,196,1,27,248,22, +75,23,195,1,28,248,22,81,23,194,2,9,28,248,23,199,2,248,22,74,23, +195,2,249,22,73,248,22,74,23,196,2,249,2,95,23,202,1,248,22,75,23, +198,1,249,2,95,23,200,1,248,22,75,23,196,1,27,248,22,75,23,196,1, +28,248,22,81,23,194,2,9,28,248,23,195,2,248,22,74,23,195,2,249,22, +73,248,22,74,23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2, +9,28,248,23,198,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2, +27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,23,201,2,248, +22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,95,23,204,1,248, +22,75,23,198,1,249,2,95,23,202,1,248,22,75,23,196,1,27,248,22,75, +23,195,1,28,248,22,81,23,194,2,9,28,248,23,199,2,248,22,74,23,195, +2,249,22,73,248,22,74,23,196,2,249,2,95,23,202,1,248,22,75,23,198, +1,249,2,95,23,200,1,248,22,75,23,196,1,27,248,22,75,23,195,1,28, +248,22,81,23,194,2,9,28,248,23,196,2,248,22,74,23,195,2,249,22,73, 248,22,74,23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9, -28,248,22,156,14,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249, -2,94,22,156,14,248,22,75,23,198,1,249,2,94,22,156,14,248,22,75,23, -196,1,27,248,22,75,23,195,1,28,248,22,81,23,194,2,9,28,248,22,156, -14,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,22,156, -14,248,22,75,23,198,1,249,2,94,22,156,14,248,22,75,23,196,1,28,249, -22,5,22,127,23,202,2,250,22,178,7,6,21,21,32,111,114,58,32,126,115, -32,105,110,32,97,110,121,32,111,102,58,32,126,115,23,202,1,249,22,2,22, -128,2,28,248,22,81,23,206,2,86,94,23,205,1,9,28,248,22,127,248,22, -74,23,207,2,249,22,73,248,22,74,23,208,2,27,248,22,75,23,209,1,28, -248,22,81,23,194,2,9,28,248,22,127,248,22,74,23,195,2,249,22,73,248, -22,74,23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28, -248,22,127,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94, -22,127,248,22,75,23,198,1,249,2,94,22,127,248,22,75,23,196,1,27,248, -22,75,23,195,1,28,248,22,81,23,194,2,9,28,248,22,127,248,22,74,23, -195,2,249,22,73,248,22,74,23,196,2,249,2,94,22,127,248,22,75,23,198, -1,249,2,94,22,127,248,22,75,23,196,1,27,248,22,75,23,207,1,28,248, -22,81,23,194,2,9,28,248,22,127,248,22,74,23,195,2,249,22,73,248,22, -74,23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248, -22,127,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,94,22, -127,248,22,75,23,198,1,249,2,94,22,127,248,22,75,23,196,1,27,248,22, -75,23,195,1,28,248,22,81,23,194,2,9,28,248,22,127,248,22,74,23,195, -2,249,22,73,248,22,74,23,196,2,249,2,94,22,127,248,22,75,23,198,1, -249,2,94,22,127,248,22,75,23,196,1,86,94,23,199,1,2,41,27,248,22, -74,23,201,2,27,28,248,22,156,14,23,195,2,249,22,174,14,23,196,1,23, -198,2,248,22,128,2,23,195,1,28,28,248,22,156,14,248,22,74,23,203,2, -248,22,169,14,23,194,2,10,27,250,22,1,22,174,14,23,197,1,23,201,2, -28,28,248,22,81,23,199,2,10,248,22,169,14,23,194,2,28,23,201,2,28, -28,248,22,168,14,249,22,174,14,195,203,10,27,28,248,22,156,14,202,248,22, -160,14,202,201,27,248,22,133,7,23,195,2,27,28,249,22,188,3,23,196,2, -40,28,249,22,136,7,6,4,4,46,114,107,116,249,22,152,7,23,199,2,249, -22,176,3,23,200,2,40,249,22,153,7,250,22,152,7,23,200,1,36,249,22, -176,3,23,201,1,40,6,3,3,46,115,115,86,95,23,195,1,23,194,1,11, -11,28,23,193,2,248,22,168,14,249,22,174,14,198,23,196,1,11,192,26,8, -2,91,203,204,205,206,23,15,23,16,248,22,75,23,18,28,23,18,23,18,200, -192,26,8,2,91,203,204,205,206,23,15,23,16,248,22,75,23,18,23,18,26, -8,2,91,202,203,204,205,206,23,15,248,22,75,23,17,23,17,90,159,38,11, -89,161,38,36,11,249,80,159,40,57,39,23,200,1,23,201,1,27,248,22,61, -28,248,22,156,14,195,248,22,160,14,195,194,27,247,22,137,15,27,250,22,87, -28,23,197,2,28,247,22,136,15,27,248,80,159,46,55,39,10,27,250,22,153, -2,23,197,2,23,203,2,11,28,23,193,2,192,86,94,23,193,1,250,22,153, -2,23,197,1,11,9,9,9,28,23,197,1,28,80,159,44,49,38,27,248,80, -159,46,55,39,11,27,250,22,153,2,23,197,2,23,203,1,11,28,23,193,2, -192,86,94,23,193,1,250,22,153,2,23,197,1,11,9,86,94,23,198,1,9, -9,247,22,134,15,26,8,2,91,200,203,204,206,23,15,23,18,200,11,86,95, -28,28,248,22,157,14,23,194,2,10,28,248,22,156,14,23,194,2,10,28,248, -22,130,7,23,194,2,28,248,22,178,14,23,194,2,10,248,22,179,14,23,194, -2,11,12,252,22,176,9,23,200,2,2,32,36,23,198,2,23,199,2,28,28, -248,22,130,7,23,195,2,10,248,22,183,7,23,195,2,86,94,23,194,1,12, -252,22,176,9,23,200,2,2,43,37,23,198,2,23,199,1,90,159,39,11,89, -161,39,36,11,248,22,177,14,23,197,2,86,94,23,195,1,86,94,28,192,12, -250,22,177,9,23,201,1,2,44,23,199,1,249,22,7,194,195,90,159,38,11, -89,161,38,36,11,86,95,28,28,248,22,157,14,23,196,2,10,28,248,22,156, -14,23,196,2,10,28,248,22,130,7,23,196,2,28,248,22,178,14,23,196,2, -10,248,22,179,14,23,196,2,11,12,252,22,176,9,2,25,2,32,36,23,200, -2,23,201,2,28,28,248,22,130,7,23,197,2,10,248,22,183,7,23,197,2, -12,252,22,176,9,2,25,2,43,37,23,200,2,23,201,2,90,159,39,11,89, -161,39,36,11,248,22,177,14,23,199,2,86,94,23,195,1,86,94,28,192,12, -250,22,177,9,2,25,2,44,23,201,2,249,22,7,194,195,27,249,22,166,14, -250,22,155,15,0,20,35,114,120,35,34,40,63,58,91,46,93,91,94,46,93, -42,124,41,36,34,248,22,162,14,23,201,1,28,248,22,130,7,23,203,2,249, -22,145,8,23,204,1,8,63,23,202,1,28,248,22,157,14,23,199,2,248,22, -158,14,23,199,1,86,94,23,198,1,247,22,159,14,28,248,22,156,14,194,249, -22,174,14,195,194,192,90,159,38,11,89,161,38,36,11,86,95,28,28,248,22, -157,14,23,196,2,10,28,248,22,156,14,23,196,2,10,28,248,22,130,7,23, -196,2,28,248,22,178,14,23,196,2,10,248,22,179,14,23,196,2,11,12,252, -22,176,9,2,26,2,32,36,23,200,2,23,201,2,28,28,248,22,130,7,23, -197,2,10,248,22,183,7,23,197,2,12,252,22,176,9,2,26,2,43,37,23, -200,2,23,201,2,90,159,39,11,89,161,39,36,11,248,22,177,14,23,199,2, -86,94,23,195,1,86,94,28,192,12,250,22,177,9,2,26,2,44,23,201,2, -249,22,7,194,195,27,249,22,166,14,249,22,131,8,250,22,156,15,0,9,35, -114,120,35,34,91,46,93,34,248,22,162,14,23,203,1,6,1,1,95,28,248, -22,130,7,23,202,2,249,22,145,8,23,203,1,8,63,23,201,1,28,248,22, -157,14,23,199,2,248,22,158,14,23,199,1,86,94,23,198,1,247,22,159,14, -28,248,22,156,14,194,249,22,174,14,195,194,192,249,247,22,161,5,194,11,249, -247,22,161,5,194,11,27,247,22,136,15,249,80,159,39,40,38,28,23,195,2, -27,248,22,150,8,2,45,28,192,192,2,41,2,41,27,28,23,196,1,250,22, -174,14,248,22,132,15,2,46,247,22,148,8,2,47,11,27,248,80,159,42,8, -28,39,250,22,87,9,248,22,83,248,22,132,15,2,38,9,28,193,249,22,73, -195,194,192,27,247,22,136,15,249,80,159,39,40,38,28,23,195,2,27,248,22, -150,8,2,45,28,192,192,2,41,2,41,27,28,23,196,1,250,22,174,14,248, -22,132,15,2,46,247,22,148,8,2,47,11,27,248,80,159,42,8,29,39,250, -22,87,23,203,1,248,22,83,248,22,132,15,2,38,9,28,193,249,22,73,195, +28,248,23,199,2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249, +2,95,23,202,1,248,22,75,23,198,1,249,2,95,23,200,1,248,22,75,23, +196,1,27,248,22,75,23,195,1,28,248,22,81,23,194,2,9,28,248,23,197, +2,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,95,23,200, +1,248,22,75,23,198,1,249,2,95,197,248,22,75,195,28,248,22,81,23,199, +2,86,94,23,198,1,28,23,199,2,28,196,249,22,174,14,200,198,198,27,28, +248,22,81,23,197,2,2,43,249,22,1,22,153,7,248,2,93,23,199,2,248, +23,198,1,251,22,178,7,6,40,40,99,111,108,108,101,99,116,105,111,110,32, +110,111,116,32,102,111,117,110,100,58,32,126,115,32,105,110,32,97,110,121,32, +111,102,58,32,126,115,126,97,28,248,22,81,23,202,1,28,248,22,156,14,23, +201,2,248,22,160,14,23,201,1,23,200,1,250,22,153,7,28,248,22,156,14, +23,204,2,248,22,160,14,23,204,1,23,203,1,2,44,23,201,2,28,248,22, +81,23,200,2,9,28,248,22,156,14,248,22,74,23,201,2,249,22,73,248,22, +74,23,202,2,27,248,22,75,23,203,2,28,248,22,81,23,194,2,9,28,248, +22,156,14,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,27,248,22, +75,23,197,1,28,248,22,81,23,194,2,9,28,248,22,156,14,248,22,74,23, +195,2,249,22,73,248,22,74,23,196,2,249,2,95,22,156,14,248,22,75,23, +198,1,249,2,95,22,156,14,248,22,75,23,196,1,27,248,22,75,23,195,1, +28,248,22,81,23,194,2,9,28,248,22,156,14,248,22,74,23,195,2,249,22, +73,248,22,74,23,196,2,249,2,95,22,156,14,248,22,75,23,198,1,249,2, +95,22,156,14,248,22,75,23,196,1,27,248,22,75,23,201,2,28,248,22,81, +23,194,2,9,28,248,22,156,14,248,22,74,23,195,2,249,22,73,248,22,74, +23,196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,22, +156,14,248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,95,22, +156,14,248,22,75,23,198,1,249,2,95,22,156,14,248,22,75,23,196,1,27, +248,22,75,23,195,1,28,248,22,81,23,194,2,9,28,248,22,156,14,248,22, +74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,95,22,156,14,248,22, +75,23,198,1,249,2,95,22,156,14,248,22,75,23,196,1,28,249,22,5,22, +127,23,201,2,250,22,178,7,6,21,21,32,111,114,58,32,126,115,32,105,110, +32,97,110,121,32,111,102,58,32,126,115,23,201,1,249,22,2,22,128,2,28, +248,22,81,23,205,2,86,94,23,204,1,9,28,248,22,127,248,22,74,23,206, +2,249,22,73,248,22,74,23,207,2,27,248,22,75,23,208,1,28,248,22,81, +23,194,2,9,28,248,22,127,248,22,74,23,195,2,249,22,73,248,22,74,23, +196,2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,22,127, +248,22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,95,22,127,248, +22,75,23,198,1,249,2,95,22,127,248,22,75,23,196,1,27,248,22,75,23, +195,1,28,248,22,81,23,194,2,9,28,248,22,127,248,22,74,23,195,2,249, +22,73,248,22,74,23,196,2,249,2,95,22,127,248,22,75,23,198,1,249,2, +95,22,127,248,22,75,23,196,1,27,248,22,75,23,206,1,28,248,22,81,23, +194,2,9,28,248,22,127,248,22,74,23,195,2,249,22,73,248,22,74,23,196, +2,27,248,22,75,23,197,1,28,248,22,81,23,194,2,9,28,248,22,127,248, +22,74,23,195,2,249,22,73,248,22,74,23,196,2,249,2,95,22,127,248,22, +75,23,198,1,249,2,95,22,127,248,22,75,23,196,1,27,248,22,75,23,195, +1,28,248,22,81,23,194,2,9,28,248,22,127,248,22,74,23,195,2,249,22, +73,248,22,74,23,196,2,249,2,95,22,127,248,22,75,23,198,1,249,2,95, +22,127,248,22,75,23,196,1,86,94,23,198,1,2,43,27,248,22,74,23,200, +2,27,28,248,22,156,14,23,195,2,249,22,174,14,23,196,1,23,198,2,248, +22,128,2,23,195,1,28,28,248,22,156,14,248,22,74,23,202,2,248,22,169, +14,23,194,2,10,27,250,22,1,22,174,14,23,197,1,23,201,2,28,28,248, +22,81,23,199,2,10,248,22,169,14,23,194,2,28,23,200,2,28,28,248,22, +168,14,249,22,174,14,195,202,10,27,28,248,22,156,14,201,248,22,160,14,201, +200,27,248,22,133,7,23,195,2,27,28,249,22,188,3,23,196,2,40,28,249, +22,136,7,6,4,4,46,114,107,116,249,22,152,7,23,199,2,249,22,176,3, +23,200,2,40,249,22,153,7,250,22,152,7,23,200,1,36,249,22,176,3,23, +201,1,40,6,3,3,46,115,115,86,95,23,195,1,23,194,1,11,11,28,23, +193,2,248,22,168,14,249,22,174,14,198,23,196,1,11,28,199,249,22,174,14, +194,201,192,254,2,92,202,203,204,205,206,248,22,75,23,16,28,23,16,23,16, +199,28,199,249,22,174,14,194,201,192,254,2,92,202,203,204,205,206,248,22,75, +23,16,23,16,254,2,92,201,202,203,204,205,248,22,75,23,15,23,15,90,159, +38,11,89,161,38,36,11,249,80,159,40,58,39,23,199,1,23,200,1,27,248, +22,61,28,248,22,156,14,195,248,22,160,14,195,194,27,247,22,137,15,27,250, +22,87,28,23,197,2,28,247,22,136,15,27,248,80,159,46,56,39,10,27,250, +22,153,2,23,197,2,23,203,2,11,28,23,193,2,192,86,94,23,193,1,250, +22,153,2,23,197,1,11,9,9,9,28,23,197,1,28,80,159,44,50,38,27, +248,80,159,46,56,39,11,27,250,22,153,2,23,197,2,23,203,1,11,28,23, +193,2,192,86,94,23,193,1,250,22,153,2,23,197,1,11,9,86,94,23,198, +1,9,9,247,22,134,15,254,2,92,199,202,203,205,23,16,199,11,86,95,28, +28,248,22,157,14,23,194,2,10,28,248,22,156,14,23,194,2,10,28,248,22, +130,7,23,194,2,28,248,22,178,14,23,194,2,10,248,22,179,14,23,194,2, +11,12,252,22,176,9,23,200,2,2,33,36,23,198,2,23,199,2,28,28,248, +22,130,7,23,195,2,10,248,22,183,7,23,195,2,86,94,23,194,1,12,252, +22,176,9,23,200,2,2,45,37,23,198,2,23,199,1,90,159,39,11,89,161, +39,36,11,248,22,177,14,23,197,2,86,94,23,195,1,86,94,28,192,12,250, +22,177,9,23,201,1,2,46,23,199,1,249,22,7,194,195,90,159,38,11,89, +161,38,36,11,86,95,28,28,248,22,157,14,23,196,2,10,28,248,22,156,14, +23,196,2,10,28,248,22,130,7,23,196,2,28,248,22,178,14,23,196,2,10, +248,22,179,14,23,196,2,11,12,252,22,176,9,2,26,2,33,36,23,200,2, +23,201,2,28,28,248,22,130,7,23,197,2,10,248,22,183,7,23,197,2,12, +252,22,176,9,2,26,2,45,37,23,200,2,23,201,2,90,159,39,11,89,161, +39,36,11,248,22,177,14,23,199,2,86,94,23,195,1,86,94,28,192,12,250, +22,177,9,2,26,2,46,23,201,2,249,22,7,194,195,27,249,22,166,14,250, +22,155,15,0,20,35,114,120,35,34,40,63,58,91,46,93,91,94,46,93,42, +124,41,36,34,248,22,162,14,23,201,1,28,248,22,130,7,23,203,2,249,22, +145,8,23,204,1,8,63,23,202,1,28,248,22,157,14,23,199,2,248,22,158, +14,23,199,1,86,94,23,198,1,247,22,159,14,28,248,22,156,14,194,249,22, +174,14,195,194,192,90,159,38,11,89,161,38,36,11,86,95,28,28,248,22,157, +14,23,196,2,10,28,248,22,156,14,23,196,2,10,28,248,22,130,7,23,196, +2,28,248,22,178,14,23,196,2,10,248,22,179,14,23,196,2,11,12,252,22, +176,9,2,27,2,33,36,23,200,2,23,201,2,28,28,248,22,130,7,23,197, +2,10,248,22,183,7,23,197,2,12,252,22,176,9,2,27,2,45,37,23,200, +2,23,201,2,90,159,39,11,89,161,39,36,11,248,22,177,14,23,199,2,86, +94,23,195,1,86,94,28,192,12,250,22,177,9,2,27,2,46,23,201,2,249, +22,7,194,195,27,249,22,166,14,249,22,131,8,250,22,156,15,0,9,35,114, +120,35,34,91,46,93,34,248,22,162,14,23,203,1,6,1,1,95,28,248,22, +130,7,23,202,2,249,22,145,8,23,203,1,8,63,23,201,1,28,248,22,157, +14,23,199,2,248,22,158,14,23,199,1,86,94,23,198,1,247,22,159,14,28, +248,22,156,14,194,249,22,174,14,195,194,192,249,247,22,161,5,194,11,249,247, +22,161,5,194,11,27,247,22,136,15,249,80,159,39,40,38,28,23,195,2,27, +248,22,150,8,2,47,28,192,192,2,43,2,43,27,28,23,196,1,250,22,174, +14,248,22,132,15,2,48,247,22,148,8,2,49,11,27,248,80,159,42,8,29, +39,250,22,87,9,248,22,83,248,22,132,15,2,40,9,28,193,249,22,73,195, 194,192,27,247,22,136,15,249,80,159,39,40,38,28,23,195,2,27,248,22,150, -8,2,45,28,192,192,2,41,2,41,27,28,23,196,1,250,22,174,14,248,22, -132,15,2,46,247,22,148,8,2,47,11,27,248,80,159,42,8,30,39,250,22, -87,23,203,1,248,22,83,248,22,132,15,2,38,23,204,1,28,193,249,22,73, -195,194,192,86,94,249,22,183,6,247,22,157,5,195,248,22,144,6,249,22,128, -4,36,249,22,176,3,197,198,27,28,23,197,2,86,95,23,196,1,23,195,1, -23,197,1,86,94,23,197,1,27,248,22,132,15,2,31,27,250,80,159,42,39, -39,23,197,1,11,11,27,248,22,131,4,23,199,1,27,28,23,194,2,23,194, -1,86,94,23,194,1,36,27,248,22,131,4,23,202,1,27,28,23,194,2,23, -194,1,86,94,23,194,1,36,249,22,188,5,23,199,1,20,20,95,88,163,8, -36,36,48,11,9,224,4,2,33,106,23,195,1,23,197,1,27,248,22,173,5, -23,195,1,248,80,159,39,8,31,39,193,159,36,20,113,159,36,16,1,11,16, -0,20,26,141,2,1,2,1,29,11,11,11,11,11,10,43,80,158,36,36,20, -113,159,40,16,28,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9, -2,10,2,11,2,12,2,13,2,14,2,15,30,2,18,76,102,105,110,100,45, -108,105,110,107,115,45,112,97,116,104,33,4,30,2,19,1,20,112,97,114,97, -109,101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,6,30,2,19,1, -23,101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97,116, -105,111,110,3,2,20,2,21,2,22,30,2,18,1,21,101,120,99,101,112,116, -105,111,110,45,104,97,110,100,108,101,114,45,107,101,121,2,2,23,2,24,2, -25,2,26,2,27,2,28,2,29,16,0,37,39,36,16,0,36,16,12,2,8, -2,7,2,3,2,24,2,22,2,20,2,15,2,21,2,23,2,13,2,12,2, -14,48,11,11,11,16,12,2,11,2,9,2,29,2,10,2,5,2,28,2,27, -2,4,2,26,2,6,2,25,2,2,16,12,11,11,11,11,11,11,11,11,11, -11,11,11,16,12,2,11,2,9,2,29,2,10,2,5,2,28,2,27,2,4, -2,26,2,6,2,25,2,2,48,48,37,12,11,11,16,0,16,0,16,0,36, -36,11,12,11,11,16,0,16,0,16,0,36,36,16,28,20,15,16,2,88,163, -8,36,37,51,16,2,8,240,0,128,0,0,8,240,1,128,0,0,2,30,223, -0,33,48,80,159,36,8,31,39,20,15,16,2,88,163,8,36,37,56,16,2, -44,8,240,0,64,0,0,2,30,223,0,33,49,80,159,36,8,30,39,20,15, -16,2,88,163,8,36,37,51,16,2,44,8,128,128,2,30,223,0,33,50,80, -159,36,8,29,39,20,15,16,2,88,163,8,36,37,51,16,2,44,8,128,64, -2,30,223,0,33,51,80,159,36,8,28,39,20,15,16,2,32,0,88,163,36, -37,45,11,2,2,222,33,52,80,159,36,36,37,20,15,16,2,249,22,132,7, -7,92,7,92,80,159,36,37,37,20,15,16,2,88,163,36,37,54,38,2,4, -223,0,33,53,80,159,36,38,37,20,15,16,2,20,25,96,2,5,88,163,8, -36,39,8,24,52,9,223,0,33,60,88,163,36,38,47,44,9,223,0,33,61, -88,163,36,37,46,44,9,223,0,33,62,80,159,36,39,37,20,15,16,2,27, -248,22,140,15,248,22,144,8,27,28,249,22,140,9,247,22,152,8,2,33,6, -1,1,59,6,1,1,58,250,22,178,7,6,14,14,40,91,94,126,97,93,42, -41,126,97,40,46,42,41,23,196,2,23,196,1,88,163,8,36,38,48,11,2, -6,223,0,33,66,80,159,36,40,37,20,15,16,2,32,0,88,163,8,36,38, -50,11,2,7,222,33,67,80,159,36,41,37,20,15,16,2,32,0,88,163,8, -36,39,51,11,2,8,222,33,69,80,159,36,42,37,20,15,16,2,88,163,45, -38,51,8,128,4,2,9,223,0,33,72,80,159,36,43,37,20,15,16,2,88, -163,45,39,52,8,128,4,2,11,223,0,33,75,80,159,36,45,37,20,15,16, -2,248,22,132,15,70,108,105,110,107,115,45,102,105,108,101,80,159,36,46,37, -20,15,16,2,247,22,133,2,80,158,36,47,20,15,16,2,2,76,80,158,36, -48,20,15,16,2,248,80,159,37,50,37,88,163,36,36,49,8,240,8,128,1, -0,9,223,1,33,77,80,159,36,49,37,20,15,16,2,247,22,133,2,80,158, -36,53,20,15,16,2,2,76,80,158,36,54,20,15,16,2,88,163,36,37,44, -8,240,0,188,23,0,2,22,223,0,33,88,80,159,36,55,37,20,15,16,2, -88,163,36,38,56,8,240,0,0,32,0,2,23,223,0,33,90,80,159,36,57, -37,20,15,16,2,88,163,36,41,8,24,8,240,0,32,40,0,2,10,223,0, -33,97,80,159,36,44,37,20,15,16,2,32,0,88,163,36,39,50,11,2,24, -222,33,98,80,159,36,58,37,20,15,16,2,32,0,88,163,36,38,53,11,2, -25,222,33,99,80,159,36,59,37,20,15,16,2,32,0,88,163,36,38,54,11, -2,26,222,33,100,80,159,36,8,24,37,20,15,16,2,20,27,158,32,0,88, -163,36,37,44,11,2,27,222,33,101,32,0,88,163,36,37,44,11,2,27,222, -33,102,80,159,36,8,25,37,20,15,16,2,20,25,96,2,28,88,163,36,36, -53,16,2,52,8,128,64,9,223,0,33,103,88,163,36,37,54,16,2,52,8, -128,128,9,223,0,33,104,88,163,36,38,55,16,2,52,8,240,0,64,0,0, -9,223,0,33,105,80,159,36,8,26,37,20,15,16,2,88,163,8,36,39,54, -16,2,44,8,240,0,128,0,0,2,29,223,0,33,107,80,159,36,8,27,37, -95,29,94,2,16,68,35,37,107,101,114,110,101,108,11,29,94,2,16,69,35, -37,109,105,110,45,115,116,120,11,2,18,9,9,9,36,0}; - EVAL_ONE_SIZED_STR((char *)expr, 10389); +8,2,47,28,192,192,2,43,2,43,27,28,23,196,1,250,22,174,14,248,22, +132,15,2,48,247,22,148,8,2,49,11,27,248,80,159,42,8,30,39,250,22, +87,23,203,1,248,22,83,248,22,132,15,2,40,9,28,193,249,22,73,195,194, +192,27,247,22,136,15,249,80,159,39,40,38,28,23,195,2,27,248,22,150,8, +2,47,28,192,192,2,43,2,43,27,28,23,196,1,250,22,174,14,248,22,132, +15,2,48,247,22,148,8,2,49,11,27,248,80,159,42,8,31,39,250,22,87, +23,203,1,248,22,83,248,22,132,15,2,40,23,204,1,28,193,249,22,73,195, +194,192,86,94,249,22,183,6,247,22,157,5,195,248,22,144,6,249,22,128,4, +36,249,22,176,3,197,198,27,28,23,197,2,86,95,23,196,1,23,195,1,23, +197,1,86,94,23,197,1,27,248,22,132,15,2,32,27,250,80,159,42,39,39, +23,197,1,11,11,27,248,22,131,4,23,199,1,27,28,23,194,2,23,194,1, +86,94,23,194,1,36,27,248,22,131,4,23,202,1,27,28,23,194,2,23,194, +1,86,94,23,194,1,36,249,22,188,5,23,199,1,20,20,95,88,163,8,36, +36,48,11,9,224,4,2,33,107,23,195,1,23,197,1,27,248,22,173,5,23, +195,1,248,80,159,39,8,32,39,193,159,36,20,113,159,36,16,1,11,16,0, +20,26,141,2,1,2,1,29,11,11,11,11,11,10,43,80,158,36,36,20,113, +159,40,16,29,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2, +10,2,11,2,12,2,13,2,14,2,15,2,16,30,2,19,76,102,105,110,100, +45,108,105,110,107,115,45,112,97,116,104,33,4,30,2,20,1,20,112,97,114, +97,109,101,116,101,114,105,122,97,116,105,111,110,45,107,101,121,6,30,2,20, +1,23,101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105,122,97, +116,105,111,110,3,2,21,2,22,2,23,30,2,19,1,21,101,120,99,101,112, +116,105,111,110,45,104,97,110,100,108,101,114,45,107,101,121,2,2,24,2,25, +2,26,2,27,2,28,2,29,2,30,16,0,37,39,36,16,0,36,16,13,2, +8,2,9,2,7,2,3,2,25,2,23,2,21,2,16,2,22,2,24,2,14, +2,13,2,15,49,11,11,11,16,12,2,12,2,10,2,30,2,11,2,5,2, +29,2,28,2,4,2,27,2,6,2,26,2,2,16,12,11,11,11,11,11,11, +11,11,11,11,11,11,16,12,2,12,2,10,2,30,2,11,2,5,2,29,2, +28,2,4,2,27,2,6,2,26,2,2,48,48,37,12,11,11,16,0,16,0, +16,0,36,36,11,12,11,11,16,0,16,0,16,0,36,36,16,29,20,15,16, +2,88,163,8,36,37,51,16,4,36,39,37,36,2,31,223,0,33,50,80,159, +36,8,32,39,20,15,16,2,88,163,8,36,37,56,16,2,44,8,240,0,128, +0,0,2,31,223,0,33,51,80,159,36,8,31,39,20,15,16,2,88,163,8, +36,37,51,16,2,44,8,240,0,64,0,0,2,31,223,0,33,52,80,159,36, +8,30,39,20,15,16,2,88,163,8,36,37,51,16,2,44,8,128,128,2,31, +223,0,33,53,80,159,36,8,29,39,20,15,16,2,32,0,88,163,36,37,45, +11,2,2,222,33,54,80,159,36,36,37,20,15,16,2,249,22,132,7,7,92, +7,92,80,159,36,37,37,20,15,16,2,88,163,36,37,54,38,2,4,223,0, +33,55,80,159,36,38,37,20,15,16,2,20,25,96,2,5,88,163,8,36,39, +8,24,52,9,223,0,33,62,88,163,36,38,47,44,9,223,0,33,63,88,163, +36,37,46,44,9,223,0,33,64,80,159,36,39,37,20,15,16,2,27,248,22, +140,15,248,22,144,8,27,28,249,22,140,9,247,22,152,8,2,34,6,1,1, +59,6,1,1,58,250,22,178,7,6,14,14,40,91,94,126,97,93,42,41,126, +97,40,46,42,41,23,196,2,23,196,1,88,163,8,36,38,48,11,2,6,223, +0,33,68,80,159,36,40,37,20,15,16,2,32,0,88,163,8,36,38,50,11, +2,7,222,33,69,80,159,36,41,37,20,15,16,2,32,0,88,163,8,36,39, +51,11,2,8,222,33,71,80,159,36,42,37,20,15,16,2,32,0,88,163,8, +36,38,46,11,2,9,222,33,72,80,159,36,43,37,20,15,16,2,88,163,45, +39,52,8,128,8,2,10,223,0,33,74,80,159,36,44,37,20,15,16,2,88, +163,45,40,53,8,128,8,2,12,223,0,33,76,80,159,36,46,37,20,15,16, +2,248,22,132,15,70,108,105,110,107,115,45,102,105,108,101,80,159,36,47,37, +20,15,16,2,247,22,133,2,80,158,36,48,20,15,16,2,2,77,80,158,36, +49,20,15,16,2,248,80,159,37,51,37,88,163,36,36,49,8,240,8,0,3, +0,9,223,1,33,78,80,159,36,50,37,20,15,16,2,247,22,133,2,80,158, +36,54,20,15,16,2,2,77,80,158,36,55,20,15,16,2,88,163,36,37,44, +8,240,0,120,47,0,2,23,223,0,33,89,80,159,36,56,37,20,15,16,2, +88,163,36,38,56,8,240,0,0,64,0,2,24,223,0,33,91,80,159,36,58, +37,20,15,16,2,88,163,36,40,59,8,240,0,64,80,0,2,11,223,0,33, +98,80,159,36,45,37,20,15,16,2,32,0,88,163,36,39,50,11,2,25,222, +33,99,80,159,36,59,37,20,15,16,2,32,0,88,163,36,38,53,11,2,26, +222,33,100,80,159,36,8,24,37,20,15,16,2,32,0,88,163,36,38,54,11, +2,27,222,33,101,80,159,36,8,25,37,20,15,16,2,20,27,158,32,0,88, +163,36,37,44,11,2,28,222,33,102,32,0,88,163,36,37,44,11,2,28,222, +33,103,80,159,36,8,26,37,20,15,16,2,20,25,96,2,29,88,163,36,36, +53,16,2,52,8,128,128,9,223,0,33,104,88,163,36,37,54,16,2,52,8, +240,0,64,0,0,9,223,0,33,105,88,163,36,38,55,16,2,52,8,240,0, +128,0,0,9,223,0,33,106,80,159,36,8,27,37,20,15,16,2,88,163,8, +36,39,54,16,4,44,36,37,36,2,30,223,0,33,108,80,159,36,8,28,37, +95,29,94,2,17,68,35,37,107,101,114,110,101,108,11,29,94,2,17,69,35, +37,109,105,110,45,115,116,120,11,2,19,9,9,9,36,0}; + EVAL_ONE_SIZED_STR((char *)expr, 10431); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,50,46,48,46,54,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,12,0,0,0,1,0,0,15,0,40,0,57, -0,75,0,97,0,120,0,140,0,162,0,169,0,176,0,183,0,0,0,175,1, -0,0,74,35,37,112,108,97,99,101,45,115,116,114,117,99,116,1,23,115,116, -114,117,99,116,58,84,72,45,112,108,97,99,101,45,99,104,97,110,110,101,108, -76,84,72,45,112,108,97,99,101,45,99,104,97,110,110,101,108,77,84,72,45, -112,108,97,99,101,45,99,104,97,110,110,101,108,63,1,20,84,72,45,112,108, -97,99,101,45,99,104,97,110,110,101,108,45,114,101,102,1,21,84,72,45,112, -108,97,99,101,45,99,104,97,110,110,101,108,45,115,101,116,33,79,84,72,45, -112,108,97,99,101,45,99,104,97,110,110,101,108,45,105,110,1,20,84,72,45, -112,108,97,99,101,45,99,104,97,110,110,101,108,45,111,117,116,249,80,158,38, -39,195,36,249,80,158,38,39,195,36,249,80,158,38,39,195,37,159,36,20,113, -159,36,16,1,11,16,0,20,26,141,2,1,2,1,29,11,11,11,11,11,10, -45,80,158,36,36,20,113,159,36,16,7,2,2,2,3,2,4,2,5,2,6, -2,7,2,8,16,0,37,39,36,16,0,36,16,2,2,5,2,6,38,11,11, -11,16,5,2,3,2,7,2,8,2,4,2,2,16,5,11,11,11,11,11,16, -5,2,3,2,7,2,8,2,4,2,2,41,41,37,12,11,11,16,0,16,0, -16,0,36,36,11,12,11,11,16,0,16,0,16,0,36,36,16,2,20,15,16, -6,253,22,181,10,2,3,11,38,36,11,248,22,83,249,22,73,22,169,10,88, -163,36,37,45,44,9,223,9,33,9,80,159,36,36,37,80,159,36,37,37,80, -159,36,38,37,80,159,36,39,37,80,159,36,40,37,20,15,16,3,249,22,7, -88,163,36,37,45,44,9,223,2,33,10,88,163,36,37,45,44,9,223,2,33, -11,80,159,36,41,37,80,159,36,42,37,93,29,94,65,113,117,111,116,101,68, -35,37,107,101,114,110,101,108,11,9,9,9,36,0}; - EVAL_ONE_SIZED_STR((char *)expr, 496); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,53,46,50,46,48,46,57,48,49,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,1,0,0,15,0,40, +0,57,0,75,0,97,0,120,0,140,0,162,0,169,0,176,0,183,0,0,0, +175,1,0,0,74,35,37,112,108,97,99,101,45,115,116,114,117,99,116,1,23, +115,116,114,117,99,116,58,84,72,45,112,108,97,99,101,45,99,104,97,110,110, +101,108,76,84,72,45,112,108,97,99,101,45,99,104,97,110,110,101,108,77,84, +72,45,112,108,97,99,101,45,99,104,97,110,110,101,108,63,1,20,84,72,45, +112,108,97,99,101,45,99,104,97,110,110,101,108,45,114,101,102,1,21,84,72, +45,112,108,97,99,101,45,99,104,97,110,110,101,108,45,115,101,116,33,79,84, +72,45,112,108,97,99,101,45,99,104,97,110,110,101,108,45,105,110,1,20,84, +72,45,112,108,97,99,101,45,99,104,97,110,110,101,108,45,111,117,116,249,80, +158,38,39,195,36,249,80,158,38,39,195,36,249,80,158,38,39,195,37,159,36, +20,113,159,36,16,1,11,16,0,20,26,141,2,1,2,1,29,11,11,11,11, +11,10,45,80,158,36,36,20,113,159,36,16,7,2,2,2,3,2,4,2,5, +2,6,2,7,2,8,16,0,37,39,36,16,0,36,16,2,2,5,2,6,38, +11,11,11,16,5,2,3,2,7,2,8,2,4,2,2,16,5,11,11,11,11, +11,16,5,2,3,2,7,2,8,2,4,2,2,41,41,37,12,11,11,16,0, +16,0,16,0,36,36,11,12,11,11,16,0,16,0,16,0,36,36,16,2,20, +15,16,6,253,22,181,10,2,3,11,38,36,11,248,22,83,249,22,73,22,169, +10,88,163,36,37,45,44,9,223,9,33,9,80,159,36,36,37,80,159,36,37, +37,80,159,36,38,37,80,159,36,39,37,80,159,36,40,37,20,15,16,3,249, +22,7,88,163,36,37,45,44,9,223,2,33,10,88,163,36,37,45,44,9,223, +2,33,11,80,159,36,41,37,80,159,36,42,37,93,29,94,65,113,117,111,116, +101,68,35,37,107,101,114,110,101,108,11,9,9,9,36,0}; + EVAL_ONE_SIZED_STR((char *)expr, 498); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,50,46,48,46,54,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,70,0,0,0,1,0,0,7,0,18,0,45, -0,51,0,64,0,73,0,80,0,102,0,124,0,150,0,158,0,170,0,185,0, -201,0,219,0,239,0,251,0,11,1,34,1,46,1,77,1,84,1,89,1,94, -1,100,1,105,1,110,1,119,1,124,1,128,1,139,1,146,1,149,1,157,1, -166,1,174,1,231,1,78,2,99,2,120,2,150,2,180,2,238,2,40,3,89, -3,138,3,68,9,119,9,182,9,201,9,215,9,117,10,130,10,8,11,50,12, -173,12,179,12,193,12,220,12,240,12,39,13,49,13,136,13,138,13,213,13,172, -19,225,19,249,19,17,20,0,0,143,23,0,0,66,35,37,98,111,111,116,70, -100,108,108,45,115,117,102,102,105,120,1,25,100,101,102,97,117,108,116,45,108, -111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,65,113,117,111,116, -101,29,94,2,4,67,35,37,117,116,105,108,115,11,68,35,37,112,97,114,97, -109,122,29,94,2,4,2,6,11,1,20,112,97,114,97,109,101,116,101,114,105, -122,97,116,105,111,110,45,107,101,121,1,20,100,101,102,97,117,108,116,45,114, -101,97,100,101,114,45,103,117,97,114,100,1,24,45,109,111,100,117,108,101,45, -104,97,115,104,45,116,97,98,108,101,45,116,97,98,108,101,67,67,65,67,72, -69,45,78,71,45,112,97,116,104,45,99,97,99,104,101,74,112,97,116,104,45, -99,97,99,104,101,45,103,101,116,75,112,97,116,104,45,99,97,99,104,101,45, -115,101,116,33,77,45,108,111,97,100,105,110,103,45,102,105,108,101,110,97,109, -101,79,45,108,111,97,100,105,110,103,45,112,114,111,109,112,116,45,116,97,103, -71,45,112,114,101,118,45,114,101,108,116,111,75,45,112,114,101,118,45,114,101, -108,116,111,45,100,105,114,1,21,115,112,108,105,116,45,114,101,108,97,116,105, -118,101,45,115,116,114,105,110,103,71,111,114,105,103,45,112,97,114,97,109,122, -1,29,115,116,97,110,100,97,114,100,45,109,111,100,117,108,101,45,110,97,109, -101,45,114,101,115,111,108,118,101,114,29,94,2,4,2,6,11,64,98,111,111, -116,64,115,101,97,108,5,4,46,114,107,116,64,115,97,109,101,5,3,46,122, -111,6,6,6,110,97,116,105,118,101,64,108,111,111,112,63,108,105,98,6,8, -8,109,97,105,110,46,114,107,116,6,4,4,46,114,107,116,6,0,0,67,105, -103,110,111,114,101,100,249,22,14,195,80,159,38,49,38,249,80,159,38,52,39, -195,10,90,159,39,11,89,161,39,36,11,248,22,177,14,197,86,95,23,195,1, -23,193,1,28,249,22,144,15,0,11,35,114,120,34,91,46,93,115,115,36,34, -248,22,161,14,23,197,1,249,80,159,41,56,39,198,2,25,196,27,28,23,195, -2,28,249,22,140,9,23,197,2,80,158,39,50,86,94,23,195,1,80,158,37, -51,27,248,22,139,5,23,197,2,28,248,22,156,14,23,194,2,90,159,39,11, -89,161,39,36,11,248,22,177,14,23,197,1,86,95,20,18,159,11,80,158,41, -50,198,20,18,159,11,80,158,41,51,192,192,11,11,28,23,193,2,192,86,94, -23,193,1,27,247,22,162,5,28,192,192,247,22,133,15,250,22,174,14,23,197, -1,23,199,1,249,80,159,43,39,39,23,198,1,2,27,250,22,174,14,23,197, -1,23,199,1,249,80,159,43,39,39,23,198,1,2,27,252,22,174,14,23,199, -1,23,201,1,2,28,247,22,153,8,249,80,159,45,39,39,23,200,1,80,159, -45,36,38,252,22,174,14,23,199,1,23,201,1,2,28,247,22,153,8,249,80, -159,45,39,39,23,200,1,80,159,45,36,38,27,252,22,174,14,23,200,1,23, -202,1,2,28,247,22,153,8,249,80,159,46,39,39,23,201,1,80,159,46,36, -38,27,250,22,191,14,196,11,32,0,88,163,8,36,36,41,11,9,222,11,28, -192,249,22,73,195,194,11,27,252,22,174,14,23,200,1,23,202,1,2,28,247, -22,153,8,249,80,159,46,39,39,23,201,1,80,159,46,36,38,27,250,22,191, -14,196,11,32,0,88,163,8,36,36,41,11,9,222,11,28,192,249,22,73,195, -194,11,27,250,22,174,14,23,198,1,23,200,1,249,80,159,44,39,39,23,199, -1,2,27,27,250,22,191,14,196,11,32,0,88,163,8,36,36,41,11,9,222, -11,28,192,249,22,73,195,194,11,27,250,22,174,14,23,198,1,23,200,1,249, -80,159,44,39,39,23,199,1,2,27,27,250,22,191,14,196,11,32,0,88,163, -8,36,36,41,11,9,222,11,28,192,249,22,73,195,194,11,86,94,28,248,80, -159,37,38,39,23,195,2,12,250,22,176,9,77,108,111,97,100,47,117,115,101, -45,99,111,109,112,105,108,101,100,6,25,25,112,97,116,104,32,111,114,32,118, -97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,23,197,2,90,159, -46,11,89,161,37,36,11,28,248,22,180,14,23,205,2,23,204,2,27,247,22, -162,5,28,23,193,2,249,22,181,14,23,207,2,23,195,1,23,205,2,89,161, -39,37,11,248,22,177,14,23,205,1,86,94,23,196,1,89,161,38,40,11,28, -23,205,2,27,248,22,161,14,23,197,2,27,248,22,188,7,23,195,2,28,28, -249,22,188,3,23,195,2,40,249,22,191,7,2,25,249,22,130,8,23,198,2, -249,22,176,3,23,199,2,40,11,249,22,7,23,199,2,248,22,165,14,249,22, -131,8,250,22,130,8,23,202,1,36,249,22,176,3,23,203,1,40,5,3,46, -115,115,249,22,7,23,199,2,11,249,22,7,23,197,2,11,89,161,37,42,11, -28,249,22,140,9,23,199,2,23,197,2,23,193,2,249,22,174,14,23,196,2, -23,199,2,89,161,37,43,11,28,23,198,2,28,249,22,140,9,23,200,2,23, -197,1,23,193,1,86,94,23,193,1,249,22,174,14,23,196,2,23,200,2,86, -94,23,195,1,11,89,161,37,44,11,28,249,22,140,9,23,196,2,68,114,101, -108,97,116,105,118,101,86,94,23,194,1,2,26,23,194,1,89,161,37,45,11, -247,22,135,15,27,250,22,191,14,23,203,2,11,32,0,88,163,8,36,36,41, -11,9,222,11,27,28,23,194,2,249,22,73,23,203,2,23,196,1,86,94,23, -194,1,11,27,28,23,203,2,28,23,194,2,11,27,250,22,191,14,23,207,2, -11,32,0,88,163,8,36,36,41,11,9,222,11,28,192,249,22,73,23,206,2, -194,11,11,27,28,23,195,2,23,195,2,23,194,2,27,88,163,36,37,50,44, -62,122,111,225,15,13,9,33,39,27,88,163,36,37,50,44,66,97,108,116,45, -122,111,225,16,14,11,33,40,27,88,163,36,37,52,45,9,225,17,15,11,33, -41,27,88,163,36,37,52,45,9,225,18,16,13,33,42,27,28,23,200,2,23, -200,2,248,22,138,9,23,200,2,27,28,23,208,2,28,23,200,2,86,94,23, -201,1,23,200,2,248,22,138,9,23,202,1,11,27,28,23,195,2,28,23,197, -1,27,249,22,5,88,163,8,36,37,53,45,9,225,24,22,18,33,43,23,216, -2,27,28,23,202,2,11,193,28,192,192,28,193,28,23,202,2,28,249,22,188, -3,248,22,75,196,248,22,75,23,205,2,193,11,11,11,11,86,94,23,197,1, -11,28,23,193,2,86,105,23,213,1,23,211,1,23,210,1,23,209,1,23,208, -1,23,201,1,23,200,1,23,199,1,23,198,1,23,196,1,23,195,1,23,194, -1,20,13,159,80,159,57,40,37,250,80,159,8,24,41,37,249,22,27,11,80, -159,8,26,40,37,22,182,4,11,20,13,159,80,159,57,40,37,250,80,159,8, -24,41,37,249,22,27,11,80,159,8,26,40,37,22,162,5,28,248,22,156,14, -23,216,2,23,215,1,86,94,23,215,1,247,22,133,15,249,247,22,139,15,248, -22,74,195,23,25,86,94,23,193,1,27,28,23,195,2,28,23,197,1,27,249, -22,5,88,163,8,36,37,53,45,9,225,25,23,20,33,44,23,217,2,27,28, -23,204,2,11,193,28,192,192,28,193,28,203,28,249,22,188,3,248,22,75,196, -248,22,75,206,193,11,11,11,11,86,94,23,197,1,11,28,23,193,2,86,102, -23,214,1,23,211,1,23,210,1,23,209,1,23,201,1,23,200,1,23,199,1, -23,196,1,23,195,1,20,13,159,80,159,58,40,37,250,80,159,8,25,41,37, -249,22,27,11,80,159,8,27,40,37,22,182,4,23,215,1,20,13,159,80,159, -58,40,37,250,80,159,8,25,41,37,249,22,27,11,80,159,8,27,40,37,22, -162,5,28,248,22,156,14,23,217,2,23,216,1,86,94,23,216,1,247,22,133, -15,249,247,22,139,15,248,22,74,195,23,26,86,94,23,193,1,27,28,23,197, -2,28,23,201,1,27,249,22,5,20,20,94,88,163,8,36,37,51,44,9,225, -26,24,20,33,45,23,213,1,23,218,2,27,28,23,204,2,11,193,28,192,192, -28,193,28,23,204,2,28,249,22,188,3,248,22,75,196,248,22,75,23,207,2, -193,11,11,11,86,94,23,210,1,11,86,94,23,201,1,11,28,23,193,2,86, -101,23,215,1,23,213,1,23,212,1,23,211,1,23,202,1,23,200,1,23,197, -1,23,196,1,20,13,159,80,159,59,40,37,250,80,159,8,26,41,37,249,22, -27,11,80,159,8,28,40,37,22,182,4,11,20,13,159,80,159,59,40,37,250, -80,159,8,26,41,37,249,22,27,11,80,159,8,28,40,37,22,162,5,28,248, -22,156,14,23,218,2,23,217,1,86,94,23,217,1,247,22,133,15,249,247,22, -160,5,248,22,74,195,23,27,86,94,23,193,1,27,28,23,197,1,28,23,201, -1,27,249,22,5,20,20,94,88,163,8,36,37,51,44,9,225,27,25,22,33, -46,23,215,1,23,219,1,27,28,23,205,2,11,193,28,192,192,28,193,28,204, -28,249,22,188,3,248,22,75,196,248,22,75,23,15,193,11,11,11,86,95,23, -216,1,23,212,1,11,86,94,23,201,1,11,28,23,193,2,86,95,23,213,1, -23,198,1,20,13,159,80,159,8,24,40,37,250,80,159,8,27,41,37,249,22, -27,11,80,159,8,29,40,37,22,182,4,23,217,1,20,13,159,80,159,8,24, -40,37,250,80,159,8,27,41,37,249,22,27,11,80,159,8,29,40,37,22,162, -5,28,248,22,156,14,23,219,2,23,218,1,86,94,23,218,1,247,22,133,15, -249,247,22,160,5,248,22,74,195,23,28,86,94,23,193,1,27,28,23,199,2, -86,94,23,215,1,23,214,1,86,94,23,214,1,23,215,1,20,13,159,80,159, -8,25,40,37,250,80,159,8,28,41,37,249,22,27,11,80,159,8,30,40,37, -22,182,4,28,23,30,28,23,202,1,11,195,86,94,23,202,1,11,20,13,159, + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,53,46,50,46,48,46,57,48,49,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,1,0,0,7,0,18, +0,45,0,51,0,64,0,73,0,80,0,102,0,124,0,150,0,158,0,170,0, +185,0,201,0,219,0,239,0,251,0,11,1,34,1,46,1,77,1,84,1,89, +1,94,1,100,1,105,1,110,1,119,1,124,1,128,1,139,1,146,1,149,1, +157,1,166,1,174,1,231,1,78,2,99,2,120,2,150,2,180,2,238,2,40, +3,89,3,138,3,68,9,119,9,182,9,201,9,215,9,117,10,130,10,8,11, +50,12,173,12,179,12,233,12,4,13,24,13,79,13,89,13,176,13,178,13,253, +13,186,19,239,19,7,20,31,20,0,0,157,23,0,0,66,35,37,98,111,111, +116,70,100,108,108,45,115,117,102,102,105,120,1,25,100,101,102,97,117,108,116, +45,108,111,97,100,47,117,115,101,45,99,111,109,112,105,108,101,100,65,113,117, +111,116,101,29,94,2,4,67,35,37,117,116,105,108,115,11,68,35,37,112,97, +114,97,109,122,29,94,2,4,2,6,11,1,20,112,97,114,97,109,101,116,101, +114,105,122,97,116,105,111,110,45,107,101,121,1,20,100,101,102,97,117,108,116, +45,114,101,97,100,101,114,45,103,117,97,114,100,1,24,45,109,111,100,117,108, +101,45,104,97,115,104,45,116,97,98,108,101,45,116,97,98,108,101,67,67,65, +67,72,69,45,78,71,45,112,97,116,104,45,99,97,99,104,101,74,112,97,116, +104,45,99,97,99,104,101,45,103,101,116,75,112,97,116,104,45,99,97,99,104, +101,45,115,101,116,33,77,45,108,111,97,100,105,110,103,45,102,105,108,101,110, +97,109,101,79,45,108,111,97,100,105,110,103,45,112,114,111,109,112,116,45,116, +97,103,71,45,112,114,101,118,45,114,101,108,116,111,75,45,112,114,101,118,45, +114,101,108,116,111,45,100,105,114,1,21,115,112,108,105,116,45,114,101,108,97, +116,105,118,101,45,115,116,114,105,110,103,71,111,114,105,103,45,112,97,114,97, +109,122,1,29,115,116,97,110,100,97,114,100,45,109,111,100,117,108,101,45,110, +97,109,101,45,114,101,115,111,108,118,101,114,29,94,2,4,2,6,11,64,98, +111,111,116,64,115,101,97,108,5,4,46,114,107,116,64,115,97,109,101,5,3, +46,122,111,6,6,6,110,97,116,105,118,101,64,108,111,111,112,63,108,105,98, +6,8,8,109,97,105,110,46,114,107,116,6,4,4,46,114,107,116,6,0,0, +67,105,103,110,111,114,101,100,249,22,14,195,80,159,38,49,38,249,80,159,38, +52,39,195,10,90,159,39,11,89,161,39,36,11,248,22,177,14,197,86,95,23, +195,1,23,193,1,28,249,22,144,15,0,11,35,114,120,34,91,46,93,115,115, +36,34,248,22,161,14,23,197,1,249,80,159,41,56,39,198,2,25,196,27,28, +23,195,2,28,249,22,140,9,23,197,2,80,158,39,50,86,94,23,195,1,80, +158,37,51,27,248,22,139,5,23,197,2,28,248,22,156,14,23,194,2,90,159, +39,11,89,161,39,36,11,248,22,177,14,23,197,1,86,95,20,18,159,11,80, +158,41,50,198,20,18,159,11,80,158,41,51,192,192,11,11,28,23,193,2,192, +86,94,23,193,1,27,247,22,162,5,28,192,192,247,22,133,15,250,22,174,14, +23,197,1,23,199,1,249,80,159,43,39,39,23,198,1,2,27,250,22,174,14, +23,197,1,23,199,1,249,80,159,43,39,39,23,198,1,2,27,252,22,174,14, +23,199,1,23,201,1,2,28,247,22,153,8,249,80,159,45,39,39,23,200,1, +80,159,45,36,38,252,22,174,14,23,199,1,23,201,1,2,28,247,22,153,8, +249,80,159,45,39,39,23,200,1,80,159,45,36,38,27,252,22,174,14,23,200, +1,23,202,1,2,28,247,22,153,8,249,80,159,46,39,39,23,201,1,80,159, +46,36,38,27,250,22,191,14,196,11,32,0,88,163,8,36,36,41,11,9,222, +11,28,192,249,22,73,195,194,11,27,252,22,174,14,23,200,1,23,202,1,2, +28,247,22,153,8,249,80,159,46,39,39,23,201,1,80,159,46,36,38,27,250, +22,191,14,196,11,32,0,88,163,8,36,36,41,11,9,222,11,28,192,249,22, +73,195,194,11,27,250,22,174,14,23,198,1,23,200,1,249,80,159,44,39,39, +23,199,1,2,27,27,250,22,191,14,196,11,32,0,88,163,8,36,36,41,11, +9,222,11,28,192,249,22,73,195,194,11,27,250,22,174,14,23,198,1,23,200, +1,249,80,159,44,39,39,23,199,1,2,27,27,250,22,191,14,196,11,32,0, +88,163,8,36,36,41,11,9,222,11,28,192,249,22,73,195,194,11,86,94,28, +248,80,159,37,38,39,23,195,2,12,250,22,176,9,77,108,111,97,100,47,117, +115,101,45,99,111,109,112,105,108,101,100,6,25,25,112,97,116,104,32,111,114, +32,118,97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,23,197,2, +90,159,46,11,89,161,37,36,11,28,248,22,180,14,23,205,2,23,204,2,27, +247,22,162,5,28,23,193,2,249,22,181,14,23,207,2,23,195,1,23,205,2, +89,161,39,37,11,248,22,177,14,23,205,1,86,94,23,196,1,89,161,38,40, +11,28,23,205,2,27,248,22,161,14,23,197,2,27,248,22,188,7,23,195,2, +28,28,249,22,188,3,23,195,2,40,249,22,191,7,2,25,249,22,130,8,23, +198,2,249,22,176,3,23,199,2,40,11,249,22,7,23,199,2,248,22,165,14, +249,22,131,8,250,22,130,8,23,202,1,36,249,22,176,3,23,203,1,40,5, +3,46,115,115,249,22,7,23,199,2,11,249,22,7,23,197,2,11,89,161,37, +42,11,28,249,22,140,9,23,199,2,23,197,2,23,193,2,249,22,174,14,23, +196,2,23,199,2,89,161,37,43,11,28,23,198,2,28,249,22,140,9,23,200, +2,23,197,1,23,193,1,86,94,23,193,1,249,22,174,14,23,196,2,23,200, +2,86,94,23,195,1,11,89,161,37,44,11,28,249,22,140,9,23,196,2,68, +114,101,108,97,116,105,118,101,86,94,23,194,1,2,26,23,194,1,89,161,37, +45,11,247,22,135,15,27,250,22,191,14,23,203,2,11,32,0,88,163,8,36, +36,41,11,9,222,11,27,28,23,194,2,249,22,73,23,203,2,23,196,1,86, +94,23,194,1,11,27,28,23,203,2,28,23,194,2,11,27,250,22,191,14,23, +207,2,11,32,0,88,163,8,36,36,41,11,9,222,11,28,192,249,22,73,23, +206,2,194,11,11,27,28,23,195,2,23,195,2,23,194,2,27,88,163,36,37, +50,44,62,122,111,225,15,13,9,33,39,27,88,163,36,37,50,44,66,97,108, +116,45,122,111,225,16,14,11,33,40,27,88,163,36,37,52,45,9,225,17,15, +11,33,41,27,88,163,36,37,52,45,9,225,18,16,13,33,42,27,28,23,200, +2,23,200,2,248,22,138,9,23,200,2,27,28,23,208,2,28,23,200,2,86, +94,23,201,1,23,200,2,248,22,138,9,23,202,1,11,27,28,23,195,2,28, +23,197,1,27,249,22,5,88,163,8,36,37,53,45,9,225,24,22,18,33,43, +23,216,2,27,28,23,202,2,11,193,28,192,192,28,193,28,23,202,2,28,249, +22,188,3,248,22,75,196,248,22,75,23,205,2,193,11,11,11,11,86,94,23, +197,1,11,28,23,193,2,86,105,23,213,1,23,211,1,23,210,1,23,209,1, +23,208,1,23,201,1,23,200,1,23,199,1,23,198,1,23,196,1,23,195,1, +23,194,1,20,13,159,80,159,57,40,37,250,80,159,8,24,41,37,249,22,27, +11,80,159,8,26,40,37,22,182,4,11,20,13,159,80,159,57,40,37,250,80, +159,8,24,41,37,249,22,27,11,80,159,8,26,40,37,22,162,5,28,248,22, +156,14,23,216,2,23,215,1,86,94,23,215,1,247,22,133,15,249,247,22,139, +15,248,22,74,195,23,25,86,94,23,193,1,27,28,23,195,2,28,23,197,1, +27,249,22,5,88,163,8,36,37,53,45,9,225,25,23,20,33,44,23,217,2, +27,28,23,204,2,11,193,28,192,192,28,193,28,203,28,249,22,188,3,248,22, +75,196,248,22,75,206,193,11,11,11,11,86,94,23,197,1,11,28,23,193,2, +86,102,23,214,1,23,211,1,23,210,1,23,209,1,23,201,1,23,200,1,23, +199,1,23,196,1,23,195,1,20,13,159,80,159,58,40,37,250,80,159,8,25, +41,37,249,22,27,11,80,159,8,27,40,37,22,182,4,23,215,1,20,13,159, +80,159,58,40,37,250,80,159,8,25,41,37,249,22,27,11,80,159,8,27,40, +37,22,162,5,28,248,22,156,14,23,217,2,23,216,1,86,94,23,216,1,247, +22,133,15,249,247,22,139,15,248,22,74,195,23,26,86,94,23,193,1,27,28, +23,197,2,28,23,201,1,27,249,22,5,20,20,94,88,163,8,36,37,51,44, +9,225,26,24,20,33,45,23,213,1,23,218,2,27,28,23,204,2,11,193,28, +192,192,28,193,28,23,204,2,28,249,22,188,3,248,22,75,196,248,22,75,23, +207,2,193,11,11,11,86,94,23,210,1,11,86,94,23,201,1,11,28,23,193, +2,86,101,23,215,1,23,213,1,23,212,1,23,211,1,23,202,1,23,200,1, +23,197,1,23,196,1,20,13,159,80,159,59,40,37,250,80,159,8,26,41,37, +249,22,27,11,80,159,8,28,40,37,22,182,4,11,20,13,159,80,159,59,40, +37,250,80,159,8,26,41,37,249,22,27,11,80,159,8,28,40,37,22,162,5, +28,248,22,156,14,23,218,2,23,217,1,86,94,23,217,1,247,22,133,15,249, +247,22,160,5,248,22,74,195,23,27,86,94,23,193,1,27,28,23,197,1,28, +23,201,1,27,249,22,5,20,20,94,88,163,8,36,37,51,44,9,225,27,25, +22,33,46,23,215,1,23,219,1,27,28,23,205,2,11,193,28,192,192,28,193, +28,204,28,249,22,188,3,248,22,75,196,248,22,75,23,15,193,11,11,11,86, +95,23,216,1,23,212,1,11,86,94,23,201,1,11,28,23,193,2,86,95,23, +213,1,23,198,1,20,13,159,80,159,8,24,40,37,250,80,159,8,27,41,37, +249,22,27,11,80,159,8,29,40,37,22,182,4,23,217,1,20,13,159,80,159, +8,24,40,37,250,80,159,8,27,41,37,249,22,27,11,80,159,8,29,40,37, +22,162,5,28,248,22,156,14,23,219,2,23,218,1,86,94,23,218,1,247,22, +133,15,249,247,22,160,5,248,22,74,195,23,28,86,94,23,193,1,27,28,23, +199,2,86,94,23,215,1,23,214,1,86,94,23,214,1,23,215,1,20,13,159, 80,159,8,25,40,37,250,80,159,8,28,41,37,249,22,27,11,80,159,8,30, -40,37,22,162,5,28,248,22,156,14,23,220,2,23,219,1,86,94,23,219,1, -247,22,133,15,249,247,22,160,5,194,23,29,27,249,22,160,8,80,159,39,45, -38,249,22,183,3,248,22,179,3,248,22,166,2,200,8,128,8,27,28,193,248, -22,169,2,194,11,28,192,27,249,22,96,198,195,28,192,248,22,75,193,11,11, -27,249,22,183,3,248,22,179,3,248,22,166,2,198,8,128,8,27,249,22,160, -8,80,159,40,45,38,195,27,28,193,248,22,169,2,194,11,250,22,161,8,80, -159,42,45,38,197,248,22,168,2,249,22,73,249,22,73,204,205,28,198,198,9, -0,17,35,114,120,34,94,40,46,42,63,41,47,40,46,42,41,36,34,32,51, -88,163,8,36,37,59,11,2,29,222,33,52,27,249,22,144,15,2,50,23,196, -2,28,23,193,2,86,94,23,194,1,249,22,73,248,22,98,23,196,2,27,248, -22,107,23,197,1,27,249,22,144,15,2,50,23,196,2,28,23,193,2,86,94, -23,194,1,249,22,73,248,22,98,23,196,2,27,248,22,107,23,197,1,27,249, +40,37,22,182,4,28,23,30,28,23,202,1,11,195,86,94,23,202,1,11,20, +13,159,80,159,8,25,40,37,250,80,159,8,28,41,37,249,22,27,11,80,159, +8,30,40,37,22,162,5,28,248,22,156,14,23,220,2,23,219,1,86,94,23, +219,1,247,22,133,15,249,247,22,160,5,194,23,29,27,249,22,160,8,80,159, +39,45,38,249,22,183,3,248,22,179,3,248,22,166,2,200,8,128,8,27,28, +193,248,22,169,2,194,11,28,192,27,249,22,96,198,195,28,192,248,22,75,193, +11,11,27,249,22,183,3,248,22,179,3,248,22,166,2,198,8,128,8,27,249, +22,160,8,80,159,40,45,38,195,27,28,193,248,22,169,2,194,11,250,22,161, +8,80,159,42,45,38,197,248,22,168,2,249,22,73,249,22,73,204,205,28,198, +198,9,0,17,35,114,120,34,94,40,46,42,63,41,47,40,46,42,41,36,34, +32,51,88,163,8,36,37,59,11,2,29,222,33,52,27,249,22,144,15,2,50, +23,196,2,28,23,193,2,86,94,23,194,1,249,22,73,248,22,98,23,196,2, +27,248,22,107,23,197,1,27,249,22,144,15,2,50,23,196,2,28,23,193,2, +86,94,23,194,1,249,22,73,248,22,98,23,196,2,27,248,22,107,23,197,1, +27,249,22,144,15,2,50,23,196,2,28,23,193,2,86,94,23,194,1,249,22, +73,248,22,98,23,196,2,27,248,22,107,23,197,1,27,249,22,144,15,2,50, +23,196,2,28,23,193,2,86,94,23,194,1,249,22,73,248,22,98,23,196,2, +248,2,51,248,22,107,23,197,1,248,22,83,194,248,22,83,194,248,22,83,194, +248,22,83,194,32,53,88,163,36,37,55,11,2,29,222,33,54,28,248,22,81, +248,22,75,23,195,2,249,22,7,9,248,22,74,195,90,159,38,11,89,161,38, +36,11,27,248,22,75,196,28,248,22,81,248,22,75,23,195,2,249,22,7,9, +248,22,74,195,90,159,38,11,89,161,38,36,11,27,248,22,75,196,28,248,22, +81,248,22,75,23,195,2,249,22,7,9,248,22,74,195,90,159,38,11,89,161, +38,36,11,248,2,53,248,22,75,196,249,22,7,249,22,73,248,22,74,199,196, +195,249,22,7,249,22,73,248,22,74,199,196,195,249,22,7,249,22,73,248,22, +74,199,196,195,27,27,249,22,144,15,2,50,23,197,2,28,23,193,2,86,94, +23,195,1,249,22,73,248,22,98,23,196,2,27,248,22,107,23,197,1,27,249, 22,144,15,2,50,23,196,2,28,23,193,2,86,94,23,194,1,249,22,73,248, 22,98,23,196,2,27,248,22,107,23,197,1,27,249,22,144,15,2,50,23,196, -2,28,23,193,2,86,94,23,194,1,249,22,73,248,22,98,23,196,2,248,2, -51,248,22,107,23,197,1,248,22,83,194,248,22,83,194,248,22,83,194,248,22, -83,194,32,53,88,163,36,37,55,11,2,29,222,33,54,28,248,22,81,248,22, -75,23,195,2,249,22,7,9,248,22,74,195,90,159,38,11,89,161,38,36,11, -27,248,22,75,196,28,248,22,81,248,22,75,23,195,2,249,22,7,9,248,22, -74,195,90,159,38,11,89,161,38,36,11,27,248,22,75,196,28,248,22,81,248, -22,75,23,195,2,249,22,7,9,248,22,74,195,90,159,38,11,89,161,38,36, -11,248,2,53,248,22,75,196,249,22,7,249,22,73,248,22,74,199,196,195,249, -22,7,249,22,73,248,22,74,199,196,195,249,22,7,249,22,73,248,22,74,199, -196,195,27,27,249,22,144,15,2,50,23,197,2,28,23,193,2,86,94,23,195, -1,249,22,73,248,22,98,23,196,2,27,248,22,107,23,197,1,27,249,22,144, -15,2,50,23,196,2,28,23,193,2,86,94,23,194,1,249,22,73,248,22,98, -23,196,2,27,248,22,107,23,197,1,27,249,22,144,15,2,50,23,196,2,28, -23,193,2,86,94,23,194,1,249,22,73,248,22,98,23,196,2,27,248,22,107, -23,197,1,27,249,22,144,15,2,50,23,196,2,28,23,193,2,86,94,23,194, -1,249,22,73,248,22,98,23,196,2,248,2,51,248,22,107,23,197,1,248,22, -83,194,248,22,83,194,248,22,83,194,248,22,83,195,28,23,195,1,192,28,248, -22,81,248,22,75,23,195,2,249,22,7,9,248,22,74,195,27,248,22,75,194, -90,159,38,11,89,161,38,36,11,28,248,22,81,248,22,75,23,197,2,249,22, -7,9,248,22,74,197,27,248,22,75,196,90,159,38,11,89,161,38,36,11,28, -248,22,81,248,22,75,23,197,2,249,22,7,9,248,22,74,197,90,159,38,11, -89,161,38,36,11,248,2,53,248,22,75,198,249,22,7,249,22,73,248,22,74, -201,196,195,249,22,7,249,22,73,248,22,74,202,196,195,249,22,7,249,22,73, -248,22,74,200,196,195,86,95,28,248,22,137,5,195,12,250,22,176,9,2,21, -6,20,20,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45,112,97, -116,104,197,28,24,193,2,248,24,194,1,195,86,94,23,193,1,12,27,250,22, -153,2,80,159,41,43,38,248,22,169,15,247,22,134,13,11,27,28,23,194,2, -193,86,94,23,194,1,27,247,22,133,2,86,94,250,22,151,2,80,159,43,43, -38,248,22,169,15,247,22,134,13,195,192,250,22,151,2,195,199,66,97,116,116, -97,99,104,251,211,197,198,199,10,28,192,250,22,175,9,11,196,195,248,22,173, -9,194,28,249,22,136,7,194,6,1,1,46,2,26,28,249,22,136,7,194,6, +2,28,23,193,2,86,94,23,194,1,249,22,73,248,22,98,23,196,2,27,248, +22,107,23,197,1,27,249,22,144,15,2,50,23,196,2,28,23,193,2,86,94, +23,194,1,249,22,73,248,22,98,23,196,2,248,2,51,248,22,107,23,197,1, +248,22,83,194,248,22,83,194,248,22,83,194,248,22,83,195,28,23,195,1,192, +28,248,22,81,248,22,75,23,195,2,249,22,7,9,248,22,74,195,27,248,22, +75,194,90,159,38,11,89,161,38,36,11,28,248,22,81,248,22,75,23,197,2, +249,22,7,9,248,22,74,197,27,248,22,75,196,90,159,38,11,89,161,38,36, +11,28,248,22,81,248,22,75,23,197,2,249,22,7,9,248,22,74,197,90,159, +38,11,89,161,38,36,11,248,2,53,248,22,75,198,249,22,7,249,22,73,248, +22,74,201,196,195,249,22,7,249,22,73,248,22,74,202,196,195,249,22,7,249, +22,73,248,22,74,200,196,195,86,95,28,248,22,137,5,195,12,250,22,176,9, +2,21,6,20,20,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45, +112,97,116,104,197,28,24,193,2,248,24,194,1,195,86,94,23,193,1,12,27, +250,22,153,2,80,159,41,43,38,248,22,169,15,247,22,134,13,11,27,28,23, +194,2,193,86,94,23,194,1,27,247,22,133,2,86,94,250,22,151,2,80,159, +43,43,38,248,22,169,15,247,22,134,13,195,192,250,22,151,2,195,199,66,97, +116,116,97,99,104,251,211,197,198,199,10,27,249,22,153,7,6,31,31,115,116, +97,110,100,97,114,100,45,109,111,100,117,108,101,45,110,97,109,101,45,114,101, +115,111,108,118,101,114,58,32,196,28,193,250,22,175,9,11,195,196,248,22,173, +9,193,28,249,22,136,7,194,6,1,1,46,2,26,28,249,22,136,7,194,6, 2,2,46,46,62,117,112,192,32,60,88,163,8,36,37,50,11,67,115,115,45, 62,114,107,116,222,33,61,27,248,22,133,7,194,28,249,22,188,3,194,39,28, 249,22,136,7,6,3,3,46,115,115,249,22,152,7,197,249,22,176,3,198,39, @@ -812,136 +816,135 @@ 94,2,30,6,19,19,112,108,97,110,101,116,47,114,101,115,111,108,118,101,114, 46,114,107,116,1,27,112,108,97,110,101,116,45,109,111,100,117,108,101,45,110, 97,109,101,45,114,101,115,111,108,118,101,114,12,252,212,199,200,201,202,80,158, -42,53,86,94,23,193,1,27,88,163,8,36,37,46,11,79,115,104,111,119,45, +42,53,86,94,23,193,1,27,88,163,8,36,37,47,11,79,115,104,111,119,45, 99,111,108,108,101,99,116,105,111,110,45,101,114,114,223,5,33,58,27,28,248, 22,58,23,198,2,27,248,80,159,41,46,39,249,22,73,23,201,2,247,22,134, 15,28,23,193,2,192,86,94,23,193,1,90,159,38,11,89,161,38,36,11,249, 80,159,44,52,39,248,22,64,23,203,2,11,27,28,248,22,81,23,195,2,2, -31,249,22,153,7,23,197,2,2,32,27,252,80,159,49,57,39,2,21,23,204, -1,28,248,22,81,23,201,2,23,201,1,86,94,23,201,1,248,22,74,23,201, -2,28,248,22,81,23,201,2,86,94,23,200,1,9,248,22,75,23,201,1,23, -199,2,249,22,174,14,23,195,1,23,196,1,28,248,22,130,7,23,198,2,86, -94,23,194,1,27,248,80,159,41,8,26,39,23,200,2,27,248,80,159,42,46, -39,249,22,73,23,202,2,23,197,2,28,23,193,2,192,86,94,23,193,1,90, -159,38,11,89,161,38,36,11,249,80,159,45,52,39,23,203,2,11,250,22,1, -22,174,14,23,199,1,249,22,87,249,22,2,32,0,88,163,8,36,37,44,11, -9,222,33,59,23,200,1,248,22,83,248,2,60,23,201,1,28,248,22,156,14, -23,198,2,86,94,23,194,1,28,248,22,179,14,23,198,2,248,80,159,40,8, -27,39,248,22,183,14,23,199,2,248,22,83,6,26,26,32,40,97,32,112,97, -116,104,32,109,117,115,116,32,98,101,32,97,98,115,111,108,117,116,101,41,28, -249,22,140,9,248,22,74,23,200,2,2,30,27,248,80,159,41,46,39,249,22, -73,23,201,2,247,22,134,15,28,23,193,2,192,86,94,23,193,1,90,159,39, -11,89,161,38,36,11,249,80,159,45,52,39,248,22,98,23,204,2,11,89,161, -37,38,11,28,248,22,81,248,22,100,23,203,2,28,248,22,81,23,194,2,249, -22,148,15,2,62,23,196,2,11,10,27,28,23,196,2,248,2,60,23,196,2, -28,248,22,81,23,195,2,2,31,28,249,22,148,15,2,62,23,197,2,248,2, -60,23,196,2,249,22,153,7,23,197,2,2,32,27,28,23,197,1,86,94,23, -196,1,249,22,87,28,248,22,81,248,22,100,23,207,2,21,93,6,5,5,109, -122,108,105,98,249,22,1,22,87,249,22,2,80,159,51,8,28,39,248,22,100, -23,210,2,23,197,1,28,248,22,81,23,196,2,86,94,23,195,1,248,22,83, -23,197,1,86,94,23,196,1,23,195,1,27,252,80,159,51,57,39,2,21,23, -206,1,248,22,74,23,200,2,248,22,75,23,200,1,23,200,2,249,22,174,14, -23,195,1,23,197,1,28,249,22,140,9,248,22,74,23,200,2,64,102,105,108, -101,248,80,159,40,8,27,39,248,22,183,14,249,22,181,14,248,22,185,14,248, -22,98,23,203,2,248,80,159,44,8,26,39,23,203,2,12,86,94,28,28,248, -22,156,14,23,194,2,10,248,22,155,8,23,194,2,86,94,23,199,1,12,28, -23,199,2,250,22,175,9,67,114,101,113,117,105,114,101,249,22,178,7,6,17, -17,98,97,100,32,109,111,100,117,108,101,32,112,97,116,104,126,97,28,23,198, -2,248,22,74,23,199,2,2,33,23,202,1,86,94,23,199,1,250,22,176,9, -2,21,249,22,178,7,6,13,13,109,111,100,117,108,101,32,112,97,116,104,126, -97,28,23,198,2,248,22,74,23,199,2,2,33,23,200,2,27,28,248,22,155, -8,23,195,2,249,22,160,8,23,196,2,36,249,22,183,14,248,22,184,14,23, -197,2,11,27,28,248,22,155,8,23,196,2,249,22,160,8,23,197,2,37,248, -80,159,42,58,39,23,195,2,90,159,39,11,89,161,39,36,11,28,248,22,155, -8,23,199,2,250,22,7,2,34,249,22,160,8,23,203,2,38,2,34,248,22, -177,14,23,198,2,86,95,23,195,1,23,193,1,27,28,248,22,155,8,23,200, -2,249,22,160,8,23,201,2,39,249,80,159,47,56,39,23,197,2,5,0,27, -28,248,22,155,8,23,201,2,249,22,160,8,23,202,2,40,248,22,138,5,23, -200,2,27,27,250,22,153,2,80,159,51,43,38,248,22,169,15,247,22,134,13, -11,28,23,193,2,192,86,94,23,193,1,27,247,22,133,2,86,94,250,22,151, -2,80,159,52,43,38,248,22,169,15,247,22,134,13,195,192,86,95,28,23,208, -1,27,250,22,153,2,23,197,2,197,11,28,23,193,1,12,86,94,27,27,28, -248,22,17,80,159,51,49,38,80,159,50,49,38,247,22,19,251,22,27,11,80, -159,54,48,38,9,23,197,1,27,248,22,169,15,247,22,134,13,86,94,249,22, -3,20,20,94,88,163,8,36,37,55,11,9,226,12,11,2,3,33,63,23,195, -1,23,196,2,248,28,248,22,17,80,159,52,49,38,32,0,88,163,36,37,42, -11,9,222,33,64,80,159,51,8,29,39,20,20,94,88,163,36,36,52,8,176, -64,9,228,15,11,10,6,5,2,33,65,23,195,1,250,22,151,2,23,197,1, -197,10,12,28,28,248,22,155,8,23,202,1,11,28,248,22,130,7,23,206,2, -10,28,248,22,58,23,206,2,10,28,248,22,71,23,206,2,249,22,140,9,248, -22,74,23,208,2,2,30,11,249,80,159,49,47,39,28,248,22,130,7,23,208, -2,249,22,73,23,209,1,248,80,159,52,8,26,39,23,211,1,86,94,23,208, -1,249,22,73,23,209,1,247,22,134,15,252,22,157,8,23,207,1,23,206,1, -23,204,1,23,202,1,200,12,193,86,96,20,18,159,11,80,158,36,53,248,80, -159,37,8,25,37,249,22,27,11,80,159,39,55,37,248,22,180,4,80,159,37, -54,38,248,22,161,5,80,159,37,37,39,248,22,189,13,80,159,37,42,39,20, -18,159,11,80,158,36,53,248,80,159,37,8,25,37,249,22,27,11,80,159,39, -55,37,20,18,159,11,80,158,36,53,248,80,159,37,8,25,37,249,22,27,11, -80,159,39,55,37,159,36,20,113,159,36,16,1,11,16,0,20,26,141,2,1, -2,1,29,11,11,11,11,11,10,38,80,158,36,36,20,113,159,40,16,26,2, -2,2,3,30,2,5,72,112,97,116,104,45,115,116,114,105,110,103,63,11,30, -2,5,75,112,97,116,104,45,97,100,100,45,115,117,102,102,105,120,8,30,2, -7,2,8,6,30,2,7,1,23,101,120,116,101,110,100,45,112,97,114,97,109, -101,116,101,114,105,122,97,116,105,111,110,3,2,9,2,10,2,11,2,12,2, -13,2,14,2,15,2,16,2,17,2,18,2,19,2,20,2,21,30,2,22,2, -8,6,30,2,5,79,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117, -102,102,105,120,10,30,2,5,73,102,105,110,100,45,99,111,108,45,102,105,108, -101,3,30,2,5,76,110,111,114,109,97,108,45,99,97,115,101,45,112,97,116, -104,7,2,23,2,24,30,2,22,74,114,101,112,97,114,97,109,101,116,101,114, -105,122,101,7,16,0,37,39,36,16,0,36,16,14,2,15,2,16,2,10,2, -12,2,17,2,18,2,11,2,3,2,9,2,2,2,13,2,14,2,19,2,21, -50,11,11,11,16,3,2,23,2,20,2,24,16,3,11,11,11,16,3,2,23, -2,20,2,24,39,39,37,12,11,11,16,0,16,0,16,0,36,36,11,12,11, -11,16,0,16,0,16,0,36,36,16,21,20,15,16,2,88,163,36,37,45,8, -128,128,9,223,0,33,35,80,159,36,8,29,39,20,15,16,2,88,163,8,36, -37,45,8,240,0,0,1,0,9,223,0,33,36,80,159,36,8,28,39,20,15, -16,2,88,163,36,37,49,8,240,0,0,16,0,72,112,97,116,104,45,115,115, -45,62,114,107,116,223,0,33,37,80,159,36,8,27,39,20,15,16,2,88,163, -36,37,49,8,240,0,192,0,0,67,103,101,116,45,100,105,114,223,0,33,38, -80,159,36,8,26,39,20,15,16,2,248,22,152,8,69,115,111,45,115,117,102, -102,105,120,80,159,36,36,37,20,15,16,2,88,163,36,38,8,38,8,61,2, -3,223,0,33,47,80,159,36,37,37,20,15,16,2,20,27,158,32,0,88,163, -8,36,37,42,11,2,9,222,192,32,0,88,163,8,36,37,42,11,2,9,222, -192,80,159,36,42,37,20,15,16,2,247,22,136,2,80,159,36,43,37,20,15, -16,2,8,128,8,80,159,36,44,37,20,15,16,2,249,22,156,8,8,128,8, -11,80,159,36,45,37,20,15,16,2,88,163,8,36,37,50,8,128,8,2,13, -223,0,33,48,80,159,36,46,37,20,15,16,2,88,163,8,36,38,55,8,128, -8,2,14,223,0,33,49,80,159,36,47,37,20,15,16,2,247,22,69,80,159, -36,48,37,20,15,16,2,248,22,18,74,109,111,100,117,108,101,45,108,111,97, -100,105,110,103,80,159,36,49,37,20,15,16,2,11,80,158,36,50,20,15,16, -2,11,80,158,36,51,20,15,16,2,32,0,88,163,36,38,8,25,11,2,19, -222,33,55,80,159,36,52,37,20,15,16,2,11,80,158,36,53,20,15,16,2, -27,11,20,19,158,36,90,159,37,10,89,161,37,36,10,20,25,96,2,21,88, -163,8,36,37,51,8,128,2,9,224,2,1,33,56,88,163,36,39,49,11,9, -223,0,33,57,88,163,36,40,8,28,16,2,8,176,242,8,187,241,9,224,2, -1,33,66,207,80,159,36,54,37,20,15,16,2,88,163,36,36,45,8,240,66, -0,14,2,2,23,223,0,33,67,80,159,36,59,37,20,15,16,2,20,27,158, -88,163,8,36,36,45,8,240,0,0,10,2,2,24,223,0,33,68,88,163,8, -36,36,45,8,240,0,0,10,2,2,24,223,0,33,69,80,159,36,8,24,37, -96,29,94,2,4,68,35,37,107,101,114,110,101,108,11,29,94,2,4,69,35, -37,109,105,110,45,115,116,120,11,2,5,2,22,9,9,9,36,0}; - EVAL_ONE_SIZED_STR((char *)expr, 6212); +31,249,22,153,7,23,197,2,2,32,251,80,159,47,57,39,23,202,1,28,248, +22,81,23,199,2,23,199,1,86,94,23,199,1,248,22,74,23,199,2,28,248, +22,81,23,199,2,86,94,23,198,1,9,248,22,75,23,199,1,23,197,1,28, +248,22,130,7,23,198,2,86,94,23,194,1,27,248,80,159,41,8,26,39,23, +200,2,27,248,80,159,42,46,39,249,22,73,23,202,2,23,197,2,28,23,193, +2,192,86,94,23,193,1,90,159,38,11,89,161,38,36,11,249,80,159,45,52, +39,23,203,2,11,250,22,1,22,174,14,23,199,1,249,22,87,249,22,2,32, +0,88,163,8,36,37,44,11,9,222,33,59,23,200,1,248,22,83,248,2,60, +23,201,1,28,248,22,156,14,23,198,2,86,94,23,194,1,28,248,22,179,14, +23,198,2,248,80,159,40,8,27,39,248,22,183,14,23,199,2,248,22,83,6, +26,26,32,40,97,32,112,97,116,104,32,109,117,115,116,32,98,101,32,97,98, +115,111,108,117,116,101,41,28,249,22,140,9,248,22,74,23,200,2,2,30,27, +248,80,159,41,46,39,249,22,73,23,201,2,247,22,134,15,28,23,193,2,192, +86,94,23,193,1,90,159,39,11,89,161,38,36,11,249,80,159,45,52,39,248, +22,98,23,204,2,11,89,161,37,38,11,28,248,22,81,248,22,100,23,203,2, +28,248,22,81,23,194,2,249,22,148,15,2,62,23,196,2,11,10,27,28,23, +196,2,248,2,60,23,196,2,28,248,22,81,23,195,2,2,31,28,249,22,148, +15,2,62,23,197,2,248,2,60,23,196,2,249,22,153,7,23,197,2,2,32, +27,28,23,197,1,86,94,23,196,1,249,22,87,28,248,22,81,248,22,100,23, +207,2,21,93,6,5,5,109,122,108,105,98,249,22,1,22,87,249,22,2,80, +159,51,8,28,39,248,22,100,23,210,2,23,197,1,28,248,22,81,23,196,2, +86,94,23,195,1,248,22,83,23,197,1,86,94,23,196,1,23,195,1,251,80, +159,49,57,39,23,204,1,248,22,74,23,198,2,248,22,75,23,198,1,23,198, +1,28,249,22,140,9,248,22,74,23,200,2,64,102,105,108,101,248,80,159,40, +8,27,39,248,22,183,14,249,22,181,14,248,22,185,14,248,22,98,23,203,2, +248,80,159,44,8,26,39,23,203,2,12,86,94,28,28,248,22,156,14,23,194, +2,10,248,22,155,8,23,194,2,86,94,23,199,1,12,28,23,199,2,250,22, +175,9,67,114,101,113,117,105,114,101,249,22,178,7,6,17,17,98,97,100,32, +109,111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2,248,22,74,23, +199,2,2,33,23,202,1,86,94,23,199,1,250,22,176,9,2,21,249,22,178, +7,6,13,13,109,111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2, +248,22,74,23,199,2,2,33,23,200,2,27,28,248,22,155,8,23,195,2,249, +22,160,8,23,196,2,36,249,22,183,14,248,22,184,14,23,197,2,11,27,28, +248,22,155,8,23,196,2,249,22,160,8,23,197,2,37,248,80,159,42,58,39, +23,195,2,90,159,39,11,89,161,39,36,11,28,248,22,155,8,23,199,2,250, +22,7,2,34,249,22,160,8,23,203,2,38,2,34,248,22,177,14,23,198,2, +86,95,23,195,1,23,193,1,27,28,248,22,155,8,23,200,2,249,22,160,8, +23,201,2,39,249,80,159,47,56,39,23,197,2,5,0,27,28,248,22,155,8, +23,201,2,249,22,160,8,23,202,2,40,248,22,138,5,23,200,2,27,27,250, +22,153,2,80,159,51,43,38,248,22,169,15,247,22,134,13,11,28,23,193,2, +192,86,94,23,193,1,27,247,22,133,2,86,94,250,22,151,2,80,159,52,43, +38,248,22,169,15,247,22,134,13,195,192,86,95,28,23,208,1,27,250,22,153, +2,23,197,2,197,11,28,23,193,1,12,86,94,27,27,28,248,22,17,80,159, +51,49,38,80,159,50,49,38,247,22,19,251,22,27,11,80,159,54,48,38,9, +23,197,1,27,248,22,169,15,247,22,134,13,86,94,249,22,3,20,20,94,88, +163,8,36,37,55,11,9,226,12,11,2,3,33,63,23,195,1,23,196,2,248, +28,248,22,17,80,159,52,49,38,32,0,88,163,36,37,42,11,9,222,33,64, +80,159,51,8,29,39,20,20,94,88,163,36,36,52,8,176,64,9,228,15,11, +10,6,5,2,33,65,23,195,1,250,22,151,2,23,197,1,197,10,12,28,28, +248,22,155,8,23,202,1,11,28,248,22,130,7,23,206,2,10,28,248,22,58, +23,206,2,10,28,248,22,71,23,206,2,249,22,140,9,248,22,74,23,208,2, +2,30,11,249,80,159,49,47,39,28,248,22,130,7,23,208,2,249,22,73,23, +209,1,248,80,159,52,8,26,39,23,211,1,86,94,23,208,1,249,22,73,23, +209,1,247,22,134,15,252,22,157,8,23,207,1,23,206,1,23,204,1,23,202, +1,200,12,193,86,96,20,18,159,11,80,158,36,53,248,80,159,37,8,25,37, +249,22,27,11,80,159,39,55,37,248,22,180,4,80,159,37,54,38,248,22,161, +5,80,159,37,37,39,248,22,189,13,80,159,37,42,39,20,18,159,11,80,158, +36,53,248,80,159,37,8,25,37,249,22,27,11,80,159,39,55,37,20,18,159, +11,80,158,36,53,248,80,159,37,8,25,37,249,22,27,11,80,159,39,55,37, +159,36,20,113,159,36,16,1,11,16,0,20,26,141,2,1,2,1,29,11,11, +11,11,11,10,38,80,158,36,36,20,113,159,40,16,26,2,2,2,3,30,2, +5,72,112,97,116,104,45,115,116,114,105,110,103,63,11,30,2,5,75,112,97, +116,104,45,97,100,100,45,115,117,102,102,105,120,8,30,2,7,2,8,6,30, +2,7,1,23,101,120,116,101,110,100,45,112,97,114,97,109,101,116,101,114,105, +122,97,116,105,111,110,3,2,9,2,10,2,11,2,12,2,13,2,14,2,15, +2,16,2,17,2,18,2,19,2,20,2,21,30,2,22,2,8,6,30,2,5, +79,112,97,116,104,45,114,101,112,108,97,99,101,45,115,117,102,102,105,120,10, +30,2,5,73,102,105,110,100,45,99,111,108,45,102,105,108,101,3,30,2,5, +76,110,111,114,109,97,108,45,99,97,115,101,45,112,97,116,104,7,2,23,2, +24,30,2,22,74,114,101,112,97,114,97,109,101,116,101,114,105,122,101,7,16, +0,37,39,36,16,0,36,16,14,2,15,2,16,2,10,2,12,2,17,2,18, +2,11,2,3,2,9,2,2,2,13,2,14,2,19,2,21,50,11,11,11,16, +3,2,23,2,20,2,24,16,3,11,11,11,16,3,2,23,2,20,2,24,39, +39,37,12,11,11,16,0,16,0,16,0,36,36,11,12,11,11,16,0,16,0, +16,0,36,36,16,21,20,15,16,2,88,163,36,37,45,8,128,128,9,223,0, +33,35,80,159,36,8,29,39,20,15,16,2,88,163,8,36,37,45,8,240,0, +0,1,0,9,223,0,33,36,80,159,36,8,28,39,20,15,16,2,88,163,36, +37,49,8,240,0,0,16,0,72,112,97,116,104,45,115,115,45,62,114,107,116, +223,0,33,37,80,159,36,8,27,39,20,15,16,2,88,163,36,37,49,8,240, +0,192,0,0,67,103,101,116,45,100,105,114,223,0,33,38,80,159,36,8,26, +39,20,15,16,2,248,22,152,8,69,115,111,45,115,117,102,102,105,120,80,159, +36,36,37,20,15,16,2,88,163,36,38,8,38,8,61,2,3,223,0,33,47, +80,159,36,37,37,20,15,16,2,20,27,158,32,0,88,163,8,36,37,42,11, +2,9,222,192,32,0,88,163,8,36,37,42,11,2,9,222,192,80,159,36,42, +37,20,15,16,2,247,22,136,2,80,159,36,43,37,20,15,16,2,8,128,8, +80,159,36,44,37,20,15,16,2,249,22,156,8,8,128,8,11,80,159,36,45, +37,20,15,16,2,88,163,8,36,37,50,8,128,8,2,13,223,0,33,48,80, +159,36,46,37,20,15,16,2,88,163,8,36,38,55,8,128,8,2,14,223,0, +33,49,80,159,36,47,37,20,15,16,2,247,22,69,80,159,36,48,37,20,15, +16,2,248,22,18,74,109,111,100,117,108,101,45,108,111,97,100,105,110,103,80, +159,36,49,37,20,15,16,2,11,80,158,36,50,20,15,16,2,11,80,158,36, +51,20,15,16,2,32,0,88,163,36,38,8,25,11,2,19,222,33,55,80,159, +36,52,37,20,15,16,2,11,80,158,36,53,20,15,16,2,27,11,20,19,158, +36,90,159,37,10,89,161,37,36,10,20,25,96,2,21,88,163,8,36,37,51, +8,128,2,9,224,2,1,33,56,88,163,36,39,49,11,9,223,0,33,57,88, +163,36,40,8,28,16,2,8,176,242,8,187,241,9,224,2,1,33,66,207,80, +159,36,54,37,20,15,16,2,88,163,36,36,45,8,240,66,0,14,2,2,23, +223,0,33,67,80,159,36,59,37,20,15,16,2,20,27,158,88,163,8,36,36, +45,8,240,0,0,10,2,2,24,223,0,33,68,88,163,8,36,36,45,8,240, +0,0,10,2,2,24,223,0,33,69,80,159,36,8,24,37,96,29,94,2,4, +68,35,37,107,101,114,110,101,108,11,29,94,2,4,69,35,37,109,105,110,45, +115,116,120,11,2,5,2,22,9,9,9,36,0}; + EVAL_ONE_SIZED_STR((char *)expr, 6228); } { - SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,50,46,48,46,54,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,11,0,0,0,1,0,0,10,0,16,0,29, -0,44,0,58,0,78,0,90,0,104,0,118,0,170,0,0,0,94,1,0,0, -69,35,37,98,117,105,108,116,105,110,65,113,117,111,116,101,29,94,2,2,67, -35,37,117,116,105,108,115,11,29,94,2,2,69,35,37,110,101,116,119,111,114, -107,11,29,94,2,2,68,35,37,112,97,114,97,109,122,11,29,94,2,2,74, -35,37,112,108,97,99,101,45,115,116,114,117,99,116,11,29,94,2,2,66,35, -37,98,111,111,116,11,29,94,2,2,68,35,37,101,120,112,111,98,115,11,29, -94,2,2,68,35,37,107,101,114,110,101,108,11,97,36,11,8,240,80,78,0, -0,100,159,2,3,36,36,159,2,4,36,36,159,2,5,36,36,159,2,6,36, -36,159,2,7,36,36,159,2,8,36,36,159,2,9,36,36,159,2,9,36,36, -16,0,159,36,20,113,159,36,16,1,11,16,0,20,26,141,2,1,2,1,29, -11,11,11,11,11,18,96,11,46,46,46,36,80,158,36,36,20,113,159,36,16, -0,16,0,37,39,36,16,0,36,16,0,36,11,11,11,16,0,16,0,16,0, -36,36,37,12,11,11,16,0,16,0,16,0,36,36,11,12,11,11,16,0,16, -0,16,0,36,36,16,0,104,2,9,2,8,29,94,2,2,69,35,37,102,111, -114,101,105,103,110,11,29,94,2,2,68,35,37,117,110,115,97,102,101,11,29, -94,2,2,69,35,37,102,108,102,120,110,117,109,11,2,7,2,6,2,5,2, -4,2,3,29,94,2,2,67,35,37,112,108,97,99,101,11,29,94,2,2,69, -35,37,102,117,116,117,114,101,115,11,9,9,9,36,0}; - EVAL_ONE_SIZED_STR((char *)expr, 413); + SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,9,53,46,50,46,48,46,57,48,49,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,1,0,0,10,0,16, +0,29,0,44,0,58,0,78,0,90,0,104,0,118,0,170,0,0,0,94,1, +0,0,69,35,37,98,117,105,108,116,105,110,65,113,117,111,116,101,29,94,2, +2,67,35,37,117,116,105,108,115,11,29,94,2,2,69,35,37,110,101,116,119, +111,114,107,11,29,94,2,2,68,35,37,112,97,114,97,109,122,11,29,94,2, +2,74,35,37,112,108,97,99,101,45,115,116,114,117,99,116,11,29,94,2,2, +66,35,37,98,111,111,116,11,29,94,2,2,68,35,37,101,120,112,111,98,115, +11,29,94,2,2,68,35,37,107,101,114,110,101,108,11,97,36,11,8,240,1, +79,0,0,100,159,2,3,36,36,159,2,4,36,36,159,2,5,36,36,159,2, +6,36,36,159,2,7,36,36,159,2,8,36,36,159,2,9,36,36,159,2,9, +36,36,16,0,159,36,20,113,159,36,16,1,11,16,0,20,26,141,2,1,2, +1,29,11,11,11,11,11,18,96,11,46,46,46,36,80,158,36,36,20,113,159, +36,16,0,16,0,37,39,36,16,0,36,16,0,36,11,11,11,16,0,16,0, +16,0,36,36,37,12,11,11,16,0,16,0,16,0,36,36,11,12,11,11,16, +0,16,0,16,0,36,36,16,0,104,2,9,2,8,29,94,2,2,69,35,37, +102,111,114,101,105,103,110,11,29,94,2,2,68,35,37,117,110,115,97,102,101, +11,29,94,2,2,69,35,37,102,108,102,120,110,117,109,11,2,7,2,6,2, +5,2,4,2,3,29,94,2,2,67,35,37,112,108,97,99,101,11,29,94,2, +2,69,35,37,102,117,116,117,114,101,115,11,9,9,9,36,0}; + EVAL_ONE_SIZED_STR((char *)expr, 415); } diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 7239db6207..f4055c2426 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.2.0.900" +#define MZSCHEME_VERSION "5.2.0.901" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 900 +#define MZSCHEME_VERSION_W 901 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) diff --git a/src/racket/src/startup.inc b/src/racket/src/startup.inc index 954107c5c7..a83e66b7d7 100644 --- a/src/racket/src/startup.inc +++ b/src/racket/src/startup.inc @@ -268,24 +268,25 @@ "(lambda(who collection collection-path)" "(-check-relpath who collection) " "(for-each(lambda(p)(-check-relpath who p)) collection-path)))" +"(define-values(-check-fail)" +"(lambda(who fail)" +"(unless(and(procedure? fail)" +"(procedure-arity-includes? fail 1))" +" (raise-type-error who \"procedure (arity 1)\" fail))))" "(define-values(collection-path)" -"(lambda(collection . collection-path) " +"(lambda(fail collection . collection-path) " "(-check-collection 'collection-path collection collection-path)" -"(find-col-file 'collection-path(lambda(s)" -"(raise" -"(exn:fail:filesystem s(current-continuation-marks))))" +"(-check-fail 'collection-path fail)" +"(find-col-file fail" " collection collection-path" " #f)))" "(define-values(collection-file-path)" -"(lambda(file-name collection . collection-path) " +"(lambda(fail file-name collection . collection-path) " "(-check-relpath 'collection-file-path file-name)" "(-check-collection 'collection-file-path collection collection-path)" -"(build-path" -"(find-col-file 'collection-file-path(lambda(s)" -"(raise" -"(exn:fail:filesystem s(current-continuation-marks))))" +"(-check-fail 'collection-file-path fail)" +"(find-col-file fail" " collection collection-path" -" file-name)" " file-name)))" "(define-values(user-links-path)(find-system-path 'links-file))" "(define-values(user-links-cache)(make-hasheq))" @@ -429,7 +430,7 @@ "(values name collection-path)" "(normalize-collection-reference base(cons name collection-path))))))))" "(define-values(find-col-file)" -"(lambda(who fail collection collection-path file-name)" +"(lambda(fail collection collection-path file-name)" "(let-values(((collection collection-path)" "(normalize-collection-reference collection collection-path)))" "(let((all-paths(let((sym(string->symbol(if(path? collection)" @@ -448,6 +449,9 @@ "(hash-ref ht #f null)))" " null)" "(current-library-collection-paths)))))" +"(define-values(done)" +"(lambda(p)" +"(if file-name(build-path p file-name) p)))" "(define-values(*build-path-rep)" "(lambda(p c)" "(if(path? p)" @@ -462,7 +466,7 @@ "(let cloop((paths all-paths)(found-col #f))" "(if(null? paths)" "(if found-col" -" found-col" +"(done found-col)" "(let((rest-coll" "(if(null? collection-path)" " \"\"" @@ -480,8 +484,7 @@ "(cons(car l)(filter f(cdr l)))" "(filter f(cdr l))))))" "(fail" -" (format \"~a: collection not found: ~s in any of: ~s~a\" " -" who" +" (format \"collection not found: ~s in any of: ~s~a\" " "(if(null? collection-path)" "(to-string collection)" " (string-append (to-string collection) \"/\" rest-coll))" @@ -509,9 +512,9 @@ " (string-append (substring file-name 0 (- len 4)) \".ss\")))))" "(and alt-file-name" "(file-exists?(build-path cpath alt-file-name)))))" -" cpath" +"(done cpath)" "(cloop(cdr paths)(or found-col cpath)))" -" cpath)" +"(done cpath))" "(cloop(cdr paths) found-col)))" "(cloop(cdr paths) found-col)))))))))" "(define-values(check-suffix-call)" @@ -835,12 +838,13 @@ "(current-load-relative-directory)" "(current-directory))))" "(show-collection-err(lambda(s)" +" (let ((s (string-append \"standard-module-name-resolver: \" s)))" "(if stx" "(raise-syntax-error" " #f" " s" " stx)" -"(error s))))" +"(error s)))))" "(ss->rkt(lambda(s)" "(let((len(string-length s)))" "(if(and(len . >= . 3)" @@ -859,13 +863,11 @@ "(let-values(((cols file)(split-relative-string(symbol->string s) #f)))" "(let*((f-file(if(null? cols)" " \"main.rkt\"" -" (string-append file \".rkt\")))" -"(p(find-col-file 'standard-module-name-resolver" -" show-collection-err" +" (string-append file \".rkt\"))))" +"(find-col-file show-collection-err" "(if(null? cols) file(car cols))" "(if(null? cols) null(cdr cols))" -" f-file)))" -"(build-path p f-file)))))" +" f-file)))))" "((string? s)" "(let*((dir(get-dir)))" "(or(path-cache-get(cons s dir))" @@ -897,8 +899,8 @@ " \"main.rkt\"" " (if (regexp-match? #rx\"[.]\" file)" "(ss->rkt file)" -" (string-append file \".rkt\")))))" -"(p(let-values(((cols)" +" (string-append file \".rkt\"))))))" +"(let-values(((cols)" "(if old-style?" "(append(if(null?(cddr s))" " '(\"mzlib\")" @@ -910,12 +912,10 @@ "(if(null? cols)" "(list file)" " cols))))" -"(find-col-file 'standard-module-name-resolver" -" show-collection-err" +"(find-col-file show-collection-err" "(car cols)" "(cdr cols)" -" f-file))))" -"(build-path p f-file)))))" +" f-file))))))" "((eq?(car s) 'file)" "(path-ss->rkt " "(simplify-path(path->complete-path(expand-user-path(cadr s))(get-dir))))))))" diff --git a/src/racket/src/startup.rktl b/src/racket/src/startup.rktl index 786d6f9c09..5089316b18 100644 --- a/src/racket/src/startup.rktl +++ b/src/racket/src/startup.rktl @@ -328,26 +328,28 @@ (-check-relpath who collection) (for-each (lambda (p) (-check-relpath who p)) collection-path))) + (define-values (-check-fail) + (lambda (who fail) + (unless (and (procedure? fail) + (procedure-arity-includes? fail 1)) + (raise-type-error who "procedure (arity 1)" fail)))) + (define-values (collection-path) - (lambda (collection . collection-path) + (lambda (fail collection . collection-path) (-check-collection 'collection-path collection collection-path) - (find-col-file 'collection-path (lambda (s) - (raise - (exn:fail:filesystem s (current-continuation-marks)))) + (-check-fail 'collection-path fail) + (find-col-file fail collection collection-path #f))) (define-values (collection-file-path) - (lambda (file-name collection . collection-path) + (lambda (fail file-name collection . collection-path) (-check-relpath 'collection-file-path file-name) (-check-collection 'collection-file-path collection collection-path) - (build-path - (find-col-file 'collection-file-path (lambda (s) - (raise - (exn:fail:filesystem s (current-continuation-marks)))) - collection collection-path - file-name) - file-name))) + (-check-fail 'collection-file-path fail) + (find-col-file fail + collection collection-path + file-name))) (define-values (user-links-path) (find-system-path 'links-file)) (define-values (user-links-cache) (make-hasheq)) @@ -506,7 +508,7 @@ (normalize-collection-reference base (cons name collection-path))))]))) (define-values (find-col-file) - (lambda (who fail collection collection-path file-name) + (lambda (fail collection collection-path file-name) (let-values ([(collection collection-path) (normalize-collection-reference collection collection-path)]) (let ([all-paths (let ([sym (string->symbol (if (path? collection) @@ -528,6 +530,9 @@ null) ;; list of paths: (current-library-collection-paths)))]) + (define-values (done) + (lambda (p) + (if file-name (build-path p file-name) p))) (define-values (*build-path-rep) (lambda (p c) (if (path? p) @@ -544,7 +549,7 @@ (let cloop ([paths all-paths] [found-col #f]) (if (null? paths) (if found-col - found-col + (done found-col) (let ([rest-coll (if (null? collection-path) "" @@ -562,8 +567,7 @@ (cons (car l) (filter f (cdr l))) (filter f (cdr l)))))) (fail - (format "~a: collection not found: ~s in any of: ~s~a" - who + (format "collection not found: ~s in any of: ~s~a" (if (null? collection-path) (to-string collection) (string-append (to-string collection) "/" rest-coll)) @@ -591,12 +595,12 @@ (string-append (substring file-name 0 (- len 4)) ".ss")))]) (and alt-file-name (file-exists? (build-path cpath alt-file-name))))) - cpath + (done cpath) ;; Look further for specific file, but remember ;; first found directory (cloop (cdr paths) (or found-col cpath))) ;; Just looking for dir; found it: - cpath) + (done cpath)) ;; sub-collection not here; try next instance ;; of the top-level collection (cloop (cdr paths) found-col))) @@ -961,12 +965,13 @@ (current-load-relative-directory) (current-directory)))] [show-collection-err (lambda (s) - (if stx - (raise-syntax-error - #f - s - stx) - (error s)))] + (let ([s (string-append "standard-module-name-resolver: " s)]) + (if stx + (raise-syntax-error + #f + s + stx) + (error s))))] [ss->rkt (lambda (s) (let ([len (string-length s)]) (if (and (len . >= . 3) @@ -986,13 +991,11 @@ (let-values ([(cols file) (split-relative-string (symbol->string s) #f)]) (let* ([f-file (if (null? cols) "main.rkt" - (string-append file ".rkt"))] - [p (find-col-file 'standard-module-name-resolver - show-collection-err - (if (null? cols) file (car cols)) - (if (null? cols) null (cdr cols)) - f-file)]) - (build-path p f-file))))] + (string-append file ".rkt"))]) + (find-col-file show-collection-err + (if (null? cols) file (car cols)) + (if (null? cols) null (cdr cols)) + f-file))))] [(string? s) (let* ([dir (get-dir)]) (or (path-cache-get (cons s dir)) @@ -1025,25 +1028,23 @@ "main.rkt" (if (regexp-match? #rx"[.]" file) (ss->rkt file) - (string-append file ".rkt"))))] - [p (let-values ([(cols) - (if old-style? - (append (if (null? (cddr s)) - '("mzlib") - (apply append - (map (lambda (p) - (split-relative-string p #t)) - (cddr s)))) - cols) - (if (null? cols) - (list file) - cols))]) - (find-col-file 'standard-module-name-resolver - show-collection-err - (car cols) - (cdr cols) - f-file))]) - (build-path p f-file))))] + (string-append file ".rkt"))))]) + (let-values ([(cols) + (if old-style? + (append (if (null? (cddr s)) + '("mzlib") + (apply append + (map (lambda (p) + (split-relative-string p #t)) + (cddr s)))) + cols) + (if (null? cols) + (list file) + cols))]) + (find-col-file show-collection-err + (car cols) + (cdr cols) + f-file)))))] [(eq? (car s) 'file) ;; Use filesystem-sensitive `simplify-path' here: (path-ss->rkt From 469b21d28df045a6cc8b4b1a70295b34d5715c1e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 9 Jan 2012 16:41:12 -0700 Subject: [PATCH 454/746] fix problem printing symbols with unicode chars Specifically, special-casing letters (such as sigma) were not handled correctly. Merge to 5.2.1 (cherry picked from commit 8b54dc43c8fc7250d7e99a97c4656a14d459ebdd) --- collects/tests/racket/print.rktl | 9 +++++++++ src/racket/src/symbol.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/collects/tests/racket/print.rktl b/collects/tests/racket/print.rktl index 567795337b..436137f2c9 100644 --- a/collects/tests/racket/print.rktl +++ b/collects/tests/racket/print.rktl @@ -197,9 +197,18 @@ (f v o) (get-output-string o)))]) (test "Π" in-string write 'Π) ;; UTF-8 encoding can be misinterpreted as having a space + (test "Σ" in-string write 'Σ) ;; interesting because it's special-casing + (test "ς" in-string write 'ς) ;; also special-casing + (test "σ" in-string write 'σ) (test "|a\xA0b|" in-string write (string->symbol "a\xA0b")) + (parameterize ([read-case-sensitive #f]) + (test "|Π|" in-string write 'Π) + (test "|Σ|" in-string write 'Σ) + (test "σ" in-string write 'σ) + (test "|ς|" in-string write 'ς)) (parameterize ([read-accept-bar-quote #f]) (test "Π" in-string write 'Π) + (test "Σ" in-string write 'Σ) (test "a\\\xA0b" in-string write (string->symbol "a\xA0b")))) (report-errs) diff --git a/src/racket/src/symbol.c b/src/racket/src/symbol.c index aafdf9939b..18da94fa27 100644 --- a/src/racket/src/symbol.c +++ b/src/racket/src/symbol.c @@ -617,7 +617,7 @@ const char *scheme_symbol_name_and_size(Scheme_Object *sym, uintptr_t *length, i ul++; } ch = buf[0]; - if (scheme_isspecialcasing(ch)) { + if ((flags & SCHEME_SNF_NEED_CASE) && scheme_isspecialcasing(ch)) { mzchar *rc; buf[1] = 0; rc = scheme_string_recase(buf, 0, 1, 3, 1, NULL); From f1a1670a7436b5806a5f1b44267996597ed62bca Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 9 Jan 2012 16:46:37 -0700 Subject: [PATCH 455/746] protect `raco setup' from files in linked collection dirs Patch by Jay McCarthy. Merge to 5.2.1 (cherry picked from commit d56d28f0b615519810ba22de51ce6c2b3f1cd52f) --- collects/setup/setup-unit.rkt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/collects/setup/setup-unit.rkt b/collects/setup/setup-unit.rkt index b5dafdf4a9..748cb4844a 100644 --- a/collects/setup/setup-unit.rkt +++ b/collects/setup/setup-unit.rkt @@ -305,7 +305,8 @@ (maybe (list (string->path c)) ->cc)) (for ([cp (in-list (links #:root? #t #:user? #f))] #:when (directory-exists? cp) - [collection (directory-list cp)]) + [collection (directory-list cp)] + #:when (directory-exists? (build-path cp collection))) (maybe (list collection) ->cc))) (when (make-user) (let ([user-collects (find-user-collects-dir)]) @@ -318,7 +319,8 @@ (maybe (list (string->path c)) ->cc)) (for ([cp (in-list (links #:root? #t))] #:when (directory-exists? cp) - [collection (directory-list cp)]) + [collection (directory-list cp)] + #:when (directory-exists? (build-path cp collection))) (maybe (list collection) ->cc)))) (hash-map ht (lambda (k v) v)))) From a1cb9a8c85ae6b438b007289b9db145c18dee1c8 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 9 Jan 2012 18:38:15 -0500 Subject: [PATCH 456/746] replaced gamepad image with higher resolution version (cherry picked from commit d9176df246acb5e5b4a212d5fdb041b5af7649bc) --- collects/2htdp/private/gamepad.png | Bin 15175 -> 129128 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/collects/2htdp/private/gamepad.png b/collects/2htdp/private/gamepad.png index 434f65df9841739c5864d2f75a83f4252fbe443b..ee79693ac40fa44c4ee99990536ce7ca33aed70c 100644 GIT binary patch literal 129128 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 literal 15175 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 If;xWx2eGI{YXATM From 9e272a2359bbd1b6f57df9670cd7186b12837a3b Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 9 Jan 2012 17:15:15 -0600 Subject: [PATCH 457/746] fix bug in lw struct generation (cherry picked from commit f1a7864c63bc2f38b99e4fd3804e4da0629301cf) --- collects/redex/private/loc-wrapper-ct.rkt | 2 +- collects/redex/tests/lw-test.rkt | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/collects/redex/private/loc-wrapper-ct.rkt b/collects/redex/private/loc-wrapper-ct.rkt index e17058638a..56de781cb1 100644 --- a/collects/redex/private/loc-wrapper-ct.rkt +++ b/collects/redex/private/loc-wrapper-ct.rkt @@ -49,7 +49,7 @@ #`#(#,init-loc-wrapper/q? #(list #(#,init-loc-wrapper/q? #,op #,(syntax-line stx) #,(syntax-column stx)) #,@(map (λ (x) (process-arg x quote-depth)) (syntax->list (syntax (a b ...)))) - #(i,init-loc-wrapper/q? #," . " #f #f) + #(#,init-loc-wrapper/q? #," . " #f #f) #,(process-arg #'c quote-depth) #(#,init-loc-wrapper/q? #,cl #f #f)) #,(syntax-line stx) diff --git a/collects/redex/tests/lw-test.rkt b/collects/redex/tests/lw-test.rkt index 31cfe3cd29..bb34a3f82b 100644 --- a/collects/redex/tests/lw-test.rkt +++ b/collects/redex/tests/lw-test.rkt @@ -320,7 +320,10 @@ (normalize-lw (to-lw (a b)))) (test (normalize-lw (to-lw/stx (from-str "(a ((b)) c 1 #t)"))) - (normalize-lw (to-lw (a ((b)) c 1 #t))))) + (normalize-lw (to-lw (a ((b)) c 1 #t)))) + + (test (normalize-lw (to-lw/stx (from-str "(a b . c)"))) + (normalize-lw (to-lw (a b . c))))) (print-tests-passed "lw-test.rkt")) From 9146b151d86e10ddd812ba36d26ca1a0d8b834e5 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Sun, 8 Jan 2012 23:13:37 -0700 Subject: [PATCH 458/746] Caching with weak boxes, cleanup, planet download icon (cherry picked from commit 6ec78137e3755f56a0472baf5ab0947173835d0a) --- collects/drracket/private/debug.rkt | 4 +- collects/drracket/private/unit.rkt | 10 +- collects/images/icons/arrow.rkt | 76 ++-- collects/images/icons/control.rkt | 187 +++++----- collects/images/icons/file.rkt | 219 ++++++------ collects/images/icons/misc.rkt | 408 +++++++++++----------- collects/images/icons/style.rkt | 52 +-- collects/images/icons/tool.rkt | 65 ++-- collects/images/logos.rkt | 367 +++++++++++++------ collects/images/private/transient-box.rkt | 57 --- collects/images/private/utils.rkt | 110 +++++- 11 files changed, 864 insertions(+), 691 deletions(-) delete mode 100644 collects/images/private/transient-box.rkt diff --git a/collects/drracket/private/debug.rkt b/collects/drracket/private/debug.rkt index ae1434fe4c..4df3981356 100644 --- a/collects/drracket/private/debug.rkt +++ b/collects/drracket/private/debug.rkt @@ -26,7 +26,7 @@ profile todo: net/url racket/match mrlib/include-bitmap - images/icons/misc images/icons/style images/icons/control + images/icons/misc images/icons/style images/icons/control images/logos (for-syntax racket/base)) (define orig (current-output-port)) @@ -191,7 +191,7 @@ profile todo: (define bug-note% (make-note% "stop-multi.png" (stop-signs-icon halt-icon-color))) (define mf-note% (make-note% "mf.gif" (include-bitmap (lib "icons/mf.gif") 'gif))) - (define small-planet-bitmap (record-icon "blue")) + (define small-planet-bitmap (planet-logo (default-icon-height))) (define planet-note% (make-note% "small-planet.png" small-planet-bitmap)) ;; display-stats : (syntax -> syntax) diff --git a/collects/drracket/private/unit.rkt b/collects/drracket/private/unit.rkt index dbd7a57293..b18001286d 100644 --- a/collects/drracket/private/unit.rkt +++ b/collects/drracket/private/unit.rkt @@ -38,7 +38,8 @@ module browser threading seems wrong. "local-member-names.rkt" "eval-helpers.rkt" (prefix-in drracket:arrow: "../arrow.rkt") - (prefix-in icons: (combine-in images/icons/file images/icons/control images/icons/style)) + (prefix-in icons: (combine-in images/icons/file images/icons/control images/icons/style + images/logos)) mred (prefix-in mred: mred) @@ -385,11 +386,12 @@ module browser threading seems wrong. frame program-filename)))]))) + (define disk-color (make-object color% 255 233 112)) (define execute-bitmap (icons:play-icon icons:run-icon-color (icons:toolbar-icon-height))) (define break-bitmap (icons:stop-icon icons:halt-icon-color (icons:toolbar-icon-height))) - (define small-save-bitmap (icons:small-save-icon icons:syntax-icon-color icons:metal-icon-color + (define small-save-bitmap (icons:small-save-icon icons:syntax-icon-color disk-color (icons:toolbar-icon-height))) - (define save-bitmap (icons:save-icon icons:syntax-icon-color icons:metal-icon-color + (define save-bitmap (icons:save-icon icons:syntax-icon-color disk-color (icons:toolbar-icon-height))) (define-values (get-program-editor-mixin add-to-program-editor-mixin) @@ -4696,7 +4698,7 @@ module browser threading seems wrong. [(null? l) '()] [else (cons (car l) (loop (cdr l) (- n 1)))]))) - (define very-small-planet-bitmap (icons:record-icon "blue" (icons:toolbar-icon-height))) + (define very-small-planet-bitmap (icons:planet-logo (icons:toolbar-icon-height))) (define saved-bug-reports-window #f) (define saved-bug-reports-panel #f) diff --git a/collects/images/icons/arrow.rkt b/collects/images/icons/arrow.rkt index 644b769f89..861cb50954 100644 --- a/collects/images/icons/arrow.rkt +++ b/collects/images/icons/arrow.rkt @@ -8,7 +8,7 @@ (provide (all-defined-out)) -(define (right-arrow-flomap color height) +(define (flat-right-arrow-flomap color height) (draw-icon-flomap 32 32 (λ (dc) (send dc set-brush color 'solid) @@ -17,15 +17,16 @@ '(14 . 31) '(15 . 22) '(0 . 22)))) (/ height 32))) -(define (right-over-arrow-flomap color height) +(define (flat-right-over-arrow-flomap color height) (draw-icon-flomap 32 32 (λ (dc) (send dc set-brush color 'solid) (draw-path-commands - dc 0 15 '((c (9 . -14) (19.5 . -8) (24 . -2)) - (l (5 . -7) (2 . 20) (-20 . -2) (7 . -5)) - (c (-2.5 . -4) (-8 . -8.5) (-14 . 0)) - (l (-4 . -4))))) + dc 0 0 '((m 0 15) + (c 9 -14 19.5 -8 24 -2) + (l 5 -7 2 20 -20 -2 7 -5) + (c -2.5 -4 -8 -8.5 -14 0) + (l -4 -4)))) (/ height 32))) (define (flomap-render-short-icon fm material) @@ -37,37 +38,46 @@ dfm)) (deep-flomap-render-icon dfm material)) -(define (right-arrow-icon-flomap* color height material) - (flomap-render-short-icon (right-arrow-flomap color height) material)) +(define (right-arrow-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (flomap-render-short-icon (flat-right-arrow-flomap color height) material))) -(define (up-arrow-icon-flomap* color height material) - (flomap-render-icon (flomap-cw-rotate (right-arrow-flomap color height)) material)) +(define (up-arrow-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (flomap-render-icon (flomap-cw-rotate (flat-right-arrow-flomap color height)) material))) -(define (down-arrow-icon-flomap* color height material) - (flomap-render-icon (flomap-ccw-rotate (right-arrow-flomap color height)) material)) +(define (down-arrow-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (flomap-render-icon (flomap-ccw-rotate (flat-right-arrow-flomap color height)) material))) -(define (right-over-arrow-icon-flomap* color height material) - (flomap-render-short-icon (right-over-arrow-flomap color height) material)) +(define (right-over-arrow-flomap color + [height (default-icon-height)] + [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (flomap-render-short-icon (flat-right-over-arrow-flomap color height) material))) -(define (right-under-arrow-icon-flomap* color height material) - (flomap-render-short-icon (flomap-flip-vertical (right-over-arrow-flomap color height)) material)) +(define (right-under-arrow-flomap color + [height (default-icon-height)] + [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (flomap-render-short-icon + (flomap-flip-vertical (flat-right-over-arrow-flomap color height)) material))) -(define-icon-flomap-proc right-arrow-icon-flomap right-arrow-icon-flomap* 32 color) -(define-icon-flomap-proc up-arrow-icon-flomap up-arrow-icon-flomap* 32 color) -(define-icon-flomap-proc down-arrow-icon-flomap down-arrow-icon-flomap* 32 color) -(define-icon-flomap-proc right-over-arrow-icon-flomap right-over-arrow-icon-flomap* 32 color) -(define-icon-flomap-proc right-under-arrow-icon-flomap right-under-arrow-icon-flomap* 32 color) +(define left-arrow-flomap (compose flomap-flip-horizontal right-arrow-flomap)) +(define left-over-arrow-flomap (compose flomap-flip-horizontal right-over-arrow-flomap)) +(define left-under-arrow-flomap (compose flomap-flip-horizontal right-under-arrow-flomap)) -(define left-arrow-icon-flomap (compose flomap-flip-horizontal right-arrow-icon-flomap)) -(define left-over-arrow-icon-flomap (compose flomap-flip-horizontal right-over-arrow-icon-flomap)) -(define left-under-arrow-icon-flomap (compose flomap-flip-horizontal right-under-arrow-icon-flomap)) +(define right-arrow-icon (compose flomap->bitmap right-arrow-flomap)) +(define left-arrow-icon (compose flomap->bitmap left-arrow-flomap)) +(define up-arrow-icon (compose flomap->bitmap up-arrow-flomap)) +(define down-arrow-icon (compose flomap->bitmap down-arrow-flomap)) -(define right-arrow-icon (compose flomap->bitmap right-arrow-icon-flomap)) -(define left-arrow-icon (compose flomap->bitmap left-arrow-icon-flomap)) -(define up-arrow-icon (compose flomap->bitmap up-arrow-icon-flomap)) -(define down-arrow-icon (compose flomap->bitmap down-arrow-icon-flomap)) - -(define right-over-arrow-icon (compose flomap->bitmap right-over-arrow-icon-flomap)) -(define left-over-arrow-icon (compose flomap->bitmap left-over-arrow-icon-flomap)) -(define right-under-arrow-icon (compose flomap->bitmap right-under-arrow-icon-flomap)) -(define left-under-arrow-icon (compose flomap->bitmap left-under-arrow-icon-flomap)) +(define right-over-arrow-icon (compose flomap->bitmap right-over-arrow-flomap)) +(define left-over-arrow-icon (compose flomap->bitmap left-over-arrow-flomap)) +(define right-under-arrow-icon (compose flomap->bitmap right-under-arrow-flomap)) +(define left-under-arrow-icon (compose flomap->bitmap left-under-arrow-flomap)) diff --git a/collects/images/icons/control.rkt b/collects/images/icons/control.rkt index e12e8168d8..ce523b644e 100644 --- a/collects/images/icons/control.rkt +++ b/collects/images/icons/control.rkt @@ -1,123 +1,126 @@ #lang racket/base (require racket/class + racket/serialize web-server/lang/serial-lambda "../private/flomap.rkt" "../private/utils.rkt" "style.rkt") (provide (all-defined-out)) -(define (play-flomap color height) - (draw-icon-flomap - 24 32 (λ (dc) +(define play-points + (list '(0 . 0) '(4 . 0) + '(23 . 13) '(23 . 18) + '(4 . 31) '(0 . 31))) + +(define (play-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (draw-rendered-icon-flomap + 24 32 (λ (dc) + (send dc set-brush color 'solid) + (send dc draw-polygon play-points)) + (/ height 32) + material))) + +(define (fast-forward-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (draw-rendered-icon-flomap + 32 32 (λ (dc) + (send dc set-brush color 'solid) + (send dc draw-polygon (list '(0 . 0) '(4 . 0) + '(17 . 13) '(17 . 18) + '(4 . 31) '(0 . 31))) + (send dc translate 2 0) + (send dc draw-polygon (list + ;; right side + '(14 . 2) + '(27 . 13) '(27 . 18) + '(14 . 29) + ;; left side + '(8 . 29) + '(18 . 19) '(18 . 12) + '(8 . 2)))) + (/ height 32) + material))) + +(define (stop-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (draw-rendered-icon-flomap + 32 32 (λ (dc) + (send dc set-brush color 'solid) + (send dc draw-polygon (list '(0 . 0) '(31 . 0) '(31 . 31) '(0 . 31)))) + (/ height 32) + material))) + +(define (record-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (draw-rendered-icon-flomap + 32 32 (λ (dc) + (send dc set-brush color 'solid) + (draw-ellipse/smoothed dc 0 0 32 32)) + (/ height 32) + material))) + +(define (bar-flomap color height material) + (make-cached-flomap + [height color material] + (draw-rendered-icon-flomap + 8 32 (λ (dc) (send dc set-brush color 'solid) - (send dc draw-polygon (list '(0 . 0) '(4 . 0) - '(23 . 13) '(23 . 18) - '(4 . 31) '(0 . 31)))) - (/ height 32))) + (send dc draw-polygon (list '(0 . 0) '(7 . 0) '(7 . 31) '(0 . 31)))) + (/ height 32) + material))) -(define (fast-forward-flomap color height) - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-brush color 'solid) - (send dc draw-polygon (list '(0 . 0) '(4 . 0) - '(17 . 13) '(17 . 18) - '(4 . 31) '(0 . 31))) - (send dc translate 2 0) - (send dc draw-polygon (list - ;; right side - '(14 . 2) - '(27 . 13) '(27 . 18) - '(14 . 29) - ;; left side - '(8 . 29) - '(18 . 19) '(18 . 12) - '(8 . 2)))) - (/ height 32))) +(define back-flomap (compose flomap-flip-horizontal play-flomap)) +(define reverse-flomap (compose flomap-flip-horizontal fast-forward-flomap)) -(define (play-icon-flomap* color height material) - (flomap-render-icon (play-flomap color height) material)) - -(define (fast-forward-icon-flomap* color height material) - (flomap-render-icon (fast-forward-flomap color height) material)) - -(define (stop-icon-flomap* color height material) - (draw-rendered-icon-flomap - 32 32 (λ (dc) - (send dc set-brush color 'solid) - (send dc draw-polygon (list '(0 . 0) '(31 . 0) '(31 . 31) '(0 . 31)))) - (/ height 32) - material)) - -(define (record-icon-flomap* color height material) - (draw-rendered-icon-flomap - 32 32 (λ (dc) - (send dc set-brush color 'solid) - (draw-ellipse/smoothed dc 0 0 32 32)) - (/ height 32) - material)) - -(define (bar-icon-flomap* color height material) - (draw-rendered-icon-flomap - 8 32 (λ (dc) - (send dc set-brush color 'solid) - (send dc draw-polygon (list '(0 . 0) '(7 . 0) '(7 . 31) '(0 . 31)))) - (/ height 32) - material)) - -(define-icon-flomap-proc play-icon-flomap play-icon-flomap* 32 color) -(define-icon-flomap-proc fast-forward-icon-flomap fast-forward-icon-flomap* 32 color) -(define-icon-flomap-proc record-icon-flomap record-icon-flomap* 32 color) -(define-icon-flomap-proc bar-icon-flomap bar-icon-flomap* 32 color) -(define-icon-flomap-proc stop-icon-flomap stop-icon-flomap* 32 color) - -(define back-icon-flomap (compose flomap-flip-horizontal play-icon-flomap)) -(define reverse-icon-flomap (compose flomap-flip-horizontal fast-forward-icon-flomap)) - -(define (pause-icon-flomap color [height (default-icon-height)] - [material (default-icon-material)]) +(define (pause-flomap color [height (default-icon-height)] [material (default-icon-material)]) (flomap-hc-append - (bar-icon-flomap color height material) + (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/8 height)))) 0) - (bar-icon-flomap color height material))) + (bar-flomap color height material))) -(define (step-icon-flomap color [height (default-icon-height)] +(define (step-flomap color [height (default-icon-height)] [material (default-icon-material)]) (flomap-hc-append - (play-icon-flomap color height material) + (play-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) - (bar-icon-flomap color height material))) + (bar-flomap color height material))) -(define (step-back-icon-flomap color [height (default-icon-height)] +(define (step-back-flomap color [height (default-icon-height)] [material (default-icon-material)]) (flomap-hc-append - (bar-icon-flomap color height material) + (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) - (back-icon-flomap color height material))) + (back-flomap color height material))) -(define (continue-icon-flomap color [height (default-icon-height)] +(define (continue-flomap color [height (default-icon-height)] [material (default-icon-material)]) (flomap-hc-append - (bar-icon-flomap color height material) + (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) - (play-icon-flomap color height material))) + (play-flomap color height material))) -(define (continue-back-icon-flomap color [height (default-icon-height)] +(define (continue-back-flomap color [height (default-icon-height)] [material (default-icon-material)]) (flomap-hc-append - (back-icon-flomap color height material) + (back-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) - (bar-icon-flomap color height material))) + (bar-flomap color height material))) -(define play-icon (compose flomap->bitmap play-icon-flomap)) -(define back-icon (compose flomap->bitmap back-icon-flomap)) -(define fast-forward-icon (compose flomap->bitmap fast-forward-icon-flomap)) -(define reverse-icon (compose flomap->bitmap reverse-icon-flomap)) -(define bar-icon (compose flomap->bitmap bar-icon-flomap)) -(define stop-icon (compose flomap->bitmap stop-icon-flomap)) -(define record-icon (compose flomap->bitmap record-icon-flomap)) -(define pause-icon (compose flomap->bitmap pause-icon-flomap)) -(define step-icon (compose flomap->bitmap step-icon-flomap)) -(define step-back-icon (compose flomap->bitmap step-back-icon-flomap)) -(define continue-icon (compose flomap->bitmap continue-icon-flomap)) -(define continue-back-icon (compose flomap->bitmap continue-back-icon-flomap)) +(define play-icon (compose flomap->bitmap play-flomap)) +(define back-icon (compose flomap->bitmap back-flomap)) +(define fast-forward-icon (compose flomap->bitmap fast-forward-flomap)) +(define reverse-icon (compose flomap->bitmap reverse-flomap)) +(define bar-icon (compose flomap->bitmap bar-flomap)) +(define stop-icon (compose flomap->bitmap stop-flomap)) +(define record-icon (compose flomap->bitmap record-flomap)) +(define pause-icon (compose flomap->bitmap pause-flomap)) +(define step-icon (compose flomap->bitmap step-flomap)) +(define step-back-icon (compose flomap->bitmap step-back-flomap)) +(define continue-icon (compose flomap->bitmap continue-flomap)) +(define continue-back-icon (compose flomap->bitmap continue-back-flomap)) diff --git a/collects/images/icons/file.rkt b/collects/images/icons/file.rkt index 99badd68cb..d8a0477fd5 100644 --- a/collects/images/icons/file.rkt +++ b/collects/images/icons/file.rkt @@ -4,124 +4,129 @@ "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/renderfx.rkt" + "../private/utils.rkt" "arrow.rkt" "style.rkt") (provide (all-defined-out)) -(define (floppy-disk-icon-flomap* color height material) - (define scale (/ height 32)) - - (define metal-fm - (let* ([fm (draw-icon-flomap - 18 11 (λ (dc) - (send dc set-background "lightgray") - (define outer-path (new dc-path%)) - (send outer-path rounded-rectangle 0.5 0.5 13 12 1) - (define inner-path (new dc-path%)) - (send inner-path rectangle 2.5 2.5 4 6) - (define outer-rgn (new region%)) - (send outer-rgn set-path outer-path) - (define inner-rgn (new region%)) - (send inner-rgn set-path inner-path) - (send outer-rgn subtract inner-rgn) - (send dc set-clipping-region outer-rgn) - (send dc clear)) - scale)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-scale-z dfm 1/16)]) - (deep-flomap-render-icon dfm metal-material))) - - (define bottom-indent-fm - (draw-icon-flomap - 20 11 (λ (dc) - (send dc set-alpha 1/4) - (send dc set-pen "black" 1 'transparent) - (send dc set-brush "black" 'solid) - (send dc draw-rounded-rectangle 1.5 0.5 18 11 1)) - scale)) - - (define label-fm - (let* ([fm (draw-icon-flomap - 22 20 (λ (dc) - (send dc set-pen "black" 1 'transparent) - (send dc set-brush "black" 'solid) - (send dc draw-rounded-rectangle -0.5 -3.5 22 21 3) - (send dc set-brush "lemonchiffon" 'solid) - (send dc draw-rounded-rectangle 0.5 -3.5 20 20 2) - (send dc set-brush "chocolate" 'solid) - (send dc draw-rectangle 0.5 -0.5 20 4) - (send dc set-brush "navy" 'solid) - (for ([i (in-range 5.5 15 3)]) - (send dc draw-rectangle 2.5 i 16 1))) - scale)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-bulge-vertical dfm (* 4 scale))]) - (deep-flomap-render-icon dfm matte-material))) - - (define top-indent-fm - (draw-icon-flomap - 22 19 (λ (dc) - (send dc set-alpha 1) - (send dc set-pen "black" 1 'transparent) - (send dc set-brush "black" 'solid) - (send dc draw-rounded-rectangle -0.5 -2.5 22 20 2.5)) - scale)) - - (define case-fm - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-brush color 'solid) - (send dc draw-polygon (list '(0 . 3) '(3 . 0) - '(28 . 0) '(31 . 3) - '(31 . 28) '(28 . 31) - '(3 . 31) '(0 . 28)))) - scale)) - - (define disk-fm - (let* ([dfm (deep-flomap-ct-superimpose - (deep-flomap-cb-superimpose - (flomap->deep-flomap case-fm) - (deep-flomap-raise (flomap->deep-flomap bottom-indent-fm) (* -4 scale)) - #:z-mode 'add) - (deep-flomap-raise (flomap->deep-flomap top-indent-fm) (* -1 scale)) - #:z-mode 'add)] - [dfm (deep-flomap-icon-style dfm)]) - (deep-flomap-render-icon dfm material))) - - (let* ([fm (flomap-cb-superimpose disk-fm metal-fm)] - [fm (flomap-ct-superimpose fm label-fm)]) - fm)) +(define (floppy-disk-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (define scale (/ height 32)) + + (define metal-fm + (let* ([fm (draw-icon-flomap + 18 11 (λ (dc) + (send dc set-background "lightgray") + (define outer-path (new dc-path%)) + (send outer-path rounded-rectangle 0.5 0.5 13 12 1) + (define inner-path (new dc-path%)) + (send inner-path rectangle 2.5 2.5 4 6) + (define outer-rgn (new region%)) + (send outer-rgn set-path outer-path) + (define inner-rgn (new region%)) + (send inner-rgn set-path inner-path) + (send outer-rgn subtract inner-rgn) + (send dc set-clipping-region outer-rgn) + (send dc clear)) + scale)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-scale-z dfm 1/16)]) + (deep-flomap-render-icon dfm metal-material))) + + (define bottom-indent-fm + (draw-icon-flomap + 20 11 (λ (dc) + (send dc set-alpha 1/4) + (send dc set-pen "black" 1 'transparent) + (send dc set-brush "black" 'solid) + (send dc draw-rounded-rectangle 1.5 0.5 18 11 1)) + scale)) + + (define label-fm + (let* ([fm (draw-icon-flomap + 22 20 (λ (dc) + (send dc set-pen "black" 1 'transparent) + (send dc set-brush "black" 'solid) + (send dc draw-rounded-rectangle -0.5 -3.5 22 21 3) + (send dc set-brush "lemonchiffon" 'solid) + (send dc draw-rounded-rectangle 0.5 -3.5 20 20 2) + (send dc set-brush "chocolate" 'solid) + (send dc draw-rectangle 0.5 -0.5 20 4) + (send dc set-brush "navy" 'solid) + (for ([i (in-range 5.5 15 3)]) + (send dc draw-rectangle 2.5 i 16 1))) + scale)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-bulge-vertical dfm (* 4 scale))]) + (deep-flomap-render-icon dfm matte-material))) + + (define top-indent-fm + (draw-icon-flomap + 22 19 (λ (dc) + (send dc set-alpha 1) + (send dc set-pen "black" 1 'transparent) + (send dc set-brush "black" 'solid) + (send dc draw-rounded-rectangle -0.5 -2.5 22 20 2.5)) + scale)) + + (define case-fm + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-brush color 'solid) + (send dc draw-polygon (list '(0 . 3) '(3 . 0) + '(28 . 0) '(31 . 3) + '(31 . 28) '(28 . 31) + '(3 . 31) '(0 . 28)))) + scale)) + + (define disk-fm + (let* ([dfm (deep-flomap-ct-superimpose + (deep-flomap-cb-superimpose + (flomap->deep-flomap case-fm) + (deep-flomap-raise (flomap->deep-flomap bottom-indent-fm) (* -4 scale)) + #:z-mode 'add) + (deep-flomap-raise (flomap->deep-flomap top-indent-fm) (* -1 scale)) + #:z-mode 'add)] + [dfm (deep-flomap-icon-style dfm)]) + (deep-flomap-render-icon dfm material))) + + (let* ([fm (flomap-cb-superimpose disk-fm metal-fm)] + [fm (flomap-ct-superimpose fm label-fm)]) + fm))) -(define-icon-flomap-proc floppy-disk-icon-flomap floppy-disk-icon-flomap* 32 color) - -(define (save-icon-flomap arrow-color color [height (default-icon-height)] - [material (default-icon-material)]) - (flomap-hc-append (right-arrow-icon-flomap arrow-color (* 3/4 height) material) +(define (save-flomap arrow-color color + [height (default-icon-height)] + [material (default-icon-material)]) + (flomap-hc-append (right-arrow-flomap arrow-color (* 3/4 height) material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) - (floppy-disk-icon-flomap color height material))) + (floppy-disk-flomap color height material))) -(define (load-icon-flomap arrow-color color [height (default-icon-height)] - [material (default-icon-material)]) - (flomap-hc-append (floppy-disk-icon-flomap color height material) +(define (load-flomap arrow-color color + [height (default-icon-height)] + [material (default-icon-material)]) + (flomap-hc-append (floppy-disk-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) - (right-arrow-icon-flomap arrow-color (* 3/4 height) material))) + (right-arrow-flomap arrow-color (* 3/4 height) material))) -(define (small-save-icon-flomap arrow-color color [height (default-icon-height)] - [material (default-icon-material)]) +(define (small-save-flomap arrow-color color + [height (default-icon-height)] + [material (default-icon-material)]) (flomap-pin* 0 0 11/16 0 - (floppy-disk-icon-flomap color height material) - (right-arrow-icon-flomap arrow-color (* 3/4 height) material))) + (floppy-disk-flomap color height material) + (right-arrow-flomap arrow-color (* 3/4 height) material))) -(define (small-load-icon-flomap arrow-color color [height (default-icon-height)] - [material (default-icon-material)]) +(define (small-load-flomap arrow-color color + [height (default-icon-height)] + [material (default-icon-material)]) (flomap-pin* 1 1 5/16 1 - (floppy-disk-icon-flomap color height material) - (right-arrow-icon-flomap arrow-color (* 3/4 height) material))) + (floppy-disk-flomap color height material) + (right-arrow-flomap arrow-color (* 3/4 height) material))) -(define floppy-disk-icon (compose flomap->bitmap floppy-disk-icon-flomap)) -(define save-icon (compose flomap->bitmap save-icon-flomap)) -(define load-icon (compose flomap->bitmap load-icon-flomap)) -(define small-save-icon (compose flomap->bitmap small-save-icon-flomap)) -(define small-load-icon (compose flomap->bitmap small-load-icon-flomap)) +(define floppy-disk-icon (compose flomap->bitmap floppy-disk-flomap)) +(define save-icon (compose flomap->bitmap save-flomap)) +(define load-icon (compose flomap->bitmap load-flomap)) +(define small-save-icon (compose flomap->bitmap small-save-flomap)) +(define small-load-icon (compose flomap->bitmap small-load-flomap)) diff --git a/collects/images/icons/misc.rkt b/collects/images/icons/misc.rkt index ff321c51de..264fa5dfad 100644 --- a/collects/images/icons/misc.rkt +++ b/collects/images/icons/misc.rkt @@ -12,7 +12,7 @@ ;; =================================================================================================== ;; Unrendered flomaps -(define (x-flomap color height) +(define (flat-x-flomap color height) (define mn 7.5) (define mx 23.5) (draw-icon-flomap @@ -25,18 +25,19 @@ (send dc draw-line mn mx mx mn)) (/ height 32))) -(define (check-flomap color height) +(define (flat-check-flomap color height) (draw-icon-flomap 32 32 (λ (dc) (send dc set-brush color 'solid) (draw-path-commands - dc 0 19 '((c (0 . 0) (7 . 4) (14 . 12) (5.5 . -13.5) (17 . -23) (17 . -23)) - (l (-9 . -8)) - (c (0 . 0) (-6.5 . 7.5) (-9.5 . 16) (-2.5 . -4) (-6 . -6.5) (-6 . -6.5)) - (l (-6 . 9))))) + dc 0 0 '((m 0 19) + (c 0 0 7 4 14 12 5.5 -13.5 17 -23 17 -23) + (l -9 -8) + (c 0 0 -6.5 7.5 -9.5 16 -2.5 -4 -6 -6.5 -6 -6.5) + (l -6 9)))) (/ height 32))) -(define (regular-polygon-flomap sides start color size) +(define (flat-regular-polygon-flomap sides start color size) (draw-icon-flomap 32 32 (λ (dc) (send dc set-brush color 'solid) @@ -52,64 +53,76 @@ ;; =================================================================================================== ;; Rendered flomaps -(define (text-icon-flomap* str font color trim? outline? height material) +(define (text-flomap str font color trim? outline? + [height (default-icon-height)] + [material (default-icon-material)]) (define family (send font get-family)) (define style (send font get-style)) (define weight (send font get-weight)) (define underline? (send font get-underlined)) (define smoothing (send font get-smoothing)) - (let ([font (make-object font% (min 255 (inexact->exact (ceiling height))) - family style weight underline? smoothing #t)]) - (define-values (w h) (get-text-size str font)) - (define outline-amt (if outline? (/ height 32) 0)) - (define ceiling-amt (inexact->exact (ceiling outline-amt))) - (define fm - (let* ([fm (draw-flomap - w h (λ (dc) - (send dc set-font font) - (send dc set-text-foreground color) - (send dc draw-text str 0 0 #t)))] - [fm (if trim? (flomap-trim fm) fm)] - [fm (flomap-resize fm #f (- height (* 2 ceiling-amt)))] - [fm (flomap-inset fm ceiling-amt)] - [fm (if outline? (flomap-outlined fm outline-amt) fm)]) - fm)) - (flomap-render-icon fm material))) + (make-cached-flomap + [height str family style weight underline? smoothing color trim? outline? material] + (let ([font (make-object font% (min 255 (inexact->exact (ceiling height))) + family style weight underline? smoothing #t)]) + (define-values (w h) (get-text-size str font)) + (define outline-amt (if outline? (/ height 32) 0)) + (define ceiling-amt (inexact->exact (ceiling outline-amt))) + (define fm + (let* ([fm (draw-flomap + w h (λ (dc) + (send dc set-font font) + (send dc set-text-foreground color) + (send dc draw-text str 0 0 #t)))] + [fm (if trim? (flomap-trim fm) fm)] + [fm (flomap-resize fm #f (- height (* 2 ceiling-amt)))] + [fm (flomap-inset fm ceiling-amt)] + [fm (if outline? (flomap-outlined fm outline-amt) fm)]) + fm)) + (flomap-render-icon fm material)))) -(define (x-icon-flomap* color height material) - (define scale (/ height 32)) - (let* ([fm (x-flomap color height)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* -8 scale))]) - (deep-flomap-render-icon dfm material))) +(define (x-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (define scale (/ height 32)) + (let* ([fm (flat-x-flomap color height)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-raise dfm (* -8 scale))]) + (deep-flomap-render-icon dfm material)))) -(define (check-icon-flomap* color height material) - (define scale (/ height 32)) - (let* ([fm (check-flomap color height)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* -12 scale))]) - (deep-flomap-render-icon dfm material))) +(define (check-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (define scale (/ height 32)) + (let* ([fm (flat-check-flomap color height)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-raise dfm (* -12 scale))]) + (deep-flomap-render-icon dfm material)))) -(define (regular-polygon-icon-flomap* sides start color height material) - (flomap-render-icon (regular-polygon-flomap sides start color height) material)) +(define (regular-polygon-flomap sides start color + [height (default-icon-height)] + [material (default-icon-material)]) + (make-cached-flomap + [height sides start color material] + (flomap-render-icon (flat-regular-polygon-flomap sides start color height) material))) -(define (octagon-icon-flomap* color height material) - (regular-polygon-icon-flomap* 8 (/ (* 2 pi) 16) color height material)) +(define (octagon-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (regular-polygon-flomap 8 (/ (* 2 pi) 16) color height material)) -(define (stop-sign-icon-flomap* color height material) - (define scale (/ height 32)) - (let* ([indent-fm (fm* 0.5 (x-flomap "black" (* 22 scale)))] - [indent-dfm (deep-flomap-raise (flomap->deep-flomap indent-fm) (* -2 scale))] - [fm (regular-polygon-flomap 8 (/ (* 2 pi) 16) color height)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-cc-superimpose dfm indent-dfm #:z-mode 'add)] - [dfm (deep-flomap-icon-style dfm)] - [fm (deep-flomap-render-icon dfm material)]) - (flomap-cc-superimpose - fm - (x-icon-flomap* "azure" (* 22 scale) metal-material)))) +(define (stop-sign-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (make-cached-flomap + [height color material] + (define scale (/ height 32)) + (let* ([indent-fm (fm* 0.5 (x-flomap "black" (* 22 scale)))] + [indent-dfm (deep-flomap-raise (flomap->deep-flomap indent-fm) (* -2 scale))] + [fm (regular-polygon-flomap 8 (/ (* 2 pi) 16) color height)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-cc-superimpose dfm indent-dfm #:z-mode 'add)] + [dfm (deep-flomap-icon-style dfm)] + [fm (deep-flomap-render-icon dfm material)]) + (flomap-cc-superimpose fm (x-flomap "azure" (* 22 scale) metal-material))))) ;; --------------------------------------------------------------------------------------------------- ;; Magnifying glass @@ -127,153 +140,158 @@ 0.8 0.1 0.2 0.2 0.8 0.0 0.0)) -(define (magnifying-glass-icon-flomap* metal-color handle-color height material) - (define scale (/ height 32)) - (define glass-fm - (let* ([fm (draw-icon-flomap - 18 18 (λ (dc) - (send dc set-pen handle-color 1 'solid) - (send dc set-brush "azure" 'solid) - (draw-ellipse/smoothed dc 0 0 18 18) - (send dc set-alpha 0.75) - (send dc set-pen "black" 1 'solid) - (send dc set-brush "white" 'transparent) - (draw-ellipse/smoothed dc 0 0 18 18)) - scale)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-bulge-spheroid dfm (* 4 scale))] - [dfm (deep-flomap-raise dfm (* 4 scale))]) - (deep-flomap-render-icon dfm magnifying-glass-material))) - - (define circle-fm - (let* ([fm (draw-icon-flomap - 28 28 (λ (dc) - (send dc set-pen "black" 3 'solid) - (send dc set-brush "black" 'solid) - (draw-ellipse/smoothed dc 1 1 26 26) - (send dc set-pen metal-color 1 'solid) - (send dc set-brush metal-color 'solid) - (draw-ellipse/smoothed dc 1 1 26 26)) - scale)] - [indent-fm (draw-icon-flomap - 28 28 (λ (dc) - (send dc set-pen metal-color 1 'solid) - (send dc set-brush metal-color 'solid) - (draw-ellipse/smoothed dc 5 5 18 18)) - scale)] - [indent-dfm (flomap->deep-flomap indent-fm)] - [indent-dfm (deep-flomap-raise indent-dfm (* -3 scale))] - ;[indent-dfm (deep-flomap-smooth-z indent-dfm (* 2 scale))] - [dfm (flomap->deep-flomap fm)] - ;[dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* 4 scale))] - [dfm (deep-flomap-cc-superimpose dfm indent-dfm #:z-mode 'add)] - [dfm (deep-flomap-smooth-z dfm (* 1 scale))] - ) - (deep-flomap-render-icon dfm magnifying-glass-metal-material))) - - (define handle-fm - (let* ([fm (draw-icon-flomap - 11 11 (λ (dc) - (send dc set-brush handle-color 'solid) - (define p (new dc-path%)) - (send p move-to 4 0) - (send p line-to 10 5) - (send p curve-to 10 8 8 10 5 10) - (send p line-to 0 4) - (send p move-to 4 0) - (send dc draw-path p)) - scale)]) - (flomap-render-icon fm material))) - - (flomap-pin* 0 0 21/28 21/28 - handle-fm - (flomap-pin* 1/2 1/2 1/2 1/2 circle-fm glass-fm))) -(define (left-bomb-icon-flomap* cap-color bomb-color height material) - (define scale (/ height 32)) - (define fuse-fm - (let* ([fm (draw-icon-flomap - 16 16 (λ (dc) - (send dc set-pen "black" 5 'solid) - (draw-path-commands dc 5.5 5.5 '((c (0 . -1) (-2.5 . -4) (-3 . -2.5)))) - (send dc set-pen "orange" 4 'solid) - (draw-path-commands dc 5.5 5.5 '((c (0 . -1) (-2.5 . -4) (-3 . -2.5))))) - scale)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-scale-z dfm 1)]) - (deep-flomap-render-icon dfm matte-material))) - - (define (bomb-cap-flomap color) - (draw-icon-flomap - 20 20 (λ (dc) - (send dc set-pen "black" 1 'solid) - (send dc set-brush color 'solid) - (draw-path-commands - dc 1 11 '((l (10 . -10) (3 . 3)) - (c (4 . 5) (-5 . 14) (-10 . 10)) - (l (-3 . -3)))) - (draw-path-commands - dc 1 11 '((c (-2 . -5) (5 . -12) (10 . -10) - (4 . 5) (-5 . 14) (-10 . 10))))) - scale)) - - (define cap-fm - (let* ([cap-fm (bomb-cap-flomap cap-color)] - [cap-dfm (flomap->deep-flomap cap-fm)] - [cap-dfm (deep-flomap-icon-style cap-dfm)]) - (deep-flomap-render-icon cap-dfm material))) - - (define sphere-fm - (let* ([sphere-fm (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-brush bomb-color 'solid) - (draw-ellipse/smoothed dc 0 0 32 32)) - scale)] - [cap-fm (bomb-cap-flomap cap-color)] - [cap-dfm (flomap->deep-flomap cap-fm)] - [cap-dfm (deep-flomap-raise cap-dfm (* -2 scale))] - [cap-dfm (deep-flomap-smooth-z cap-dfm (* 1 scale))] - [sphere-dfm (flomap->deep-flomap sphere-fm)] - [sphere-dfm (deep-flomap-bulge-spheroid sphere-dfm (* 16 scale))] - [sphere-dfm (deep-flomap-lt-superimpose sphere-dfm cap-dfm #:z-mode 'add)] - ) - (deep-flomap-render-icon sphere-dfm material))) - (flomap-lt-superimpose sphere-fm cap-fm fuse-fm)) +(define (magnifying-glass-flomap metal-color handle-color + [height (default-icon-height)] + [material (default-icon-material)]) + (make-cached-flomap + [height metal-color handle-color material] + (define scale (/ height 32)) + (define glass-fm + (let* ([fm (draw-icon-flomap + 18 18 (λ (dc) + (send dc set-pen handle-color 1 'solid) + (send dc set-brush "azure" 'solid) + (draw-ellipse/smoothed dc 0 0 18 18) + (send dc set-alpha 0.75) + (send dc set-pen "black" 1 'solid) + (send dc set-brush "white" 'transparent) + (draw-ellipse/smoothed dc 0 0 18 18)) + scale)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-bulge-spheroid dfm (* 4 scale))] + [dfm (deep-flomap-raise dfm (* 4 scale))]) + (deep-flomap-render-icon dfm magnifying-glass-material))) + + (define circle-fm + (let* ([fm (draw-icon-flomap + 28 28 (λ (dc) + (send dc set-pen "black" 3 'solid) + (send dc set-brush "black" 'solid) + (draw-ellipse/smoothed dc 1 1 26 26) + (send dc set-pen metal-color 1 'solid) + (send dc set-brush metal-color 'solid) + (draw-ellipse/smoothed dc 1 1 26 26)) + scale)] + [indent-fm (draw-icon-flomap + 28 28 (λ (dc) + (send dc set-pen metal-color 1 'solid) + (send dc set-brush metal-color 'solid) + (draw-ellipse/smoothed dc 5 5 18 18)) + scale)] + [indent-dfm (flomap->deep-flomap indent-fm)] + [indent-dfm (deep-flomap-raise indent-dfm (* -3 scale))] + ;[indent-dfm (deep-flomap-smooth-z indent-dfm (* 2 scale))] + [dfm (flomap->deep-flomap fm)] + ;[dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-raise dfm (* 4 scale))] + [dfm (deep-flomap-cc-superimpose dfm indent-dfm #:z-mode 'add)] + [dfm (deep-flomap-smooth-z dfm (* 1 scale))] + ) + (deep-flomap-render-icon dfm magnifying-glass-metal-material))) + + (define handle-fm + (let* ([fm (draw-icon-flomap + 11 11 (λ (dc) + (send dc set-brush handle-color 'solid) + (define p (new dc-path%)) + (send p move-to 4 0) + (send p line-to 10 5) + (send p curve-to 10 8 8 10 5 10) + (send p line-to 0 4) + (send p move-to 4 0) + (send dc draw-path p)) + scale)]) + (flomap-render-icon fm material))) + + (flomap-pin* 0 0 21/28 21/28 + handle-fm + (flomap-pin* 1/2 1/2 1/2 1/2 circle-fm glass-fm)))) -(define-icon-flomap-proc text-icon-flomap text-icon-flomap* 32 str font color trim? outline?) -(define-icon-flomap-proc regular-polygon-icon-flomap regular-polygon-icon-flomap* 32 color) -(define-icon-flomap-proc octagon-icon-flomap octagon-icon-flomap* 32 color) -(define-icon-flomap-proc x-icon-flomap x-icon-flomap* 24 color) -(define-icon-flomap-proc stop-sign-icon-flomap stop-sign-icon-flomap* 32 color) -(define-icon-flomap-proc check-icon-flomap check-icon-flomap* 32 color) -(define-icon-flomap-proc magnifying-glass-icon-flomap - magnifying-glass-icon-flomap* 32 color metal-color) -(define-icon-flomap-proc left-bomb-icon-flomap left-bomb-icon-flomap* 32 cap-color bomb-color) +;; --------------------------------------------------------------------------------------------------- +;; Bomb -(define (stop-signs-icon-flomap color [height (default-icon-height)] - [icon-material (default-icon-material)]) - (define fm (stop-sign-icon-flomap color (* height 2/3) icon-material)) +(define (left-bomb-flomap cap-color bomb-color + [height (default-icon-height)] + [material (default-icon-material)]) + (make-cached-flomap + [height cap-color bomb-color material] + (define scale (/ height 32)) + (define fuse-fm + (let* ([fm (draw-icon-flomap + 16 16 (λ (dc) + (send dc set-pen "black" 1/2 'solid) + (send dc set-brush "gold" 'solid) + (draw-path-commands + dc 0 0 + '((m 0.5 5.5) + (c -1.5 -2 -0.5 -5 2 -5.5 + 3 0.5 5 2.5 6 5 + 0.5 2.5 -1.5 4.5 -4 4 + -1 -2 -1.5 -3.5 -4 -3.5)))) + scale)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-scale-z dfm 1)]) + (deep-flomap-render-icon dfm matte-material))) + + (define (bomb-cap-flomap color) + (draw-icon-flomap + 20 20 (λ (dc) + (send dc set-pen "black" 1 'solid) + (send dc set-brush color 'solid) + (draw-path-commands dc 0 0 '((m 1.5 11.5) + (l 10 -10 2.5 2.5) + (c 4 5 -5 14 -10 10) + (l -2.5 -2.5))) + (draw-path-commands dc 0 0 '((m 1.5 11.5) + (c -2 -5 5 -12 10 -10 + 4 5 -5 14 -10 10)))) + scale)) + + (define cap-fm + (let* ([cap-fm (bomb-cap-flomap cap-color)] + [cap-dfm (flomap->deep-flomap cap-fm)] + [cap-dfm (deep-flomap-icon-style cap-dfm)]) + (deep-flomap-render-icon cap-dfm material))) + + (define sphere-fm + (let* ([sphere-fm (draw-icon-flomap + 30 30 (λ (dc) + (send dc set-brush bomb-color 'solid) + (draw-ellipse/smoothed dc 0 0 30 30)) + scale)] + [cap-fm (bomb-cap-flomap cap-color)] + [cap-dfm (flomap->deep-flomap cap-fm)] + [cap-dfm (deep-flomap-raise cap-dfm (* -2 scale))] + [cap-dfm (deep-flomap-smooth-z cap-dfm (* 1 scale))] + [sphere-dfm (flomap->deep-flomap sphere-fm)] + [sphere-dfm (deep-flomap-bulge-spheroid sphere-dfm (* 15 scale))] + [sphere-dfm (deep-flomap-inset sphere-dfm 2 2 0 0)] + [sphere-dfm (deep-flomap-lt-superimpose sphere-dfm cap-dfm #:z-mode 'add)] + ) + (deep-flomap-render-icon sphere-dfm material))) + (flomap-lt-superimpose sphere-fm cap-fm fuse-fm))) + +(define (stop-signs-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (define fm (stop-sign-flomap color (* height 2/3) material)) (flomap-pin* 3/16 1/4 0 0 fm (flomap-pin* 3/16 1/4 0 0 fm fm))) -(define left-magnifying-glass-icon-flomap - (compose flomap-flip-horizontal magnifying-glass-icon-flomap)) - -(define bomb-icon-flomap (compose flomap-flip-horizontal left-bomb-icon-flomap)) +(define left-magnifying-glass-flomap (compose flomap-flip-horizontal magnifying-glass-flomap)) +(define bomb-flomap (compose flomap-flip-horizontal left-bomb-flomap)) ;; =================================================================================================== ;; Bitmaps (icons) -(define text-icon (compose flomap->bitmap text-icon-flomap)) -(define regular-polygon-icon (compose flomap->bitmap regular-polygon-icon-flomap)) -(define octagon-icon (compose flomap->bitmap octagon-icon-flomap)) -(define x-icon (compose flomap->bitmap x-icon-flomap)) -(define stop-sign-icon (compose flomap->bitmap stop-sign-icon-flomap)) -(define stop-signs-icon (compose flomap->bitmap stop-signs-icon-flomap)) -(define check-icon (compose flomap->bitmap check-icon-flomap)) -(define magnifying-glass-icon (compose flomap->bitmap magnifying-glass-icon-flomap)) -(define left-magnifying-glass-icon (compose flomap->bitmap left-magnifying-glass-icon-flomap)) -(define bomb-icon (compose flomap->bitmap bomb-icon-flomap)) -(define left-bomb-icon (compose flomap->bitmap left-bomb-icon-flomap)) +(define text-icon (compose flomap->bitmap text-flomap)) +(define regular-polygon-icon (compose flomap->bitmap regular-polygon-flomap)) +(define octagon-icon (compose flomap->bitmap octagon-flomap)) +(define x-icon (compose flomap->bitmap x-flomap)) +(define stop-sign-icon (compose flomap->bitmap stop-sign-flomap)) +(define stop-signs-icon (compose flomap->bitmap stop-signs-flomap)) +(define check-icon (compose flomap->bitmap check-flomap)) +(define magnifying-glass-icon (compose flomap->bitmap magnifying-glass-flomap)) +(define left-magnifying-glass-icon (compose flomap->bitmap left-magnifying-glass-flomap)) +(define bomb-icon (compose flomap->bitmap bomb-flomap)) +(define left-bomb-icon (compose flomap->bitmap left-bomb-flomap)) diff --git a/collects/images/icons/style.rkt b/collects/images/icons/style.rkt index 0042a08f65..16b625afd7 100644 --- a/collects/images/icons/style.rkt +++ b/collects/images/icons/style.rkt @@ -3,8 +3,7 @@ (require racket/draw unstable/parameter-group "../private/flomap.rkt" "../private/deep-flomap.rkt" - "../private/renderfx.rkt" - "../private/transient-box.rkt") + "../private/renderfx.rkt") (provide (all-defined-out)) @@ -31,7 +30,7 @@ (define metal-icon-color "lightsteelblue") (define dark-metal-icon-color "steelblue") -(define syntax-icon-color (make-object color% 38 38 128)) +(define syntax-icon-color (make-object color% 76 76 255)) (define halt-icon-color (make-object color% 255 32 24)) (define run-icon-color "lawngreen") @@ -72,50 +71,3 @@ (let* ([fm (draw-icon-flomap w h draw-proc scale)] [fm (flomap-render-icon fm material)]) fm)) - -(define (clean-cache! h) - (define ks (for*/list ([(k v) (in-hash h)] - [vv (in-value (transient-box-value v))] - #:when (not vv)) - k)) - (for ([k (in-list ks)]) (hash-remove! h k))) - -(define (transient-value-hash-ref! h k thnk) - (thnk) - #;(begin - (define bx (hash-ref! h k (λ () (make-transient-box (thnk))))) - (transient-box-touch! bx) - (define val (transient-box-value bx)) - (cond [val val] - [else (clean-cache! h) - (let ([val (thnk)]) - (hash-set! h k (make-transient-box val)) - val)]))) - -(define caches empty) - -(define (add-cache! cache) (set! caches (cons cache caches))) - -(define (clean-caches!) - (for ([h (in-list caches)]) - (clean-cache! h))) - -(define (read-caches) - (for*/list ([cache (in-list caches)] - [(k v) (in-hash cache)]) - (cons k v))) - -(define-syntax-rule (define-icon-flomap-proc name name* min-height args ...) - (define name - (let ([cache (make-hash)]) - (add-cache! cache) - (λ (args ... - [height (default-icon-height)] - [material (default-icon-material)]) - (cond [(height . < . min-height) - (flomap-scale (transient-value-hash-ref! cache (list args ... min-height material) - (λ () (name* args ... min-height material))) - (/ height min-height))] - [else - (transient-value-hash-ref! cache (list args ... height material) - (λ () (name* args ... height material)))]))))) diff --git a/collects/images/icons/tool.rkt b/collects/images/icons/tool.rkt index 9e448e66b8..5b0052472c 100644 --- a/collects/images/icons/tool.rkt +++ b/collects/images/icons/tool.rkt @@ -11,53 +11,50 @@ (provide (all-defined-out)) -(define (check-syntax-icon-flomap [height (toolbar-icon-height)] - [material (default-icon-material)]) - (flomap-ht-append - (left-magnifying-glass-icon-flomap metal-icon-color syntax-icon-color height material) - (make-flomap 4 (max 1 (inexact->exact (round (* 1/32 height)))) 0) - (check-icon-flomap run-icon-color height material))) +(define debugger-bomb-color (make-object color% 128 64 64)) +(define macro-stepper-hash-color (make-object color% 30 96 30)) -(define (small-check-syntax-icon-flomap [height (toolbar-icon-height)] - [material (default-icon-material)]) +(define (check-syntax-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) + (flomap-ht-append + (left-magnifying-glass-flomap metal-icon-color "chocolate" height material) + (make-flomap 4 (max 1 (inexact->exact (round (* 1/32 height)))) 0) + (check-flomap syntax-icon-color height material))) + +(define (small-check-syntax-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) (flomap-pin* 1 1 5/16 1 - (check-icon-flomap run-icon-color height material) - (magnifying-glass-icon-flomap metal-icon-color syntax-icon-color (* 3/4 height) material))) + (check-flomap syntax-icon-color height material) + (magnifying-glass-flomap metal-icon-color "chocolate" (* 3/4 height) material))) -(define (macro-stepper-icon-flomap [height (toolbar-icon-height)] - [material (default-icon-material)]) +(define (macro-stepper-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) (flomap-ht-append - (text-icon-flomap "#'" (make-object font% 12 'system 'normal 'normal) - run-icon-color #t #t height material) + (text-flomap "#'" (make-object font% 12 'system 'normal 'normal) + macro-stepper-hash-color #t #t height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/32 height)))) 0) - (step-icon-flomap (make-object color% 38 38 128) height material))) + (step-flomap syntax-icon-color height material))) -(define (small-macro-stepper-icon-flomap [height (toolbar-icon-height)] - [material (default-icon-material)]) +(define (small-macro-stepper-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) (flomap-pin* 0 0 7/16 0 - (step-icon-flomap (make-object color% 38 38 128) height material) - (text-icon-flomap "#'" (make-object font% 12 'system 'normal 'bold) - run-icon-color #t #t (* 3/4 height) material))) + (step-flomap syntax-icon-color height material) + (text-flomap "#'" (make-object font% 12 'system 'normal 'bold) + macro-stepper-hash-color #t #t (* 3/4 height) material))) -(define (debugger-icon-flomap [height (toolbar-icon-height)] - [material (default-icon-material)]) +(define (debugger-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) (flomap-ht-append - (left-bomb-icon-flomap metal-icon-color halt-icon-color height material) + (left-bomb-flomap metal-icon-color debugger-bomb-color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) - (step-icon-flomap run-icon-color height material))) + (step-flomap run-icon-color height material))) -(define (small-debugger-icon-flomap [height (toolbar-icon-height)] - [material (default-icon-material)]) +(define (small-debugger-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) (flomap-pin* 0 0 9/16 0 - (step-icon-flomap run-icon-color height material) - (left-bomb-icon-flomap metal-icon-color halt-icon-color (* 3/4 height) material))) + (step-flomap run-icon-color height material) + (left-bomb-flomap metal-icon-color debugger-bomb-color (* 3/4 height) material))) -(define check-syntax-icon (compose flomap->bitmap check-syntax-icon-flomap)) -(define small-check-syntax-icon (compose flomap->bitmap small-check-syntax-icon-flomap)) -(define macro-stepper-icon (compose flomap->bitmap macro-stepper-icon-flomap)) -(define small-macro-stepper-icon (compose flomap->bitmap small-macro-stepper-icon-flomap)) -(define debugger-icon (compose flomap->bitmap debugger-icon-flomap)) -(define small-debugger-icon (compose flomap->bitmap small-debugger-icon-flomap)) +(define check-syntax-icon (compose flomap->bitmap check-syntax-flomap)) +(define small-check-syntax-icon (compose flomap->bitmap small-check-syntax-flomap)) +(define macro-stepper-icon (compose flomap->bitmap macro-stepper-flomap)) +(define small-macro-stepper-icon (compose flomap->bitmap small-macro-stepper-flomap)) +(define debugger-icon (compose flomap->bitmap debugger-flomap)) +(define small-debugger-icon (compose flomap->bitmap small-debugger-flomap)) diff --git a/collects/images/logos.rkt b/collects/images/logos.rkt index 5751014ffe..ac78a25481 100644 --- a/collects/images/logos.rkt +++ b/collects/images/logos.rkt @@ -5,9 +5,10 @@ "private/deep-flomap.rkt" "private/renderfx.rkt" "icons/style.rkt" - "private/unsafe.rkt") + "private/unsafe.rkt" + "private/utils.rkt") -(provide plt-logo) +(provide plt-logo planet-logo) (define glass-logo-material (deep-flomap-material-value @@ -16,44 +17,67 @@ 0.2 0.1 0.1 0.0)) -(define lambda-start-point (cons 235.0 38.0)) -(define lambda-control-points - (list (list (cons -27.07492 0.489079) (cons -52.83237 9.901645) (cons -78.13681 18.608898)) - (list (cons 11.0396 11.823329) (cons 9.37418 15.558039) (cons 14.19246 14.659919)) - (list (cons 18.43869 -4.46584) (cons 45.7868 -14.85883) (cons 57.97111 4.83448)) - (list (cons 26.56443 33.55767) (cons 37.83026 76.50393) (cons 41.85449 118.37596)) - (list (cons 5.15871 25.44003) (cons -47.30403 116.52589) (cons -63.42303 152.88265)) - (list (cons -26.20045 46.22879) (cons -49.47611 94.20521) (cons -78.99673 138.48542)) - (list (cons 7.0596 9.34303) (cons 17.25993 5.68676) (cons 26.86192 4.2502)) - (list (cons 8.19842 -1.22826) (cons 16.39686 -2.4565) (cons 24.59528 -3.68475)) - (list (cons 26.44013 -62.68827) (cons 54.98797 -120.2314) (cons 79.79859 -183.59412)) - (list (cons 11.30581 -26.11293) (cons 16.82865 -40.47628) (cons 30.26123 -57.57618)) - (list (cons 15.92423 9.74246) (cons 20.66525 33.77224) (cons 29.3527 50.35199)) - (list (cons 25.60238 65.87977) (cons 51.09413 131.80228) (cons 75.25809 198.22074)) - (list (cons 6.32468 2.20244) (cons 12.81613 8.78314) (cons 18.81535 2.44056)) - (list (cons 15.78086 -9.73038) (cons 34.15342 -15.82488) (cons 47.2925 -29.27438)) - (list (cons -3.74907 -18.17899) (cons -15.79452 -35.18254) (cons -23.13261 -52.66524)) - (list (cons -46.51473 -92.95952) (cons -91.3634 -191.5622) (cons -120.47873 -291.65949)) - (list (cons -10.72309 -31.50493) (cons -23.92724 -69.469699) (cons -58.05359 -81.906439)) - (list (cons -7.7741 -2.308013) (cons -15.96612 -2.751575) (cons -24.03222 -2.750218)))) - -(define (lambda-path x y x-scale y-scale) - (define (scale-x x) (* x x-scale)) - (define (scale-y y) (* y y-scale)) - (define p (new dc-path%)) - (match-define (cons (app scale-x sx) (app scale-y sy)) lambda-start-point) - (send p move-to sx sy) - (for/fold ([lx sx] [ly sy]) ([pt (in-list lambda-control-points)]) - (match-define (list (cons (app scale-x x1) (app scale-y y1)) - (cons (app scale-x x2) (app scale-y y2)) - (cons (app scale-x x3) (app scale-y y3))) pt) - (send p curve-to (+ lx x1) (+ ly y1) (+ lx x2) (+ ly y2) (+ lx x3) (+ ly y3)) - (values (+ lx x3) (+ ly y3))) - (send p close) - p) +(define lambda-path-commands + '((m 97.5 10) + (c -12.267574371681416 0.22160039646017698 + -23.938206584070794 4.486409061946903 + -35.40358116814159 8.431642279646018 + 5.002013451327434 5.357118980530973 + 4.2474160707964606 7.049306166371681 + 6.430565946902655 6.642370378761062 + 8.354521486725664 -2.0234602477876105 + 20.745877522123894 -6.732496424778761 + 26.26655603539823 2.1904900530973452 + 12.036272707964603 15.204891185840708 + 17.140790371681415 34.66372757522124 + 18.964158300884954 53.635833203539825 + 2.3373978053097346 11.526810053097345 + -21.433330407079644 52.79757139823009 + -28.736806513274335 69.27072283185841 + -11.871354336283186 20.946142017699113 + -22.417494088495573 42.68413054867256 + -35.79320863716814 62.74737614159292 + 3.198686017699115 4.233302088495575 + 7.820428460176991 2.5766558584070793 + 12.171064637168142 1.925754336283186 + 3.714682336283186 -0.5565213451327433 + 7.429373734513274 -1.1130336283185842 + 11.14405607079646 -1.6695504424778762 + 11.979952707964602 -28.4038887079646 + 24.914903221238937 -54.476528141592915 + 36.156529274336286 -83.1860083539823 + 5.122632495575221 -11.831699256637167 + 7.625016637168141 -18.33969500884956 + 13.711282973451327 -26.087614300884955 + 7.215226336283186 4.414282761061947 + 9.363369911504424 15.302112283185838 + 13.299630442477875 22.814352991150443 + 11.600370407079646 29.849948884955747 + 23.150614654867255 59.71926315044247 + 34.09924077876106 89.81329104424779 + 2.8656957168141592 0.9979197168141594 + 5.806954477876106 3.9796174159292033 + 8.525185132743362 1.105811256637168 + 7.150265769911504 -4.4088093451327435 + 15.474823929203538 -7.170211115044248 + 21.428106194690265 -13.26414385840708 + -1.6986936637168142 -8.23685210619469 + -7.156455079646018 -15.941115469026549 + -10.48132417699115 -23.86248042477876 + -21.07570067256637 -42.11971171681416 + -41.39651398230088 -86.79632424778761 + -54.5885927079646 -132.15014060176992 + -4.858603610619468 -14.274800141592921 + -10.841368920353982 -31.4765361840708 + -26.303927504424777 -37.111590060176994 + -3.5224240707964602 -1.0457545628318583 + -7.2342065840707965 -1.2467313274336282 + -10.888935079646018 -1.2461164743362831))) (define (draw-lambda dc x y w h) - (send dc draw-path (lambda-path x y (/ w 565) (/ h 565)))) + (define-values (sx sy) (send dc get-scale)) + (draw-path-commands dc x y (scale-path-commands lambda-path-commands (/ w 240) (/ h 240))) + (send dc set-scale sx sy)) (define blue-θ-start (* -45 (/ pi 180))) (define blue-θ-end (* 110 (/ pi 180))) @@ -84,70 +108,205 @@ (unsafe-fl* g l) (unsafe-fl* b l))))) -(define (flomap-rough fm z-amt) - (match-define (flomap vs c w h) fm) - (unsafe-build-flomap - c w h - (λ (k x y) - (define i (unsafe-fx+ k (unsafe-fx* c (unsafe-fx+ x (unsafe-fx* w y))))) - (unsafe-fl+ (unsafe-fl* z-amt (exact->inexact (random))) - (unsafe-flvector-ref vs i))))) +(define (make-random-flomap c w h) + (unsafe-build-flomap c w h (λ (k x y) (random)))) -(define (plt-logo height) - (define scale (/ height 256)) - (define bulge-fm - (draw-flomap - height height - (λ (dc) - (send dc set-scale scale scale) - (send dc set-pen logo-red-color 2 'solid) - (send dc set-brush logo-red-color 'solid) - (send dc draw-path (make-arc-path 7 7 242 242 blue-θ-end blue-θ-start)) - (send dc set-pen logo-blue-color 2 'solid) - (send dc set-brush logo-blue-color 'solid) - (send dc draw-path (make-arc-path 7 7 242 242 blue-θ-start blue-θ-end)) - (send dc set-pen (lambda-pen lambda-outline-color 12)) - (send dc set-brush lambda-outline-color 'solid) - (draw-lambda dc 0 0 256 256)))) - - ;(flomap-add-sparkles! bulge-fm) - - (define (lambda-flomap color pen-width) - (draw-flomap - height height - (λ (dc) - (send dc set-scale scale scale) - (send dc set-pen (lambda-pen color pen-width)) - (send dc set-brush color 'solid) - (draw-lambda dc 0 0 256 256)))) - - (let* ([bulge-dfm (flomap->deep-flomap bulge-fm)] - [bulge-dfm (deep-flomap-bulge-spheroid bulge-dfm (* 116 scale))] - ;[bulge-dfm (deep-flomap-raise bulge-dfm (* 8 scale))] - ;[bulge-dfm (deep-flomap-smooth-z bulge-dfm (* 1/2 scale))] - #;[bulge-dfm (deep-flomap (deep-flomap-argb bulge-dfm) - (flomap-rough (deep-flomap-z bulge-dfm) 0.5))] - [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] - [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 116 scale))] - [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] - [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] - [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] - [fm (flomap-cc-superimpose - fm - (lambda-flomap lambda-outline-color 12) - lambda-fm)] - [fm (flomap-inset fm 16)] - [fm (flomap-cc-superimpose - fm - (draw-flomap - (inexact->exact (ceiling (* 1.015625 height))) - (inexact->exact (ceiling (* 1.015625 height))) - (λ (dc) - (send dc set-scale scale scale) - (send dc set-origin (* 2.5 scale) (* 2.5 scale)) - (send dc set-pen lambda-outline-color 4 'solid) - (send dc set-brush lambda-outline-color 'transparent) - (send dc draw-ellipse 0 0 256 256))))] - [fm (flomap-cc-superimpose (fm* 0.5 (flomap-shadow fm (* 4 scale))) fm)] - ) - (flomap->bitmap fm))) +(define (flomap-rough fm z-amt) + (match-define (flomap _ c w h) fm) + (fm+ fm (fm* z-amt (make-random-flomap c w h)))) + +(define (plt-flomap height) + (make-cached-flomap + [height] + (define scale (/ height 256)) + (define bulge-fm + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-pen logo-red-color 2 'transparent) + (send dc set-brush logo-red-color 'solid) + (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-end blue-θ-start)) + (send dc set-pen logo-blue-color 2 'transparent) + (send dc set-brush logo-blue-color 'solid) + (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-start blue-θ-end)) + (send dc set-pen (lambda-pen lambda-outline-color 10)) + (send dc set-brush lambda-outline-color 'solid) + (draw-lambda dc 8 8 240 240)) + scale)) + + ;(flomap-add-sparkles! bulge-fm) + + (define (lambda-flomap color pen-width) + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-scale scale scale) + (send dc set-pen (lambda-pen color pen-width)) + (send dc set-brush color 'solid) + (draw-lambda dc 8 8 240 240)) + scale)) + + (let* ([bulge-dfm (flomap->deep-flomap bulge-fm)] + [bulge-dfm (deep-flomap-bulge-spheroid bulge-dfm (* 112 scale))] + ;[bulge-dfm (deep-flomap-raise bulge-dfm (* 8 scale))] + ;[bulge-dfm (deep-flomap-smooth-z bulge-dfm (* 1/2 scale))] + #;[bulge-dfm (deep-flomap (deep-flomap-argb bulge-dfm) + (flomap-rough (deep-flomap-z bulge-dfm) 0.5))] + [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] + [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 112 scale))] + [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] + [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] + [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] + [fm (flomap-cc-superimpose + fm + (lambda-flomap lambda-outline-color 10) + lambda-fm)] + [fm (flomap-cc-superimpose + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-pen "lightblue" 2 'solid) + (send dc set-brush "white" 'transparent) + (send dc draw-ellipse 7 7 242 242) + (send dc set-pen lambda-outline-color 4 'solid) + (send dc draw-ellipse 2 2 252 252)) + scale) + fm)] + ) + fm))) + +(define plt-logo (compose flomap->bitmap plt-flomap)) + +(define continents-path-commands + '((m 11.526653 18.937779) + (c 0.05278 0.724075 1.940414 1.202607 0.678885 2.296248 + 0.249172 0.918181 1.040063 1.620575 1.448285 0.308034 + 1.219485 -0.885607 3.250882 -0.938443 3.317014 -2.906655 + -1.599965 -1.033954 -4.029479 -0.431148 -5.444184 0.302373) + (M 11.53125 18.125) + (C 10.786965 18.380649 9.3917452 18.611001 9.1304904 19.245707 + 10.289001 19.269837 11.178405 18.606302 11.53125 18.125) + (M 8.1875 19.65625) + (C 7.2652998 23.370888 8.6787734 19.63772 9.9124431 20.95891 + 10.727811 21.80382 11.739516 20.92275 10.465247 20.422456 + 9.7714766 19.980166 8.3964342 19.699414 8.1875 19.65625) + (M 7.5625 21.125) + (c -0.9196331 -1.962382 -3.205955 1.390782 -4.0978229 2.41995 + -1.707808 2.289408 -2.72190385 5.078558 -2.9334271 7.9238 + 1.0237952 1.983695 5.5272247 2.76676 4.7145431 4.084262 + -0.7368064 1.151552 -0.8906555 2.601652 0.1135446 3.680893 + 2.7495495 2.364498 1.2541019 5.824595 2.5609489 6.229519 + 2.5755284 0.853846 2.7512924 -3.696022 4.1297234 -3.843434 + 0.745066 -1.051147 0.04765 -2.428466 1.056101 -3.411232) + (C 12.318556 36.222109 8.8169859 35.479018 8.6188979 33.8253 + 7.7181807 34.141675 7.0679715 33.334232 6.30372 33.30415 + 5.7220663 34.646967 3.9378253 34.122031 4.3012403 32.699798 + 3.024533 33.043038 4.3605584 31.222879 3.40625 31.28125 + 0.5 33 2.5 26.5 5.0295875 29.903027 + 5.5 30.5 6.9002733 26.371666 8.8261905 25.876953 + 9.8027554 25.533149 9.5159021 24.727855 8.5279357 25.0625 + 7.6214946 24.941384 9.6975411 24.462771 10.075856 24.483273 + 11.540792 24.233047 9.904685 23.334106 9.8601011 22.602389 + 9.0900535 22.676405 9.4028275 22.737933 9.1185443 22.100147 + 6.8948741 22.58513 7.6831847 24.739145 5.9002404 23.244912 + 4.6247757 22.264239 7.321322 21.942832 7.5625 21.125) + (m 15.15625 -0.9375) + (c -1.37421 0.06218 -2.005432 1.159129 -2.784107 1.978327 + -0.114565 1.368674 0.952693 -0.07002 1.385771 0.968032 + 0.953881 -0.129572 -0.01507 -1.993413 1.425543 -2.008859 + -0.269351 0.525838 -0.494795 1.470731 0.411144 1.15174 + -0.646943 0.90275 -1.874871 2.045333 -2.613442 0.960703 + 0.08813 0.809648 -1.042388 0.509104 -1.186702 1.40851 + -0.738698 0.338761 -1.028513 0.375271 -0.383294 1.119927 + -1.340908 -0.226887 -1.979854 2.002883 -0.346874 1.903539 + 3.128783 -3.578714 2.7333 -0.07275 3.379252 -0.61531 + -0.408321 -3.069544 0.823059 1.69915 1.30948 -0.328623 + 0.476726 0.916648 1.583858 0.757279 2.129612 1.386838 + -2.140558 2.214946 -4.171988 -1.055384 -6.363065 -0.232922 + -2.486751 0.823935 -2.418258 3.347586 -3.103635 4.864439 + 0.687061 3.597921 3.669743 1.43585 5.132502 2.724104 + -0.344691 1.08929 0.484513 1.884668 0.473244 3.022942 + -0.01352 2.068761 0.378264 6.65826 1.845318 5.542497 + 1.472489 0.175399 1.430793 -1.740909 2.30904 -2.30502 + -1.36358 -1.181833 2.025569 -1.358588 0.887958 -2.838158 + -0.499809 -1.988948 1.367195 -3.177085 1.789594 -4.928946 + 0.579613 -0.960476 -1.588234 -0.05789 -0.373062 -1.023304 + 0.927113 -0.301781 2.379761 -2.07879 0.994298 -2.428506 + -0.676988 0.933612 -1.737597 -2.080985 -0.549773 -0.651497 + 0.699549 -0.419557 1.900516 1.563553 1.759683 -0.08984 + -0.608903 -3.386912 -2.4601 -6.520148 -5.090986 -8.736865 + -0.200722 0.802307 -1.230158 0.889683 -1.228926 0.0694 + 2.155263 -0.50116 -0.789058 -0.572123 -1.208573 -0.913148) + (M 17.09375 21) + (c -1.221276 0.05745 -0.44882 1.331427 0.232503 0.449916) + (C 17.458514 21.23484 17.234278 21.104353 17.09375 21) + (m -7.5 0.125) + (c -1.2040413 0.60218 1.459244 1.052142 0.289004 0.112253) + (m 8.96875 1.5) + (c 0.38412 0.655402 -0.236077 2.74213 1.030518 1.55154 + 0.0634 -0.524592 -0.59842 -1.401743 -1.030518 -1.55154) + (m -0.21875 0.75) + (c -1.155615 0.198578 0.509999 1.388302 0.06733 0.201634) + (M 10.5 24.53125) + (c -0.117519 1.313533 1.058399 0.642504 0 0))) + +(define water-logo-material + (deep-flomap-material-value + 'cubic-zirconia 1.0 0.7 1.0 + 0.25 0.15 1.0 + 0.15 0.1 0.2 + 0.0)) + +(define logo-under-continents-color "black") +(define logo-continents-color "azure") +(define logo-water-color "lightskyblue") +(define logo-earth-outline-color logo-red-color) + +(define (continents-flomap color height) + (define scale (/ height 32)) + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen lambda-outline-color 3/8 'solid) + (send dc set-brush color 'solid) + (draw-path-commands dc 0 -17 continents-path-commands)) + scale)) + +(define (planet-flomap height) + (make-cached-flomap + [height] + (define scale (/ height 32)) + (define-values (earth-fm earth-z) + (let* ([indent-fm (continents-flomap logo-red-color height)] + [indent-dfm (flomap->deep-flomap indent-fm)] + [indent-dfm (deep-flomap-raise indent-dfm (* -1/8 scale))] + [indent-dfm (deep-flomap-smooth-z indent-dfm (* 1 scale))] + [earth-fm (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen logo-water-color 1/2 'solid) + (send dc set-brush logo-water-color 'solid) + (draw-ellipse/smoothed dc 0.75 0.75 30.5 30.5)) + scale)] + [earth-dfm (flomap->deep-flomap earth-fm)] + [earth-dfm (deep-flomap-bulge-spheroid earth-dfm (* 16 scale))] + [earth-dfm (deep-flomap-cc-superimpose earth-dfm indent-dfm #:z-mode 'add)]) + (values (deep-flomap-render-icon earth-dfm water-logo-material) + (deep-flomap-z earth-dfm)))) + + (define land-fm + (let* ([land-fm (continents-flomap logo-continents-color height)] + [land-dfm (flomap->deep-flomap land-fm)] + ;[land-dfm (deep-flomap-emboss land-dfm (* 2 scale) (* 8 scale))] + [land-dfm (deep-flomap-bulge-spheroid land-dfm (* 16 scale))] + [land-dfm (deep-flomap-smooth-z land-dfm (* 1/2 scale))]) + (deep-flomap-render-icon land-dfm metal-material))) + + (flomap-cc-superimpose + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen "lightblue" 1/2 'solid) + (send dc set-brush "white" 'transparent) + (send dc draw-ellipse 0.5 0.5 31 31) + (send dc set-pen lambda-outline-color 1/2 'solid) + (send dc draw-ellipse -0.25 -0.25 32.5 32.5)) + scale) + earth-fm + land-fm))) + +(define planet-logo (compose flomap->bitmap planet-flomap)) diff --git a/collects/images/private/transient-box.rkt b/collects/images/private/transient-box.rkt deleted file mode 100644 index 431917eb63..0000000000 --- a/collects/images/private/transient-box.rkt +++ /dev/null @@ -1,57 +0,0 @@ -#lang racket - -(require ffi/unsafe) - -(provide make-transient-box transient-box? - (rename-out [transient-box-value* transient-box-value]) - transient-box-touch!) - -(define (register-gc-callback f) - (define v (make-vector 0)) - (register-finalizer v (λ (x) (when (f) (register-gc-callback f))))) - -(struct transient-box (value counter max-counter touched?) #:mutable #:transparent) - -(struct no-value-struct ()) -(define no-value (no-value-struct)) - -(define (make-transient-box value) - (define bx (transient-box value 1 1 #f)) - (register-gc-callback - (λ () - (define cnt (transient-box-counter bx)) - (cond [(cnt . <= . 0) - (cond [(transient-box-touched? bx) - (define max-cnt (* 2 (transient-box-max-counter bx))) - (set-transient-box-counter! bx max-cnt) - (set-transient-box-max-counter! bx max-cnt) - (set-transient-box-touched?! bx #f) - #t] - [else - (set-transient-box-value! bx no-value) - #f])] - [else - (set-transient-box-counter! bx (- cnt 1)) - #t]))) - bx) - -(define (transient-box-value* bx [gced-value #f]) - (define value (transient-box-value bx)) - (if (eq? value no-value) gced-value value)) - -(define (transient-box-touch! bx) - (set-transient-box-touched?! bx #t)) - -#| -(define bx (make-transient-box (make-vector 0))) -(transient-box-value* bx) -bx -(collect-garbage) -bx -(transient-box-value* bx) -bx -(collect-garbage) -bx -(collect-garbage) -bx -|# diff --git a/collects/images/private/utils.rkt b/collects/images/private/utils.rkt index f73e0d2c74..48794567ec 100644 --- a/collects/images/private/utils.rkt +++ b/collects/images/private/utils.rkt @@ -1,9 +1,74 @@ #lang racket/base -(require racket/draw racket/class racket/match racket/list) +(require racket/draw racket/class racket/match racket/list ffi/unsafe + (for-syntax racket/base) + "flomap.rkt") (provide (all-defined-out)) +(define (register-gc-callback proc) + (define val (box 0)) + (register-finalizer val (λ (_) + (define again? (proc)) + (when again? (register-gc-callback proc))))) + +(define (weak-value-hash-clean! h) + (define ks (for*/list ([(k bx) (in-hash h)] + [val (in-value (weak-box-value bx))] + #:when (not val)) + k)) + (for ([k (in-list ks)]) (hash-remove! h k))) + +;(define total-time-saved 0) +;(define total-time-spent 0) + +;; Can't simply wrap hash-ref! with weak-box-value and thnk with make-weak-box, because +;; 1. If weak-box-value returns #f, we need to regenerate the value +;; 2. We need to keep a handle to the generated value while it's being stored in the hash +(define (weak-value-hash-ref! h k thnk) + (define (cache-ref!) + ;(define start (current-milliseconds)) + (define val (thnk)) + ;(define time (- (current-milliseconds) start)) + ;(set! total-time-spent (+ total-time-spent time)) + ;(printf "total-time-spent = ~v~n" total-time-spent) + (hash-set! h k (cons (make-weak-box val) 0)) + val) + (cond [(hash-has-key? h k) (define p (hash-ref h k)) + (define val (weak-box-value (car p))) + (cond [val ;(set! total-time-saved (+ total-time-saved (cdr p))) + ;(printf "total-time-saved = ~v~n" total-time-saved) + val] + [else (cache-ref!)])] + [else (cache-ref!)])) + +(define flomap-cache (make-hash)) + +(define (clean-flomap-cache!) + (weak-value-hash-clean! flomap-cache)) + +(register-gc-callback clean-flomap-cache!) + +(define (read-flomap-cache) + (for/list ([(k bx) (in-hash flomap-cache)]) + (cons k (weak-box-value bx)))) + +(define (make-cached-flomap* name proc size . args) + (define rendered-size + (cond [(size . < . 32) 32] + [else (expt 2 (inexact->exact (ceiling (/ (log size) (log 2)))))])) + (define fm (weak-value-hash-ref! flomap-cache (list name rendered-size args) + (λ () (apply proc rendered-size args)))) + (flomap-scale fm (/ size rendered-size))) + +(define-syntax (make-cached-flomap stx) + (syntax-case stx () + [(_ (size args ...) expr0 expr ...) + (with-syntax ([(name) (generate-temporaries #'(make-cached-flomap))]) + (syntax/loc stx + (make-cached-flomap* 'name (λ (size args ...) expr0 expr ...) size args ...)))])) + + (define (draw-ellipse/smoothed dc x y w h) (define pen (send dc get-pen)) (define brush (send dc get-brush)) @@ -25,22 +90,22 @@ [`(M) (loop x y (rest cmds))] [`(L) (loop x y (rest cmds))] [`(C) (loop x y (rest cmds))] - [`(M (,ax . ,ay) ,as ...) (send p move-to ax ay) - (loop ax ay (cons `(M ,@as) (rest cmds)))] - [`(L (,ax . ,ay) ,as ...) (send p line-to ax ay) - (loop ax ay (cons `(L ,@as) (rest cmds)))] - [`(C (,ax1 . ,ay1) (,ax2 . ,ay2) (,ax . ,ay) ,as ...) + [`(M ,ax ,ay ,as ...) (send p move-to ax ay) + (loop ax ay (cons `(M ,@as) (rest cmds)))] + [`(L ,ax ,ay ,as ...) (send p line-to ax ay) + (loop ax ay (cons `(L ,@as) (rest cmds)))] + [`(C ,ax1 ,ay1 ,ax2 ,ay2 ,ax ,ay ,as ...) (send p curve-to ax1 ay1 ax2 ay2 ax ay) (loop ax ay (cons `(C ,@as) (rest cmds)))] ;; relative commands [`(m) (loop x y (rest cmds))] [`(l) (loop x y (rest cmds))] [`(c) (loop x y (rest cmds))] - [`(m (,dx . ,dy) ,ds ...) (send p move-to (+ x dx) (+ y dy)) - (loop (+ x dx) (+ y dy) (cons `(m ,@ds) (rest cmds)))] - [`(l (,dx . ,dy) ,ds ...) (send p line-to (+ x dx) (+ y dy)) - (loop (+ x dx) (+ y dy) (cons `(l ,@ds) (rest cmds)))] - [`(c (,dx1 . ,dy1) (,dx2 . ,dy2) (,dx . ,dy) ,ds ...) + [`(m ,dx ,dy ,ds ...) (send p move-to (+ x dx) (+ y dy)) + (loop (+ x dx) (+ y dy) (cons `(m ,@ds) (rest cmds)))] + [`(l ,dx ,dy ,ds ...) (send p line-to (+ x dx) (+ y dy)) + (loop (+ x dx) (+ y dy) (cons `(l ,@ds) (rest cmds)))] + [`(c ,dx1 ,dy1 ,dx2 ,dy2 ,dx ,dy ,ds ...) (send p curve-to (+ dx1 x) (+ dy1 y) (+ dx2 x) (+ dy2 y) (+ dx x) (+ dy y)) (loop (+ x dx) (+ y dy) (cons `(c ,@ds) (rest cmds)))] [_ (error 'apply-path-commands "unknown path command ~e" cmd)])])) @@ -48,8 +113,27 @@ (define (draw-path-commands dc x y cmds) (define p (new dc-path%)) - (apply-path-commands p (cons `(M (,x . ,y)) cmds)) - (send dc draw-path p)) + (apply-path-commands p cmds) + (define t (send dc get-transformation)) + (send dc translate x y) + (send dc draw-path p) + (send dc set-transformation t)) + +(define (list->pairs lst) + (match lst + [(list x y xs ...) (cons (cons x y) (list->pairs xs))] + [(list) (list)])) + +(define (scale-path-commands cmds sx sy) + (match cmds + [(list `(,sym ,xys ...) cmds ...) + (cons + `(,sym ,@(flatten (map (λ (xy) + (match-define (cons x y) xy) + (list (* x sx) (* y sy))) + (list->pairs xys)))) + (scale-path-commands cmds sx sy))] + [(list) (list)])) (define (get-text-size str font) (define bm (make-bitmap 1 1)) From c8c8fdf36019c01c09062442dcaba66f5af1d099 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Sun, 8 Jan 2012 23:18:15 -0700 Subject: [PATCH 459/746] Contract fix (cherry picked from commit be4bfdff4cd0a821a6697b46b1cde09d23654da4) --- collects/images/private/flomap.rkt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/collects/images/private/flomap.rkt b/collects/images/private/flomap.rkt index 5188475d3a..fb986fcfa3 100644 --- a/collects/images/private/flomap.rkt +++ b/collects/images/private/flomap.rkt @@ -59,9 +59,7 @@ [fmmin ((or/c flomap? real?) (or/c flomap? real?) . -> . flomap?)] [fmmax ((or/c flomap? real?) (or/c flomap? real?) . -> . flomap?)] ;; Blur - [flomap-gaussian-blur ((flomap? real?) - (real? #:x-stddevs real? #:y-stddevs real?) - . ->* . flomap?)] + [flomap-gaussian-blur ((flomap? real?) (real? real? real?) . ->* . flomap?)] [flomap-box-blur ((flomap? real?) (real?) . ->* . flomap?)] [flomap-blur ((flomap? real?) (real?) . ->* . flomap?)] ;[flomap-integral (flomap? . -> . flomap?)] @@ -119,10 +117,10 @@ [flomap-hc-append ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] [flomap-hb-append ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] ;; Effects - [flomap-outline ([flomap? real?] [#:color (or/c real? (listof real?))] . ->* . flomap?)] - [flomap-outlined ([flomap? real?] [#:color (or/c real? (listof real?))] . ->* . flomap?)] - [flomap-shadow ([flomap? real?] [#:color (or/c real? (listof real?))] . ->* . flomap?)] - [flomap-shadowed ([flomap? real?] [#:color (or/c real? (listof real?))] . ->* . flomap?)] + [flomap-outline ([flomap? real?] [#:color (or/c #f (listof real?))] . ->* . flomap?)] + [flomap-outlined ([flomap? real?] [#:color (or/c #f (listof real?))] . ->* . flomap?)] + [flomap-shadow ([flomap? real?] [#:color (or/c #f (listof real?))] . ->* . flomap?)] + [flomap-shadowed ([flomap? real?] [#:color (or/c #f (listof real?))] . ->* . flomap?)] ) unsafe-build-flomap flomap-lift/unsafe @@ -445,7 +443,7 @@ ;; =================================================================================================== ;; Gaussian blur -(define (flomap-gaussian-blur fm xσ [yσ xσ] #:x-stddevs [x-stddevs 3.0] #:y-stddevs [y-stddevs 3.0]) +(define (flomap-gaussian-blur fm xσ [yσ xσ] [x-stddevs 3.0] [y-stddevs 3.0]) (flomap-gaussian-blur-y (flomap-gaussian-blur-x fm (abs (exact->inexact xσ)) (abs (exact->inexact x-stddevs))) (abs (exact->inexact yσ)) (abs (exact->inexact y-stddevs)))) From 789756eb60db645d354d1c47f20bed8b76113321 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Tue, 10 Jan 2012 13:29:00 -0700 Subject: [PATCH 460/746] Rewrote flomaps and rendering in Typed Racket for speed and safety (cherry picked from commit daf3ed55bae4e84fd6ecf495e7cfe0a74735eefb) --- collects/images/icons/control.rkt | 1 - collects/images/icons/file.rkt | 9 +- collects/images/icons/misc.rkt | 8 +- collects/images/icons/style.rkt | 3 +- collects/images/icons/tool.rkt | 1 - collects/images/logos.rkt | 36 +- .../images/private/deep-flomap-parameters.rkt | 33 + .../images/private/deep-flomap-render.rkt | 530 ++++++++ .../images/private/deep-flomap-struct.rkt | 482 +++++++ .../deep-flomap-untyped-parameters.rkt | 117 ++ collects/images/private/deep-flomap.rkt | 491 +------ collects/images/private/draw-predicates.rkt | 11 + collects/images/private/flomap-blur.rkt | 338 +++++ collects/images/private/flomap-composite.rkt | 103 ++ collects/images/private/flomap-convert.rkt | 87 ++ collects/images/private/flomap-effects.rkt | 67 + collects/images/private/flomap-gradient.rkt | 74 ++ collects/images/private/flomap-pointwise.rkt | 121 ++ collects/images/private/flomap-resize.rkt | 221 +++ collects/images/private/flomap-stats.rkt | 55 + collects/images/private/flomap-struct.rkt | 160 +++ collects/images/private/flomap-transform.rkt | 40 + collects/images/private/flomap.rkt | 1181 +---------------- collects/images/private/flonum.rkt | 102 ++ collects/images/private/renderfx.rkt | 640 --------- collects/images/private/unsafe.rkt | 243 ---- collects/images/private/utils.rkt | 42 +- collects/images/tests/icon-tests.rkt | 3 +- collects/images/tests/logo-tests.rkt | 1 + 29 files changed, 2628 insertions(+), 2572 deletions(-) create mode 100644 collects/images/private/deep-flomap-parameters.rkt create mode 100644 collects/images/private/deep-flomap-render.rkt create mode 100644 collects/images/private/deep-flomap-struct.rkt create mode 100644 collects/images/private/deep-flomap-untyped-parameters.rkt create mode 100644 collects/images/private/draw-predicates.rkt create mode 100644 collects/images/private/flomap-blur.rkt create mode 100644 collects/images/private/flomap-composite.rkt create mode 100644 collects/images/private/flomap-convert.rkt create mode 100644 collects/images/private/flomap-effects.rkt create mode 100644 collects/images/private/flomap-gradient.rkt create mode 100644 collects/images/private/flomap-pointwise.rkt create mode 100644 collects/images/private/flomap-resize.rkt create mode 100644 collects/images/private/flomap-stats.rkt create mode 100644 collects/images/private/flomap-struct.rkt create mode 100644 collects/images/private/flomap-transform.rkt create mode 100644 collects/images/private/flonum.rkt delete mode 100644 collects/images/private/renderfx.rkt delete mode 100644 collects/images/private/unsafe.rkt diff --git a/collects/images/icons/control.rkt b/collects/images/icons/control.rkt index ce523b644e..e0eb70afb8 100644 --- a/collects/images/icons/control.rkt +++ b/collects/images/icons/control.rkt @@ -1,7 +1,6 @@ #lang racket/base (require racket/class - racket/serialize web-server/lang/serial-lambda "../private/flomap.rkt" "../private/utils.rkt" "style.rkt") diff --git a/collects/images/icons/file.rkt b/collects/images/icons/file.rkt index d8a0477fd5..4d7fedd6f1 100644 --- a/collects/images/icons/file.rkt +++ b/collects/images/icons/file.rkt @@ -3,7 +3,6 @@ (require racket/draw racket/class "../private/flomap.rkt" "../private/deep-flomap.rkt" - "../private/renderfx.rkt" "../private/utils.rkt" "arrow.rkt" "style.rkt") @@ -84,12 +83,12 @@ (define disk-fm (let* ([dfm (deep-flomap-ct-superimpose + 'add (deep-flomap-cb-superimpose + 'add (flomap->deep-flomap case-fm) - (deep-flomap-raise (flomap->deep-flomap bottom-indent-fm) (* -4 scale)) - #:z-mode 'add) - (deep-flomap-raise (flomap->deep-flomap top-indent-fm) (* -1 scale)) - #:z-mode 'add)] + (deep-flomap-raise (flomap->deep-flomap bottom-indent-fm) (* -4 scale))) + (deep-flomap-raise (flomap->deep-flomap top-indent-fm) (* -1 scale)))] [dfm (deep-flomap-icon-style dfm)]) (deep-flomap-render-icon dfm material))) diff --git a/collects/images/icons/misc.rkt b/collects/images/icons/misc.rkt index 264fa5dfad..316d374acc 100644 --- a/collects/images/icons/misc.rkt +++ b/collects/images/icons/misc.rkt @@ -3,7 +3,6 @@ (require racket/draw racket/class racket/math racket/sequence "../private/flomap.rkt" "../private/deep-flomap.rkt" - "../private/renderfx.rkt" "../private/utils.rkt" "style.rkt") @@ -119,7 +118,7 @@ [indent-dfm (deep-flomap-raise (flomap->deep-flomap indent-fm) (* -2 scale))] [fm (regular-polygon-flomap 8 (/ (* 2 pi) 16) color height)] [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-cc-superimpose dfm indent-dfm #:z-mode 'add)] + [dfm (deep-flomap-cc-superimpose 'add dfm indent-dfm)] [dfm (deep-flomap-icon-style dfm)] [fm (deep-flomap-render-icon dfm material)]) (flomap-cc-superimpose fm (x-flomap "azure" (* 22 scale) metal-material))))) @@ -185,7 +184,7 @@ [dfm (flomap->deep-flomap fm)] ;[dfm (deep-flomap-icon-style dfm)] [dfm (deep-flomap-raise dfm (* 4 scale))] - [dfm (deep-flomap-cc-superimpose dfm indent-dfm #:z-mode 'add)] + [dfm (deep-flomap-cc-superimpose 'add dfm indent-dfm)] [dfm (deep-flomap-smooth-z dfm (* 1 scale))] ) (deep-flomap-render-icon dfm magnifying-glass-metal-material))) @@ -268,8 +267,7 @@ [sphere-dfm (flomap->deep-flomap sphere-fm)] [sphere-dfm (deep-flomap-bulge-spheroid sphere-dfm (* 15 scale))] [sphere-dfm (deep-flomap-inset sphere-dfm 2 2 0 0)] - [sphere-dfm (deep-flomap-lt-superimpose sphere-dfm cap-dfm #:z-mode 'add)] - ) + [sphere-dfm (deep-flomap-lt-superimpose 'add sphere-dfm cap-dfm)]) (deep-flomap-render-icon sphere-dfm material))) (flomap-lt-superimpose sphere-fm cap-fm fuse-fm))) diff --git a/collects/images/icons/style.rkt b/collects/images/icons/style.rkt index 16b625afd7..ae3c8184b3 100644 --- a/collects/images/icons/style.rkt +++ b/collects/images/icons/style.rkt @@ -2,8 +2,7 @@ (require racket/draw unstable/parameter-group "../private/flomap.rkt" - "../private/deep-flomap.rkt" - "../private/renderfx.rkt") + "../private/deep-flomap.rkt") (provide (all-defined-out)) diff --git a/collects/images/icons/tool.rkt b/collects/images/icons/tool.rkt index 5b0052472c..33ce9166b6 100644 --- a/collects/images/icons/tool.rkt +++ b/collects/images/icons/tool.rkt @@ -3,7 +3,6 @@ (require racket/draw racket/class racket/math racket/sequence "../private/flomap.rkt" "../private/deep-flomap.rkt" - "../private/renderfx.rkt" "../private/utils.rkt" "control.rkt" "misc.rkt" diff --git a/collects/images/logos.rkt b/collects/images/logos.rkt index ac78a25481..56da35d64e 100644 --- a/collects/images/logos.rkt +++ b/collects/images/logos.rkt @@ -3,9 +3,7 @@ (require racket/draw racket/class racket/match racket/math racket/flonum "private/flomap.rkt" "private/deep-flomap.rkt" - "private/renderfx.rkt" "icons/style.rkt" - "private/unsafe.rkt" "private/utils.rkt") (provide plt-logo planet-logo) @@ -93,23 +91,8 @@ (send p close) p) -(define (flomap-add-sparkles! fm) - (match-define (flomap vs c w h) fm) - (for ([_ (in-range 2000)]) - (define x (random w)) - (define y (random h)) - (define i (unsafe-fx* c (unsafe-fx+ x (unsafe-fx* w y)))) - (define a (flvector-ref vs i)) - (when (a . > . 0) - (define l (unsafe-fl+ 0.5 (unsafe-fl* 1.5 (random)))) - (define-values (r g b) (unsafe-flvector-3ref vs (unsafe-fx+ 1 i))) - (unsafe-flvector-3set! vs (unsafe-fx+ 1 i) - (unsafe-fl* r l) - (unsafe-fl* g l) - (unsafe-fl* b l))))) - (define (make-random-flomap c w h) - (unsafe-build-flomap c w h (λ (k x y) (random)))) + (build-flomap c w h (λ (k x y i) (random)))) (define (flomap-rough fm z-amt) (match-define (flomap _ c w h) fm) @@ -133,8 +116,6 @@ (draw-lambda dc 8 8 240 240)) scale)) - ;(flomap-add-sparkles! bulge-fm) - (define (lambda-flomap color pen-width) (draw-icon-flomap 256 256 (λ (dc) @@ -153,8 +134,9 @@ [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 112 scale))] [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] - [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] - [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] + [lambda-fm (time (printf "render lam:~n") + (deep-flomap-render-icon lambda-dfm metal-material))] + [fm (time (printf "render fm:~n") (deep-flomap-render-icon bulge-dfm glass-logo-material))] [fm (flomap-cc-superimpose fm (lambda-flomap lambda-outline-color 10) @@ -168,11 +150,13 @@ (send dc set-pen lambda-outline-color 4 'solid) (send dc draw-ellipse 2 2 252 252)) scale) - fm)] - ) + fm)]) fm))) -(define plt-logo (compose flomap->bitmap plt-flomap)) +(define (plt-logo height) + (define fm (plt-flomap height)) + (time (printf "flomap->bitmap:~n") + (flomap->bitmap fm))) (define continents-path-commands '((m 11.526653 18.937779) @@ -285,7 +269,7 @@ scale)] [earth-dfm (flomap->deep-flomap earth-fm)] [earth-dfm (deep-flomap-bulge-spheroid earth-dfm (* 16 scale))] - [earth-dfm (deep-flomap-cc-superimpose earth-dfm indent-dfm #:z-mode 'add)]) + [earth-dfm (deep-flomap-cc-superimpose 'add earth-dfm indent-dfm)]) (values (deep-flomap-render-icon earth-dfm water-logo-material) (deep-flomap-z earth-dfm)))) diff --git a/collects/images/private/deep-flomap-parameters.rkt b/collects/images/private/deep-flomap-parameters.rkt new file mode 100644 index 0000000000..849000f511 --- /dev/null +++ b/collects/images/private/deep-flomap-parameters.rkt @@ -0,0 +1,33 @@ +#lang typed/racket/base + +(require typed/private/utils + (except-in "deep-flomap-untyped-parameters.rkt" + light-direction light-intensity ambient-intensity reflected-intensity + refractive-index ideal-reflectance ideal-transmission transmission-density + specular-reflectance specular-roughness specular-purity + diffuse-reflectance ambient-reflectance ambient-transmission + shadow-blur + ->refractive-index)) + +(provide (all-from-out "deep-flomap-untyped-parameters.rkt")) + +(require/typed/provide + "deep-flomap-untyped-parameters.rkt" + ;; lighting parameters + [light-direction (Parameterof (List Flonum Flonum Flonum))] + [light-intensity (Parameterof (List Flonum Flonum Flonum))] + [ambient-intensity (Parameterof (List Flonum Flonum Flonum))] + [reflected-intensity (Parameterof (List Flonum Flonum Flonum))] + ;; material parameters + [refractive-index (Parameterof Flonum)] + [ideal-reflectance (Parameterof Flonum)] + [ideal-transmission (Parameterof Flonum)] + [transmission-density (Parameterof Flonum)] + [specular-reflectance (Parameterof Flonum)] + [specular-roughness (Parameterof Flonum)] + [specular-purity (Parameterof Flonum)] + [diffuse-reflectance (Parameterof Flonum)] + [ambient-reflectance (Parameterof Flonum)] + [ambient-transmission (Parameterof Flonum)] + [shadow-blur (Parameterof Flonum)] + [->refractive-index ((U Symbol Real) -> Flonum)]) diff --git a/collects/images/private/deep-flomap-render.rkt b/collects/images/private/deep-flomap-render.rkt new file mode 100644 index 0000000000..6d46cfb856 --- /dev/null +++ b/collects/images/private/deep-flomap-render.rkt @@ -0,0 +1,530 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match racket/math + "flonum.rkt" + "flomap.rkt" + "deep-flomap-struct.rkt" + "deep-flomap-parameters.rkt") + +(provide deep-flomap-render) + +;; Hacks +(define specular-blur 1/2) +(define diffuse-blur 1/2) +(define ideal-transmission-blur 1) +(define ambient-transmission-blur-fraction 1/32) + +;; =================================================================================================== +;; Ray tracing ops + +;; assumes direction to viewer is 0.0 0.0 1.0 (i.e. viewer above at infinity) +(: reflect-view-ray (Flonum Flonum Flonum -> (values Flonum Flonum Flonum))) +(define (reflect-view-ray nx ny nz) + (values (* 2.0 (* nz nx)) + (* 2.0 (* nz ny)) + (- (* 2.0 (* nz nz)) 1.0))) + +;; calculates intensity of transmitted rays using Fresnel's equation +(: transmission-intensity (Flonum Flonum Flonum -> Flonum)) +(define (transmission-intensity cos-i η1 η2) + (define n1/n2 (/ η1 η2)) + (define cos^2-i (* cos-i cos-i)) + (define sin^2-t (* (* n1/n2 n1/n2) (- 1.0 cos^2-i))) + (define cos-t (flsqrt (- 1.0 sin^2-t))) + (define n1-cos-i (* η1 cos-i)) + (define n2-cos-t (* η2 cos-t)) + (define n1-cos-t (* η1 cos-t)) + (define n2-cos-i (* η2 cos-i)) + (define perp (/ (- n1-cos-i n2-cos-t) + (+ n1-cos-i n2-cos-t))) + (define parl (/ (- n2-cos-i n1-cos-t) + (+ n2-cos-i n1-cos-t))) + (- 1.0 (* 0.5 (+ (* perp perp) (* parl parl))))) + +(: transmitted-vector (Flonum Flonum Flonum Flonum Flonum Flonum Flonum Flonum + -> (values Flonum Flonum Flonum))) +(define (transmitted-vector nx ny nz ix iy iz η1 η2) + (define η1/η2 (/ η1 η2)) + (define cos-i (- (fl3dot nx ny nz ix iy iz))) + (define cos^2-i (* cos-i cos-i)) + (define sin^2-t (* (* η1/η2 η1/η2) (- 1.0 cos^2-i))) + (define c (- (* η1/η2 cos-i) (flsqrt (- 1.0 sin^2-t)))) + (define-values (tx1 ty1 tz1) (fl3* ix iy iz η1/η2)) + (define-values (tx2 ty2 tz2) (fl3* nx ny nz c)) + (fl3+ tx1 ty1 tz1 tx2 ty2 tz2)) + +(: absorb-intensity (Flonum Flonum -> Flonum)) +(define (absorb-intensity opacity dist) + (let* ([o (+ (* opacity 0.99) 0.005)]) + (cond [(o . = . 0.0) 0.0] + [else (exp (* (fllog o) dist))]))) + +(: beckmann-distribution (Flonum Flonum -> Flonum)) +(define (beckmann-distribution cos-θ m) + (define x (/ (tan (acos cos-θ)) m)) + (define m*cos^2-θ (* m cos-θ cos-θ)) + (/ (exp (- (* x x))) (* pi m*cos^2-θ m*cos^2-θ))) + +;; =================================================================================================== +;; Pass 1: tracing from a directional light source + +(: trace-directional-light (flomap flomap flomap flomap -> (values flomap flomap))) +(define (trace-directional-light alpha-fm rgb-fm z-fm normal-fm) + (match-define (flomap alpha-vs 1 w h) alpha-fm) + (match-define (list rgb-vs z-vs normal-vs) (map flomap-values (list rgb-fm z-fm normal-fm))) + + (define z-max (flomap-max-value z-fm)) + (define opacity-z (/ z-max (transmission-density))) + ;; max coordinates of the shadow image + (define sx-max (- w 1.0)) + (define sy-max (- h 1.0)) + ;; vector pointing toward light source, incident vector, and light color + (define-values (lx ly lz) (match-let ([(list lx ly lz) (light-direction)]) + (fl3normalize lx ly lz))) + (define-values (ix iy iz) (fl3- lx ly lz)) + (match-define (list lr lg lb) (light-intensity)) + ;; view and "half" directions + (define-values (hx hy hz) (fl3-half-norm lx ly lz 0.0 0.0 1.0)) + ;; material properties + (define η2 (exact->inexact (refractive-index))) + (define η1/η2 (/ 1.0 η2)) + ;; proportion of diffracted reflection + (define 0.5*v-dot-h (* 0.5 hz)) + (define Ra (ambient-reflectance)) + (define Ta (ambient-transmission)) + (define Rd (diffuse-reflectance)) + (define Rs (specular-reflectance)) + (define Ti (ideal-transmission)) + (define roughness (specular-roughness)) + (define purity (specular-purity)) + + (match-define (list ar ag ab) (ambient-intensity)) + (define-values (Tar Tag Tab) (fl3* ar ag ab Ta)) + (define-values (Rar Rag Rab) (fl3* ar ag ab Ra)) + + (define intensity-fm (make-flomap 3 w h)) + (define intensity-vs (flomap-values intensity-fm)) + (define specular-fm (make-flomap 1 w h)) + (define specular-vs (flomap-values specular-fm)) + (define diffuse-fm (make-flomap 3 w h lz)) + (define diffuse-vs (flomap-values diffuse-fm)) + + (define sx-vs (make-flvector (* w h) +nan.0)) + (define sy-vs (make-flvector (* w h) +nan.0)) + (define Irgb-vs (make-flvector (* 3 w h))) + + (for*: ([int-y : Integer (in-range h)] [int-x : Integer (in-range w)]) + (define i (fx+ int-x (fx* int-y w))) + (define a (unsafe-flvector-ref alpha-vs i)) + (when (a . > . 0.0) + (define j (fx* 3 i)) + ;; altitude and surface normal + (define z (unsafe-flvector-ref z-vs i)) + (define nx (unsafe-flvector-ref normal-vs j)) + (define ny (unsafe-flvector-ref normal-vs (fx+ j 1))) + (define nz (unsafe-flvector-ref normal-vs (fx+ j 2))) + ;; cosine of angle between light and surface normal + (define n-dot-l (fl3dot nx ny nz lx ly lz)) + ;; intensity of incident light (Lambert's cosine law) + (define-values (Ilr Ilg Ilb) (fl3* lr lg lb n-dot-l)) + (unsafe-flvector-set! intensity-vs j Ilr) + (unsafe-flvector-set! intensity-vs (fx+ j 1) Ilg) + (unsafe-flvector-set! intensity-vs (fx+ j 2) Ilb) + ;; diffraction intensity due to specular, diffuse and ambient reflection + (cond + [(n-dot-l . > . 0.0) ; does the microfacet face the light? + (define Is + (cond + ;; Cook-Torrance specular reflection intensity + [(Rs . > . 0.0) + (define n-dot-h (fl3dot nx ny nz hx hy hz)) + (define n-dot-v nz) + ;; geometrical attenuation factor (has something to do with local reflections) + (define G (min 1.0 + (/ (* n-dot-h n-dot-v) 0.5*v-dot-h) + (/ (* n-dot-h n-dot-l) 0.5*v-dot-h))) + ;; scatter distribution + (define D (beckmann-distribution n-dot-h roughness)) + ;; Fresnel term + (define F (- 1.0 (transmission-intensity n-dot-l 1.0 η2))) + (* Rs F (/ D n-dot-l) (/ G n-dot-v))] + [else 0.0])) + (unsafe-flvector-set! specular-vs i Is) + + (let*-values ([(Idr Idg Idb) (fl3* Ilr Ilg Ilb Rd)] + [(Idr Idg Idb) (fl3+ Idr Idg Idb Rar Rag Rab)]) + (unsafe-flvector-set! diffuse-vs j Idr) + (unsafe-flvector-set! diffuse-vs (fx+ j 1) Idg) + (unsafe-flvector-set! diffuse-vs (fx+ j 2) Idb))] + [else + (unsafe-flvector-set! diffuse-vs j Rar) + (unsafe-flvector-set! diffuse-vs (fx+ j 1) Rag) + (unsafe-flvector-set! diffuse-vs (fx+ j 2) Rab)]) + + (when (and (Ti . > . 0.0) (n-dot-l . > . 0.0)) + ;; ideal transmission vector + (define-values (tx ty tz) (transmitted-vector nx ny nz ix iy iz 1.0 η2)) + ;; sz = z + dist * tz, so dist = (sz - z) / tz + (define dist (/ (- 0.0 z) tz)) + (when (and (dist . >= . 0.0) (dist . < . +inf.0)) + ;; transmitted ray intersects with shadow plane at sx sy 0.0 + (define sx (+ 0.5 (fx->fl int-x) (* dist tx))) + (define sy (+ 0.5 (fx->fl int-y) (* dist ty))) + ;; actual transmission proportion (Fresnel's law) + (define T (* Ti (transmission-intensity n-dot-l 1.0 η2))) + ;; intensity of incident light (Lambert's cosine law) + (define-values (Ilr Ilg Ilb) (fl3* lr lg lb n-dot-l)) + ;; normalized distance to the surface + (define norm-dist (/ dist opacity-z)) + ;; intensity of the light that strikes the surface + (define r (unsafe-flvector-ref rgb-vs j)) + (define g (unsafe-flvector-ref rgb-vs (fx+ j 1))) + (define b (unsafe-flvector-ref rgb-vs (fx+ j 2))) + (define-values (Ir Ig Ib) + (values (* T Ilr (absorb-intensity r norm-dist)) + (* T Ilg (absorb-intensity g norm-dist)) + (* T Ilb (absorb-intensity b norm-dist)))) + (unsafe-flvector-set! sx-vs i sx) + (unsafe-flvector-set! sy-vs i sy) + (unsafe-flvector-set! Irgb-vs j Ir) + (unsafe-flvector-set! Irgb-vs (fx+ j 1) Ig) + (unsafe-flvector-set! Irgb-vs (fx+ j 2) Ib))))) + + (define diffracted-fm (fm+ (fm* (flomap-blur diffuse-fm diffuse-blur) + rgb-fm) + (fm* (flomap-blur specular-fm specular-blur) + (fm+ (fm* (- 1.0 purity) rgb-fm) + (fm* purity intensity-fm))))) + + ;; approximate ambient transmission by casting light downward with no refraction, then blurring + (define ambient-shadow-fm (make-flomap 3 w h)) + (define ambient-shadow-vs (flomap-values ambient-shadow-fm)) + (when (Ta . > . 0.0) + (for*: ([int-y : Integer (in-range h)] [int-x : Integer (in-range w)]) + (define i (fx+ int-x (fx* int-y w))) + (define a (unsafe-flvector-ref alpha-vs i)) + (when (a . > . 0.0) + (define z (unsafe-flvector-ref z-vs i)) + (define j (fx* 3 i)) + (define r (unsafe-flvector-ref rgb-vs j)) + (define g (unsafe-flvector-ref rgb-vs (fx+ j 1))) + (define b (unsafe-flvector-ref rgb-vs (fx+ j 2))) + (define norm-dist (/ z opacity-z)) + (define-values (Ir Ig Ib) + (values (* Tar (absorb-intensity r norm-dist)) + (* Tag (absorb-intensity g norm-dist)) + (* Tab (absorb-intensity b norm-dist)))) + (unsafe-flvector-set! ambient-shadow-vs j Ir) + (unsafe-flvector-set! ambient-shadow-vs (fx+ j 1) Ig) + (unsafe-flvector-set! ambient-shadow-vs (fx+ j 2) Ib)))) + + ;; cast approximate shadow volumes + (define shadow-fm (flomap-blur ambient-shadow-fm (* ambient-transmission-blur-fraction (min w h)))) + (define shadow-vs (flomap-values shadow-fm)) + (when (Ti . > . 0.0) + ;; Gaussian kernels - make as wide as possible to keep from having to reallocate + (define kxs (make-flvector w)) + (define kys (make-flvector h)) + (for*: ([int-y : Integer (in-range (- h 1))] [int-x : Integer (in-range (- w 1))]) + (define i00 (fx+ int-x (fx* int-y w))) + (define i01 (fx+ i00 1)) + (define i10 (fx+ i00 w)) + (define i11 (fx+ i10 1)) + (define sx00 (unsafe-flvector-ref sx-vs i00)) + (define sx01 (unsafe-flvector-ref sx-vs i01)) + (define sx10 (unsafe-flvector-ref sx-vs i10)) + (define sx11 (unsafe-flvector-ref sx-vs i11)) + (when (and (flrational? sx00) (flrational? sx01) + (flrational? sx10) (flrational? sx11)) + (define sy00 (unsafe-flvector-ref sy-vs i00)) + (define sy01 (unsafe-flvector-ref sy-vs i01)) + (define sy10 (unsafe-flvector-ref sy-vs i10)) + (define sy11 (unsafe-flvector-ref sy-vs i11)) + (define sx-min (min sx00 sx01 sx10 sx11)) + (define sy-min (min sy00 sy01 sy10 sy11)) + (define sx-max (max sx00 sx01 sx10 sx11)) + (define sy-max (max sy00 sy01 sy10 sy11)) + ;; find the mean and standard deviation + (define sx-mid (* 0.25 (+ sx00 sx01 sx10 sx11))) + (define sy-mid (* 0.25 (+ sy00 sy01 sy10 sy11))) + (define sx-mid^2 (* 0.25 (+ (* sx00 sx00) (* sx01 sx01) (* sx10 sx10) (* sx11 sx11)))) + (define sy-mid^2 (* 0.25 (+ (* sy00 sy00) (* sy01 sy01) (* sy10 sy10) (* sy11 sy11)))) + (define sx-stddev (flsqrt (- sx-mid^2 (* sx-mid sx-mid)))) + (define sy-stddev (flsqrt (- sy-mid^2 (* sy-mid sy-mid)))) + (define x-min (fxmax 0 (fl->fx (floor sx-min)))) + (define x-max (fxmin w (fx+ 1 (fl->fx (floor sx-max))))) + (define y-min (fxmax 0 (fl->fx (floor sy-min)))) + (define y-max (fxmin h (fx+ 1 (fl->fx (floor sy-max))))) + (define x-size (fx- x-max x-min)) + (define y-size (fx- y-max y-min)) + (when (and (x-size . fx> . 0) (y-size . fx> . 0)) + ;; average the color + (define j00 (fx* 3 i00)) + (define j01 (fx* 3 i01)) + (define j10 (fx* 3 i10)) + (define j11 (fx* 3 i11)) + (define r (* 0.25 (+ (unsafe-flvector-ref Irgb-vs j00) + (unsafe-flvector-ref Irgb-vs j01) + (unsafe-flvector-ref Irgb-vs j10) + (unsafe-flvector-ref Irgb-vs j11)))) + (define g (* 0.25 (+ (unsafe-flvector-ref Irgb-vs (fx+ j00 1)) + (unsafe-flvector-ref Irgb-vs (fx+ j01 1)) + (unsafe-flvector-ref Irgb-vs (fx+ j10 1)) + (unsafe-flvector-ref Irgb-vs (fx+ j11 1))))) + (define b (* 0.25 (+ (unsafe-flvector-ref Irgb-vs (fx+ j00 2)) + (unsafe-flvector-ref Irgb-vs (fx+ j01 2)) + (unsafe-flvector-ref Irgb-vs (fx+ j10 2)) + (unsafe-flvector-ref Irgb-vs (fx+ j11 2))))) + ;; precalculate the Gaussian kernel for the x direction + (for ([dx (in-range x-size)]) + (define x (fx+ dx x-min)) + (define d (/ (- (+ 0.5 (fx->fl x)) sx-mid) sx-stddev)) + (define kx (exp (* -0.5 (* d d)))) + (unsafe-flvector-set! kxs dx kx)) + ;; precalculate the Gaussian kernel for the y direction + ;; this shouldn't help because it's used only once per y iteration, but it reduces allocs + ;; within the loop (unsafe-flexp has no bytecode op yet, so its args and return are boxed) + (for ([dy (in-range y-size)]) + (define y (fx+ dy y-min)) + (define d (/ (- (+ 0.5 (fx->fl y)) sy-mid) sy-stddev)) + (define ky (exp (* -0.5 (* d d)))) + (unsafe-flvector-set! kys dy ky)) + ;; normalization constant for a 2D Gaussian kernel + (define c (* 2.0 pi sx-stddev sy-stddev)) + ;; cast the approximate shadow volume + (let y-loop ([dy 0]) + (when (dy . fx< . y-size) + (define ky (unsafe-flvector-ref kys dy)) + (cond [(ky . > . 0.1) + (define a (/ ky c)) + (define Ir (* r a)) + (define Ig (* g a)) + (define Ib (* b a)) + (define i (fx* 3 (fx+ x-min (fx* (fx+ dy y-min) w)))) + (let x-loop ([dx 0] [i i]) + (cond [(dx . fx< . x-size) + (define kx (unsafe-flvector-ref kxs dx)) + (when (kx . > . 0.1) + (unsafe-flvector-set! + shadow-vs i (+ (* Ir kx) (unsafe-flvector-ref shadow-vs i))) + (define i1 (fx+ i 1)) + (unsafe-flvector-set! + shadow-vs i1 (+ (* Ig kx) (unsafe-flvector-ref shadow-vs i1))) + (define i2 (fx+ i 2)) + (unsafe-flvector-set! + shadow-vs i2 (+ (* Ib kx) (unsafe-flvector-ref shadow-vs i2)))) + (x-loop (fx+ 1 dx) (fx+ 3 i))] + [else + (y-loop (fx+ 1 dy))]))] + [else + (y-loop (fx+ 1 dy))]))))))) + + ;; blur the shadow a bit to make up for approximating it with Gaussians + (values diffracted-fm (flomap-box-blur shadow-fm 1))) + +;; =================================================================================================== +;; Pass 2: tracing from a directional viewer + +(: trace-directional-view (flomap flomap flomap flomap flomap -> (values flomap flomap))) +(define (trace-directional-view alpha-fm rgb-fm z-fm normal-fm shadow-fm) + (define-values (w h) (flomap-size alpha-fm)) + (match-define (list alpha-vs rgb-vs z-vs normal-vs shadow-vs) + (map flomap-values (list alpha-fm rgb-fm z-fm normal-fm shadow-fm))) + + (define w-1 (fx- w 1)) + (define h-1 (fx- h 1)) + (define x-size (fx->fl w)) + (define y-size (fx->fl h)) + (define z-size (flomap-max-value z-fm)) + (define x-mid (* 0.5 x-size)) + (define y-mid (* 0.5 y-size)) + (define opacity-z (/ z-size (transmission-density))) + + ;; reflected wall is tilted a bit toward the viewer + (define wall-tilt-θ (* 1/8 pi)) + (define cos-wall-tilt-θ (cos wall-tilt-θ)) + (define sin-wall-tilt-θ (sin wall-tilt-θ)) + (match-define (list Irr Irg Irb) (reflected-intensity)) + + ;; max coords of the shadow image + ;; subtract epsilon to ensure that sx < (w - 1) so that (flfloor sx) < (w - 1) (similarly for sy) + (define sx-max (- w 1.00001)) + (define sy-max (- h 1.00001)) + ;; material properties + (define η2 (refractive-index)) + (define η1/η2 (/ 1.0 η2)) + (define Ri (ideal-reflectance)) + (define Ti (ideal-transmission)) + + (define reflected-fm (make-flomap 3 w h)) + (define reflected-vs (flomap-values reflected-fm)) + (define transmitted-fm (make-flomap 3 w h)) + (define transmitted-vs (flomap-values transmitted-fm)) + + (when (or (Ri . > . 0.0) (Ti . > . 0.0)) + (for*: ([int-y : Integer (in-range h)] [int-x : Integer (in-range w)]) + (define i (fx+ int-x (fx* int-y w))) + (define a (unsafe-flvector-ref alpha-vs i)) + (when (a . > . 0.0) + (define j (fx* 3 i)) + ;; surface normal + (define nx (unsafe-flvector-ref normal-vs j)) + (define ny (unsafe-flvector-ref normal-vs (fx+ j 1))) + (define nz (unsafe-flvector-ref normal-vs (fx+ j 2))) + ;; cosine of angle between viewer and surface normal + ;; with gradient inferred from z flomap, this is always > 0.0 + (define cos-i nz) + ;; transmitted intensity + (define orig-T (transmission-intensity cos-i 1.0 η2)) + (define T (* Ti orig-T)) + (define R (* Ri (- 1.0 orig-T))) + ;; surface coordinates + (define x (+ 0.5 (fx->fl int-x))) + (define y (+ 0.5 (fx->fl int-y))) + (define z (unsafe-flvector-ref z-vs i)) + ;; reflection + (when (and (Ri . > . 0.0) + (int-x . fx> . 0) (int-x . fx< . w-1) + (int-y . fx> . 0) (int-y . fx< . h-1)) + (define-values (rx ry rz) (reflect-view-ray nx ny nz)) + ;; tilt the wall a little so flat surfaces reflect something + (define ry* (- (* ry cos-wall-tilt-θ) (* rz sin-wall-tilt-θ))) + ;(define rz* (+ (* ry sin-wall-tilt-θ) (* rz cos-wall-tilt-θ))) + ;; distance to the wall + (define rdist (/ (- (- z-size) y) ry*)) + (define sx (+ x (* rx rdist))) + (define sy (+ y (* ry rdist))) + (define sz (+ z (* rz rdist))) + (when (rdist . >= . 0.0) + (define cdist (fl3dist sx sy sz x-mid y-mid 0.0)) + (define v (flsigmoid (* 0.25 (- (* 4.5 z-size) cdist)))) + (define trash 0.0) + (set! trash Irr) + (set! trash Irg) + (set! trash Irb) + (let-values ([(r g b) (fl3* Irr Irg Irb (* R v))]) + (unsafe-flvector-set! reflected-vs j r) + (unsafe-flvector-set! reflected-vs (fx+ j 1) g) + (unsafe-flvector-set! reflected-vs (fx+ j 2) b)))) + ;; transmission (refraction) + (when (Ti . > . 0.0) + (define-values (tx ty tz) (transmitted-vector nx ny nz 0.0 0.0 -1.0 1.0 η2)) + ;; sz = z + dist * tz, so dist = (sz - z) / tz + (define dist (/ (- 0.0 z) tz)) + (when (and (dist . >= . 0.0) (dist . < . +inf.0)) + ;; Find the color of the point on the shadow that the ray struck + (define sx (max 0.0 (min sx-max (+ x (* dist tx))))) + (define sy (max 0.0 (min sy-max (+ y (* dist ty))))) + (define floor-sx (floor sx)) + (define floor-sy (floor sy)) + (define bx (fl->fx floor-sx)) + (define by (fl->fx floor-sy)) + ;; Bilinearly interpolate the four colors nearest the point on the shadow + (define 1-αx (- sx floor-sx)) + (define 1-αy (- sy floor-sy)) + (define αx (- 1.0 1-αx)) + (define αy (- 1.0 1-αy)) + ;; upper-left weighted values + (define j1 (fx* 3 (fx+ bx (fx* by w)))) + (define r1 (unsafe-flvector-ref shadow-vs j1)) + (define g1 (unsafe-flvector-ref shadow-vs (fx+ j1 1))) + (define b1 (unsafe-flvector-ref shadow-vs (fx+ j1 2))) + (define-values (sr1 sg1 sb1) (fl3* r1 g1 b1 (* αx αy))) + ;; upper-right weighted values + (define j2 (fx+ j1 3)) + (define r2 (unsafe-flvector-ref shadow-vs j2)) + (define g2 (unsafe-flvector-ref shadow-vs (fx+ j2 1))) + (define b2 (unsafe-flvector-ref shadow-vs (fx+ j2 2))) + (define-values (sr2 sg2 sb2) (fl3* r2 g2 b2 (* 1-αx αy))) + ;; lower-left weighted values + (define j3 (fx+ j1 (fx* 3 w))) + (define r3 (unsafe-flvector-ref shadow-vs j3)) + (define g3 (unsafe-flvector-ref shadow-vs (fx+ j3 1))) + (define b3 (unsafe-flvector-ref shadow-vs (fx+ j3 2))) + (define-values (sr3 sg3 sb3) (fl3* r3 g3 b3 (* αx 1-αy))) + ;; lower-right weighted values + (define j4 (fx+ j3 3)) + (define r4 (unsafe-flvector-ref shadow-vs j4)) + (define g4 (unsafe-flvector-ref shadow-vs (fx+ j4 1))) + (define b4 (unsafe-flvector-ref shadow-vs (fx+ j4 2))) + (define-values (sr4 sg4 sb4) (fl3* r4 g4 b4 (* 1-αx 1-αy))) + ;; final interpolated shadow color + (define sr (+ sr1 sr2 sr3 sr4)) + (define sg (+ sg1 sg2 sg3 sg4)) + (define sb (+ sb1 sb2 sb3 sb4)) + ;; normalized distance to the surface + (define norm-dist (/ dist opacity-z)) + ;; intensities of each r g b by the time the light emerges from the surface + (define-values (r g b) + ;; colors represent absorption rates + (let ([r (unsafe-flvector-ref rgb-vs j)] + [g (unsafe-flvector-ref rgb-vs (fx+ j 1))] + [b (unsafe-flvector-ref rgb-vs (fx+ j 2))]) + (values (* T sr (absorb-intensity r norm-dist)) + (* T sg (absorb-intensity g norm-dist)) + (* T sb (absorb-intensity b norm-dist))))) + (unsafe-flvector-set! transmitted-vs j r) + (unsafe-flvector-set! transmitted-vs (fx+ j 1) g) + (unsafe-flvector-set! transmitted-vs (fx+ j 2) b)))))) + + ;; blur to cut down on sparklies (poor man's supersampling) + (values reflected-fm + (flomap-blur transmitted-fm ideal-transmission-blur))) + +;; =================================================================================================== +;; Full rendering + +(: prep-background (flomap Integer Integer -> (Option flomap))) +(define (prep-background fm w h) + (let loop ([fm (flomap-cc-crop fm w h)]) + (case (flomap-components fm) + [(0) #f] + [(1) (flomap-append-components fm fm fm)] + [(2) (define value-fm (flomap-ref-component fm 1)) + (loop (flomap-append-components fm value-fm value-fm))] + [(3) fm] + [(4) (flomap-drop-components (flomap-cc-superimpose (make-flomap 4 w h 1.0) fm) 1)] + [else (raise-type-error 'deep-flomap-render "flomap with 0, 1, 2, 3 or 4 components" fm)]))) + +(: deep-flomap-render (case-> (deep-flomap -> flomap) + (deep-flomap (Option flomap) -> flomap))) +(define deep-flomap-render + (case-lambda + [(dfm) (deep-flomap-render dfm #f)] + [(dfm background-fm) + (define-values (w h) (deep-flomap-size dfm)) + (define argb-fm (flomap-divide-alpha (deep-flomap-argb dfm))) + (define alpha-fm (flomap-ref-component argb-fm 0)) + (define rgb-fm (flomap-drop-components argb-fm 1)) + (define z-fm (fmmax 0.0 (deep-flomap-z dfm))) + (define normal-fm (flomap-gradient-normal z-fm)) + (define bg-fm (if background-fm (prep-background background-fm w h) #f)) + + ;; pass 1: trace from the light source + (define-values (diffracted-fm raw-shadow-fm) + (trace-directional-light alpha-fm rgb-fm z-fm normal-fm)) + + ;; blur the shadow to simulate internal scatter + (define σ (* (min w h) (shadow-blur))) + (define shadow-fm + (cond [bg-fm + ;; two Gaussian blurs by half-σ is equivalent to one Gaussian blur by σ + (define half-σ (* (/ 1 (sqrt 2)) σ)) + (let* ([fm (flomap-blur raw-shadow-fm half-σ)] + [fm (fm* fm bg-fm)] + [fm (flomap-blur fm half-σ)]) + fm)] + [else + (flomap-blur raw-shadow-fm σ)])) + + ;; pass 2: trace from the viewer + (define-values (reflected-fm transmitted-fm) + (trace-directional-view alpha-fm rgb-fm z-fm normal-fm shadow-fm)) + + ;; add all the light together, convert to premultiplied-alpha flomap + (let* ([fm (fm+ (fm+ diffracted-fm transmitted-fm) reflected-fm)] + [fm (flomap-append-components alpha-fm fm)] + [fm (flomap-multiply-alpha fm)]) + fm)])) diff --git a/collects/images/private/deep-flomap-struct.rkt b/collects/images/private/deep-flomap-struct.rkt new file mode 100644 index 0000000000..71ba4a34d7 --- /dev/null +++ b/collects/images/private/deep-flomap-struct.rkt @@ -0,0 +1,482 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fx->fl fl->fx) + racket/match racket/math + "flonum.rkt" + "flomap.rkt") + +(provide deep-flomap deep-flomap? deep-flomap-argb deep-flomap-z + deep-flomap-width deep-flomap-height deep-flomap-z-min deep-flomap-z-max + deep-flomap-size deep-flomap-alpha deep-flomap-rgb + flomap->deep-flomap + ;; Sizing + deep-flomap-inset deep-flomap-trim deep-flomap-scale deep-flomap-resize + ;; Z-adjusting + deep-flomap-scale-z deep-flomap-smooth-z deep-flomap-raise deep-flomap-tilt + deep-flomap-emboss + deep-flomap-bulge deep-flomap-bulge-round deep-flomap-bulge-round-rect + deep-flomap-bulge-spheroid deep-flomap-bulge-horizontal deep-flomap-bulge-vertical + deep-flomap-bulge-ripple + ;; Compositing + deep-flomap-pin deep-flomap-pin* + deep-flomap-lt-superimpose deep-flomap-lc-superimpose deep-flomap-lb-superimpose + deep-flomap-ct-superimpose deep-flomap-cc-superimpose deep-flomap-cb-superimpose + deep-flomap-rt-superimpose deep-flomap-rc-superimpose deep-flomap-rb-superimpose + deep-flomap-vl-append deep-flomap-vc-append deep-flomap-vr-append + deep-flomap-ht-append deep-flomap-hc-append deep-flomap-hb-append) + +(struct: deep-flomap ([argb : flomap] [z : flomap]) + #:transparent + #:guard + (λ (argb-fm z-fm name) + (match-define (flomap _ 4 w h) argb-fm) + (match-define (flomap _ 1 zw zh) z-fm) + (unless (and (= w zw) (= h zh)) + (error 'deep-flomap + "expected flomaps of equal dimension; given dimensions ~e×~e and ~e×~e" w h zw zh)) + (values argb-fm z-fm))) + +(: flomap->deep-flomap (flomap -> deep-flomap)) +(define (flomap->deep-flomap argb-fm) + (match-define (flomap _ 4 w h) argb-fm) + (deep-flomap argb-fm (make-flomap 1 w h))) + +(: deep-flomap-width (deep-flomap -> Nonnegative-Fixnum)) +(define (deep-flomap-width dfm) + (define w (flomap-width (deep-flomap-argb dfm))) + (with-asserts ([w nonnegative-fixnum?]) + w)) + +(: deep-flomap-height (deep-flomap -> Nonnegative-Fixnum)) +(define (deep-flomap-height dfm) + (define h (flomap-height (deep-flomap-argb dfm))) + (with-asserts ([h nonnegative-fixnum?]) + h)) + +(: deep-flomap-z-min (deep-flomap -> Flonum)) +(define (deep-flomap-z-min dfm) + (flomap-min-value (deep-flomap-z dfm))) + +(: deep-flomap-z-max (deep-flomap -> Flonum)) +(define (deep-flomap-z-max dfm) + (flomap-max-value (deep-flomap-z dfm))) + +(: deep-flomap-size (deep-flomap -> (values Nonnegative-Fixnum Nonnegative-Fixnum))) +(define (deep-flomap-size dfm) + (values (deep-flomap-width dfm) (deep-flomap-height dfm))) + +(: deep-flomap-alpha (deep-flomap -> flomap)) +(define (deep-flomap-alpha dfm) + (flomap-ref-component (deep-flomap-argb dfm) 0)) + +(: deep-flomap-rgb (deep-flomap -> flomap)) +(define (deep-flomap-rgb dfm) + (flomap-drop-components (deep-flomap-argb dfm) 1)) + +;; =================================================================================================== +;; Z adjusters + +(: deep-flomap-scale-z (deep-flomap (U Real flomap) -> deep-flomap)) +(define (deep-flomap-scale-z dfm z) + (match-define (deep-flomap argb-fm z-fm) dfm) + (deep-flomap argb-fm (fm* z-fm z))) + +(: deep-flomap-smooth-z (deep-flomap Real -> deep-flomap)) +(define (deep-flomap-smooth-z dfm σ) + (let ([σ (exact->inexact σ)]) + (match-define (deep-flomap argb-fm z-fm) dfm) + (define new-z-fm (flomap-blur z-fm σ)) + (deep-flomap argb-fm new-z-fm))) + +;; deep-flomap-raise and everything derived from it observe an invariant: +;; when z is added, added z must be 0.0 everywhere alpha is 0.0 + +(: deep-flomap-raise (deep-flomap (U Real flomap) -> deep-flomap)) +(define (deep-flomap-raise dfm z) + (match-define (deep-flomap argb-fm z-fm) dfm) + (define alpha-fm (deep-flomap-alpha dfm)) + (deep-flomap argb-fm (fm+ z-fm (fm* alpha-fm z)))) + +(: deep-flomap-emboss (deep-flomap Real (U Real flomap) -> deep-flomap)) +(define (deep-flomap-emboss dfm xy-amt z-amt) + (let ([σ (/ xy-amt 3.0)]) + (define z-fm (flomap-normalize (deep-flomap-alpha dfm))) + (define new-z-fm (fm* (flomap-blur z-fm σ) z-amt)) + (deep-flomap-raise dfm new-z-fm))) + +(define-syntax-rule (inline-deep-flomap-bulge dfm f) + (let () + (define-values (w h) (deep-flomap-size dfm)) + (define half-x-size (- (* 0.5 (fx->fl w)) 0.5)) + (define half-y-size (- (* 0.5 (fx->fl h)) 0.5)) + (define z-fm + (inline-build-flomap + 1 w h + (λ (_ x y _i) + (f (- (/ (fx->fl x) half-x-size) 1.0) + (- (/ (fx->fl y) half-y-size) 1.0))))) + (deep-flomap-raise dfm z-fm))) + +(: deep-flomap-bulge (deep-flomap (Flonum Flonum -> Real) -> deep-flomap)) +(define (deep-flomap-bulge dfm f) + (inline-deep-flomap-bulge dfm (λ (cx cy) (exact->inexact (f cx cy))))) + +(: deep-flomap-tilt (deep-flomap Real Real Real Real -> deep-flomap)) +(define (deep-flomap-tilt dfm left-z-amt top-z-amt right-z-amt bottom-z-amt) + (let ([l (exact->inexact left-z-amt)] + [t (exact->inexact top-z-amt)] + [r (exact->inexact right-z-amt)] + [b (exact->inexact bottom-z-amt)]) + (define: (f [x : Flonum] [y : Flonum]) : Flonum + (define α (/ (+ x 1.0) 2.0)) + (define β (/ (+ y 1.0) 2.0)) + (+ (* (- 1.0 α) l) (* α r) + (* (- 1.0 β) t) (* β b))) + (inline-deep-flomap-bulge dfm f))) + +(: deep-flomap-bulge-round (deep-flomap Real -> deep-flomap)) +(define (deep-flomap-bulge-round dfm z-amt) + (let ([z-amt (exact->inexact z-amt)]) + (define: (f [x : Flonum] [y : Flonum]) : Flonum + (define d^2 (+ (* x x) (* y y))) + (* z-amt (flsqrt (/ (- 2.0 d^2) 2.0)))) + (inline-deep-flomap-bulge dfm f))) + +(: deep-flomap-bulge-round-rect (deep-flomap Real -> deep-flomap)) +(define (deep-flomap-bulge-round-rect dfm z-amt) + (let ([z-amt (exact->inexact z-amt)]) + (define: (f [x : Flonum] [y : Flonum]) : Flonum + (* z-amt (flsqrt (* (- 1.0 (* x x)) + (- 1.0 (* y y)))))) + (inline-deep-flomap-bulge dfm f))) + +(: deep-flomap-bulge-spheroid (deep-flomap Real -> deep-flomap)) +(define (deep-flomap-bulge-spheroid dfm z-amt) + (let ([z-amt (exact->inexact z-amt)]) + (define: (f [x : Flonum] [y : Flonum]) : Flonum + (define d^2 (+ (* x x) (* y y))) + (if (d^2 . < . 1.0) (* z-amt (flsqrt (- 1.0 d^2))) 0.0)) + (inline-deep-flomap-bulge dfm f))) + +(: deep-flomap-bulge-horizontal (deep-flomap Real -> deep-flomap)) +(define (deep-flomap-bulge-horizontal dfm z-amt) + (let ([z-amt (exact->inexact z-amt)]) + (define: (f [x : Flonum] [y : Flonum]) : Flonum + (* z-amt (flsqrt (- 1.0 (* x x))))) + (inline-deep-flomap-bulge dfm f))) + +(: deep-flomap-bulge-vertical (deep-flomap Real -> deep-flomap)) +(define (deep-flomap-bulge-vertical dfm z-amt) + (let ([z-amt (exact->inexact z-amt)]) + (define: (f [x : Flonum] [y : Flonum]) : Flonum + (* z-amt (flsqrt (- 1.0 (* y y))))) + (inline-deep-flomap-bulge dfm f))) + +(: deep-flomap-bulge-ripple (deep-flomap Real Real -> deep-flomap)) +(define (deep-flomap-bulge-ripple dfm freq z-amt) + (let ([freq (exact->inexact freq)] + [z-amt (exact->inexact z-amt)]) + (define: (f [x : Flonum] [y : Flonum]) : Flonum + (define d^2 (+ (* x x) (* y y))) + (define d (* freq pi (flsqrt d^2))) + (* z-amt 0.5 (- 1.0 (cos d)))) + (inline-deep-flomap-bulge dfm f))) + +;; =================================================================================================== +;; Sizing + +(: deep-flomap-inset (case-> (deep-flomap Integer -> deep-flomap) + (deep-flomap Integer Integer -> deep-flomap) + (deep-flomap Integer Integer Integer Integer -> deep-flomap))) +(define deep-flomap-inset + (case-lambda + [(dfm amt) (deep-flomap-inset dfm amt amt amt amt)] + [(dfm h-amt v-amt) (deep-flomap-inset dfm h-amt v-amt h-amt v-amt)] + [(dfm l-amt t-amt r-amt b-amt) + (match-define (deep-flomap argb-fm z-fm) dfm) + (deep-flomap (flomap-inset argb-fm l-amt t-amt r-amt b-amt) + (flomap-inset z-fm l-amt t-amt r-amt b-amt))])) + +(: deep-flomap-trim (deep-flomap -> deep-flomap)) +(define (deep-flomap-trim dfm) + (define-values (w h) (deep-flomap-size dfm)) + (define-values (_k-min x-min y-min _k-max x-max y-max) + (flomap-nonzero-rect (deep-flomap-alpha dfm))) + (deep-flomap-inset dfm (- x-min) (- y-min) (- x-max w) (- y-max h))) + +(: deep-flomap-scale (case-> (deep-flomap Real -> deep-flomap) + (deep-flomap Real Real Real -> deep-flomap))) +(define deep-flomap-scale + (case-lambda + [(dfm scale) + (match-define (deep-flomap argb-fm z-fm) (deep-flomap-scale-z dfm scale)) + (deep-flomap (flomap-scale argb-fm scale) + (flomap-scale z-fm scale))] + [(dfm x-scale y-scale z-scale) + (match-define (deep-flomap argb-fm z-fm) (deep-flomap-scale-z dfm z-scale)) + (deep-flomap (flomap-scale argb-fm x-scale y-scale) + (flomap-scale z-fm x-scale y-scale))])) + +(: deep-flomap-resize (deep-flomap (Option Integer) (Option Integer) (Option Real) (Option Real) + -> deep-flomap)) +(define (deep-flomap-resize dfm width height z-min z-max) + (match-define (deep-flomap argb-fm z-fm) dfm) + (define new-z-fm + (cond [(or z-min z-max) + (let ([z-min (if z-min z-min (flomap-min-value z-fm))] + [z-max (if z-max z-max (flomap-max-value z-fm))]) + (fm+ (fm* (flomap-normalize z-fm) (- z-max z-min)) z-min))] + [else z-fm])) + (deep-flomap (flomap-resize argb-fm width height) + (flomap-resize new-z-fm width height))) + +;; =================================================================================================== +;; Combining + +(define-type Z-Mode (U 'add 'blend 'place 'replace)) + +(: deep-flomap-pin (Z-Mode deep-flomap Real Real deep-flomap Real Real -> deep-flomap)) +(define (deep-flomap-pin z-mode dfm1 x1 y1 dfm2 x2 y2) + (cond + [(not (and (zero? x2) (zero? y2))) + (deep-flomap-pin z-mode dfm1 (- x1 x2) (- y1 y2) dfm2 0 0)] + [else + (define-values (w1 h1) (deep-flomap-size dfm1)) + (define-values (w2 h2) (deep-flomap-size dfm2)) + (let ([x1 (exact->inexact x1)] [y1 (exact->inexact y1)]) + ;; dfm1 and dfm2 offsets, in final image coordinates + (define dx1 (fl->fx (round (max 0.0 (- x1))))) + (define dy1 (fl->fx (round (max 0.0 (- y1))))) + (define dx2 (fl->fx (round (max 0.0 x1)))) + (define dy2 (fl->fx (round (max 0.0 y1)))) + ;; final image size + (define w (fxmax (fx+ dx1 w1) (fx+ dx2 w2))) + (define h (fxmax (fx+ dy1 h1) (fx+ dy2 h2))) + + (case z-mode + [(place) (deep-flomap-superimpose/place w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2)] + [(blend) (deep-flomap-superimpose/blend w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2)] + [else (deep-flomap-superimpose/replace z-mode w h + dfm1 dx1 dy1 w1 h1 + dfm2 dx2 dy2 w2 h2)]))])) + +(: deep-flomap-superimpose/replace + (Z-Mode Integer Integer + deep-flomap Integer Integer Integer Integer + deep-flomap Integer Integer Integer Integer -> deep-flomap)) +(define (deep-flomap-superimpose/replace z-mode w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2) + (match-define (deep-flomap argb1-fm z1-fm) dfm1) + (match-define (deep-flomap argb2-fm z2-fm) dfm2) + (define argb1-vs (flomap-values argb1-fm)) + (define argb2-vs (flomap-values argb2-fm)) + (define z1-vs (flomap-values z1-fm)) + (define z2-vs (flomap-values z2-fm)) + + (define-syntax-rule (get-argbz-pixel argb-vs z-vs dx dy w h x y) + (let ([x (fx- x dx)] [y (fx- y dy)]) + (cond [(and (x . fx>= . 0) (x . fx< . w) (y . fx>= . 0) (y . fx< . h)) + (define i (fx+ x (fx* y w))) + (define j (fx* 4 i)) + (values (unsafe-flvector-ref argb-vs j) + (unsafe-flvector-ref argb-vs (fx+ j 1)) + (unsafe-flvector-ref argb-vs (fx+ j 2)) + (unsafe-flvector-ref argb-vs (fx+ j 3)) + (unsafe-flvector-ref z-vs i))] + [else + (values 0.0 0.0 0.0 0.0 0.0)]))) + + (define argb-vs (make-flvector (* 4 w h))) + (define z-vs (make-flvector (* w h))) + (let: y-loop : Void ([y : Nonnegative-Fixnum 0]) + (when (y . fx< . h) + (let: x-loop : Void ([x : Nonnegative-Fixnum 0]) + (cond [(x . fx< . w) + (define-values (a1 r1 g1 b1 z1) (get-argbz-pixel argb1-vs z1-vs dx1 dy1 w1 h1 x y)) + (define-values (a2 r2 g2 b2 z2) (get-argbz-pixel argb2-vs z2-vs dx2 dy2 w2 h2 x y)) + + (define i (fx+ x (fx* y w))) + (define j (fx* 4 i)) + (unsafe-flvector-set! argb-vs j (fl-alpha-blend a1 a2 a2)) + (unsafe-flvector-set! argb-vs (fx+ j 1) (fl-alpha-blend r1 r2 a2)) + (unsafe-flvector-set! argb-vs (fx+ j 2) (fl-alpha-blend g1 g2 a2)) + (unsafe-flvector-set! argb-vs (fx+ j 3) (fl-alpha-blend b1 b2 a2)) + (unsafe-flvector-set! z-vs i (case z-mode + [(replace) (fl-alpha-blend z1 z2 a2)] + [else (+ z1 z2)])) + (x-loop (fx+ x 1))] + [else + (y-loop (fx+ y 1))])))) + + (deep-flomap (flomap argb-vs 4 w h) + (flomap z-vs 1 w h))) + +(: deep-flomap-superimpose/place (Integer Integer + deep-flomap Integer Integer Integer Integer + deep-flomap Integer Integer Integer Integer -> deep-flomap)) +(define (deep-flomap-superimpose/place w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2) + (match-define (deep-flomap argb1-fm z1-fm) dfm1) + (match-define (deep-flomap argb2-fm z2-fm) dfm2) + (match-define (flomap argb1-vs 4 argb1-w argb1-h) argb1-fm) + (match-define (flomap argb2-vs 4 argb2-w argb2-h) argb2-fm) + (match-define (flomap z1-vs 1 z1-w z1-h) z1-fm) + (match-define (flomap z2-vs 1 z2-w z2-h) z2-fm) + + (define-syntax-rule (get-alpha-pixel vs dx dy w h x y) + (let ([x (fx- x dx)] [y (fx- y dy)]) + (cond [(and (x . fx>= . 0) (x . fx< . w) (y . fx>= . 0) (y . fx< . h)) + (unsafe-flvector-ref vs (fx* 4 (fx+ x (fx* y w))))] + [else 0.0]))) + + (define-syntax-rule (get-z-pixel vs dx dy w h x y) + (let ([x (fx- x dx)] [y (fx- y dy)]) + (cond [(and (x . fx>= . 0) (x . fx< . w) (y . fx>= . 0) (y . fx< . h)) + (unsafe-flvector-ref vs (fx+ x (fx* y w)))] + [else 0.0]))) + + (define z1-max -inf.0) + (let: y-loop : Void ([y : Nonnegative-Fixnum 0]) + (when (y . fx< . h) + (let: x-loop : Void ([x : Nonnegative-Fixnum 0]) + (cond [(x . fx< . w) + (define a1 (get-alpha-pixel argb1-vs dx1 dy1 w1 h1 x y)) + (define a2 (get-alpha-pixel argb2-vs dx2 dy2 w2 h2 x y)) + (when (and (a1 . > . 0.0) (a2 . > . 0.0)) + (define z1 (get-z-pixel z1-vs dx1 dy1 w1 h1 x y)) + (set! z1-max (max z1-max z1))) + (x-loop (fx+ x 1))] + [else + (y-loop (fx+ y 1))])))) + + (define new-dfm2 (deep-flomap argb2-fm (fm+ z2-fm z1-max))) + (deep-flomap-superimpose/replace 'replace w h dfm1 dx1 dy1 w1 h1 new-dfm2 dx2 dy2 w2 h2)) + +(: deep-flomap-superimpose/blend (Integer Integer + deep-flomap Integer Integer Integer Integer + deep-flomap Integer Integer Integer Integer -> deep-flomap)) +(define (deep-flomap-superimpose/blend w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2) + (match-define (deep-flomap argb1-fm z1-fm) dfm1) + (match-define (deep-flomap argb2-fm z2-fm) dfm2) + (define argb1-vs (flomap-values argb1-fm)) + (define argb2-vs (flomap-values argb2-fm)) + (define z1-vs (flomap-values z1-fm)) + (define z2-vs (flomap-values z2-fm)) + + (define-values (u1-fm v1-fm) (flomap-gradient z1-fm)) + (define-values (u2-fm v2-fm) (flomap-gradient z2-fm)) + (define u1-vs (flomap-values u1-fm)) + (define v1-vs (flomap-values v1-fm)) + (define u2-vs (flomap-values u2-fm)) + (define v2-vs (flomap-values v2-fm)) + + (define-syntax-rule (get-argbzuv-pixel argb-vs z-vs u-vs v-vs dx dy w h x y) + (let ([x (fx- x dx)] [y (fx- y dy)]) + (cond [(and (x . fx>= . 0) (x . fx< . w) (y . fx>= . 0) (y . fx< . h)) + (define i (fx+ x (fx* y w))) + (define j (fx* 4 i)) + (values (unsafe-flvector-ref argb-vs j) + (unsafe-flvector-ref argb-vs (fx+ j 1)) + (unsafe-flvector-ref argb-vs (fx+ j 2)) + (unsafe-flvector-ref argb-vs (fx+ j 3)) + (unsafe-flvector-ref z-vs i) + (unsafe-flvector-ref u-vs i) + (unsafe-flvector-ref v-vs i))] + [else + (values 0.0 0.0 0.0 0.0 0.0 0.0 0.0)]))) + + (define argb-vs (make-flvector (* 4 w h))) + (define z-vs (make-flvector (* w h))) + (let: y-loop : Void ([y : Nonnegative-Fixnum 0]) + (when (y . fx< . h) + (let: x-loop : Void ([x : Nonnegative-Fixnum 0]) + (cond [(x . fx< . w) + (define-values (a1 r1 g1 b1 z1 u1 v1) + (get-argbzuv-pixel argb1-vs z1-vs u1-vs v1-vs dx1 dy1 w1 h1 x y)) + (define-values (a2 r2 g2 b2 z2 u2 v2) + (get-argbzuv-pixel argb2-vs z2-vs u2-vs v2-vs dx2 dy2 w2 h2 x y)) + + ;; softmax blending + (define α + (cond [(and (a1 . > . 0.0) (a2 . > . 0.0)) + (define u (- (* a2 u2) (* a1 u1))) + (define v (- (* a2 v2) (* a1 v1))) + (define β (/ (- (* a2 z2) (* a1 z1)) + (flsqrt (+ (* u u) (* v v))))) + (flsigmoid (* 15.0 β))] + [(a1 . > . 0.0) 0.0] + [(a2 . > . 0.0) 1.0] + [else 0.5])) + + (define i (fx+ x (fx* y w))) + (define j (fx* 4 i)) + (unsafe-flvector-set! argb-vs j (fl-convex-combination a1 a2 α)) + (unsafe-flvector-set! argb-vs (fx+ j 1) (fl-convex-combination r1 r2 α)) + (unsafe-flvector-set! argb-vs (fx+ j 2) (fl-convex-combination g1 g2 α)) + (unsafe-flvector-set! argb-vs (fx+ j 3) (fl-convex-combination b1 b2 α)) + (unsafe-flvector-set! z-vs i (fl-convex-combination z1 z2 α)) + (x-loop (fx+ x 1))] + [else + (y-loop (fx+ y 1))])))) + + (deep-flomap (flomap argb-vs 4 w h) + (flomap z-vs 1 w h))) + +(: deep-flomap-pin* (Z-Mode Real Real Real Real deep-flomap deep-flomap * -> deep-flomap)) +(define (deep-flomap-pin* z-mode x1-frac y1-frac x2-frac y2-frac dfm . dfms) + (for/fold ([dfm1 dfm]) ([dfm2 (in-list dfms)]) + (define-values (w1 h1) (deep-flomap-size dfm1)) + (define-values (w2 h2) (deep-flomap-size dfm2)) + (deep-flomap-pin z-mode + dfm1 (* x1-frac w1) (* y1-frac h1) + dfm2 (* x2-frac w2) (* y2-frac h2)))) + +(: deep-flomap-lt-superimpose (Z-Mode deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-lc-superimpose (Z-Mode deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-lb-superimpose (Z-Mode deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-ct-superimpose (Z-Mode deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-cc-superimpose (Z-Mode deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-cb-superimpose (Z-Mode deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-rt-superimpose (Z-Mode deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-rc-superimpose (Z-Mode deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-rb-superimpose (Z-Mode deep-flomap deep-flomap * -> deep-flomap)) + +(define (deep-flomap-lt-superimpose z-mode dfm . dfms) + (apply deep-flomap-pin* z-mode 0 0 0 0 dfm dfms)) + +(define (deep-flomap-lc-superimpose z-mode dfm . dfms) + (apply deep-flomap-pin* z-mode 0 1/2 0 1/2 dfm dfms)) + +(define (deep-flomap-lb-superimpose z-mode dfm . dfms) + (apply deep-flomap-pin* z-mode 0 1 0 1 dfm dfms)) + +(define (deep-flomap-ct-superimpose z-mode dfm . dfms) + (apply deep-flomap-pin* z-mode 1/2 0 1/2 0 dfm dfms)) + +(define (deep-flomap-cc-superimpose z-mode dfm . dfms) + (apply deep-flomap-pin* z-mode 1/2 1/2 1/2 1/2 dfm dfms)) + +(define (deep-flomap-cb-superimpose z-mode dfm . dfms) + (apply deep-flomap-pin* z-mode 1/2 1 1/2 1 dfm dfms)) + +(define (deep-flomap-rt-superimpose z-mode dfm . dfms) + (apply deep-flomap-pin* z-mode 1 0 1 0 dfm dfms)) + +(define (deep-flomap-rc-superimpose z-mode dfm . dfms) + (apply deep-flomap-pin* z-mode 1 1/2 1 1/2 dfm dfms)) + +(define (deep-flomap-rb-superimpose z-mode dfm . dfms) + (apply deep-flomap-pin* z-mode 1 1 1 1 dfm dfms)) + +(: deep-flomap-vl-append (deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-vc-append (deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-vr-append (deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-ht-append (deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-hc-append (deep-flomap deep-flomap * -> deep-flomap)) +(: deep-flomap-hb-append (deep-flomap deep-flomap * -> deep-flomap)) + +(define (deep-flomap-vl-append dfm . dfms) (apply deep-flomap-pin* 'add 0 1 0 0 dfm dfms)) +(define (deep-flomap-vc-append dfm . dfms) (apply deep-flomap-pin* 'add 1/2 1 1/2 0 dfm dfms)) +(define (deep-flomap-vr-append dfm . dfms) (apply deep-flomap-pin* 'add 1 1 1 0 dfm dfms)) +(define (deep-flomap-ht-append dfm . dfms) (apply deep-flomap-pin* 'add 1 0 0 0 dfm dfms)) +(define (deep-flomap-hc-append dfm . dfms) (apply deep-flomap-pin* 'add 1 1/2 0 1/2 dfm dfms)) +(define (deep-flomap-hb-append dfm . dfms) (apply deep-flomap-pin* 'add 1 1 0 1 dfm dfms)) diff --git a/collects/images/private/deep-flomap-untyped-parameters.rkt b/collects/images/private/deep-flomap-untyped-parameters.rkt new file mode 100644 index 0000000000..0005babeb9 --- /dev/null +++ b/collects/images/private/deep-flomap-untyped-parameters.rkt @@ -0,0 +1,117 @@ +#lang racket/base + +(require unstable/parameter-group) + +(provide (all-defined-out)) + +(define refractive-indexes + #hash((diamond . 2.42) + (cubic-zirconia . 2.15) + (ruby . 1.76) + (enamel . 1.63) + (glass . 1.54) + (wax . 1.43) + (water . 1.33) + (vacuum . 1.0))) + +(define (->refractive-index idx) + (cond [(symbol? idx) + (hash-ref refractive-indexes idx + (λ () (error 'refractive-index + "`refractive-indexes' does not have a refractive index for ~e" + idx)))] + [else (exact->inexact idx)])) + +(define (list-exact->inexact vs) + (map exact->inexact vs)) + +;; light parameters +(define light-direction (make-parameter '(0.0 -1.0 1.0) list-exact->inexact)) +(define light-intensity (make-parameter '(1.0 1.0 1.0) list-exact->inexact)) +(define ambient-intensity (make-parameter '(1.0 1.0 1.0) list-exact->inexact)) +(define reflected-intensity (make-parameter '(1.0 1.0 1.0) list-exact->inexact)) + +;; material parameters +(define refractive-index (make-parameter (->refractive-index 'glass) ->refractive-index)) +(define ideal-reflectance (make-parameter 1.0 exact->inexact)) +(define ideal-transmission (make-parameter 1.0 exact->inexact)) +(define transmission-density (make-parameter 0.65 exact->inexact)) +(define specular-reflectance (make-parameter 0.15 exact->inexact)) +(define specular-roughness (make-parameter 0.15 exact->inexact)) +(define specular-purity (make-parameter 1.0 exact->inexact)) +(define diffuse-reflectance (make-parameter 0.25 exact->inexact)) +(define ambient-reflectance (make-parameter 0.1 exact->inexact)) +(define ambient-transmission (make-parameter 0.7 exact->inexact)) +(define shadow-blur (make-parameter 0.02 exact->inexact)) + +(define-parameter-group deep-flomap-lighting + (light-direction light-intensity ambient-intensity reflected-intensity)) + +(define-parameter-group deep-flomap-material + (refractive-index ideal-reflectance ideal-transmission transmission-density + specular-reflectance specular-roughness specular-purity + diffuse-reflectance ambient-reflectance ambient-transmission + shadow-blur)) + +(define matte-material + (deep-flomap-material-value + 'vacuum 0.0 0.0 1.0 + 0.0 1.0 1.0 + 1.0 0.25 0.0 + 0.0)) + +(define dull-plastic-material + (deep-flomap-material-value + 'glass 0.0 0.0 1.0 + 1.0 0.25 1.0 + 1.0 0.25 0.0 + 0.0)) + +(define wax-material + (deep-flomap-material-value + 'wax 1.0 0.5 1.25 + 0.5 0.5 0.5 + 0.5 0.5 0.5 + 0.04)) + +(define plastic-material + (deep-flomap-material-value + 'glass 0.375 1.0 2.0 + 0.25 0.15 1.0 + 0.6 0.5 0.1 + 0.03)) + +(define metal-material + (deep-flomap-material-value + 3.0 0.3 0.0 1.0 + 0.8 0.1 0.2 + 0.2 0.8 0.0 + 0.0)) + +(define porcelain-material + (deep-flomap-material-value + 'enamel 0.9 0.5 1.5 + 0.4 0.2 1.0 + 0.5 0.5 0.5 + 0.04)) + +(define frosted-glass-material + (deep-flomap-material-value + 'glass 0.9 1.0 0.8 + 0.4 0.2 1.0 + 0.5 0.1 0.5 + 0.04)) + +(define glass-material + (deep-flomap-material-value + 'glass 1.0 1.0 0.65 + 0.15 0.15 1.0 + 0.25 0.1 0.7 + 0.02)) + +(define diamond-material + (deep-flomap-material-value + 'diamond 1.0 1.0 0.5 + 0.15 0.15 1.0 + 0.15 0.1 0.7 + 0.02)) diff --git a/collects/images/private/deep-flomap.rkt b/collects/images/private/deep-flomap.rkt index 5ab232a45f..2f0f4b6a2c 100644 --- a/collects/images/private/deep-flomap.rkt +++ b/collects/images/private/deep-flomap.rkt @@ -1,486 +1,9 @@ -#lang racket/base +#lang typed/racket/base -(require racket/flonum racket/draw racket/match racket/math racket/contract racket/class - "unsafe.rkt" - "flomap.rkt") +(require "deep-flomap-struct.rkt" + "deep-flomap-parameters.rkt" + "deep-flomap-render.rkt") -(provide - (contract-out - ;; type, contructors and accessors - (struct deep-flomap ([argb flomap?] [z flomap?])) - [flomap->deep-flomap (flomap? . -> . deep-flomap?)] - [bitmap->deep-flomap ((is-a?/c bitmap%) . -> . deep-flomap?)] - [deep-flomap-width (deep-flomap? . -> . (fx>=/c 0))] - [deep-flomap-height (deep-flomap? . -> . (fx>=/c 0))] - [deep-flomap-z-min (deep-flomap? . -> . flonum?)] - [deep-flomap-z-max (deep-flomap? . -> . flonum?)] - [deep-flomap-size (deep-flomap? . -> . (values (fx>=/c 0) (fx>=/c 0)))] - [deep-flomap-alpha (deep-flomap? . -> . flomap?)] - [deep-flomap-rgb (deep-flomap? . -> . flomap?)] - ;; sizing - [deep-flomap-inset (case-> (deep-flomap? fixnum? . -> . deep-flomap?) - (deep-flomap? fixnum? fixnum? . -> . deep-flomap?) - (deep-flomap? fixnum? fixnum? fixnum? fixnum? . -> . deep-flomap?))] - [deep-flomap-trim (deep-flomap? . -> . deep-flomap?)] - [deep-flomap-scale (case-> (deep-flomap? (>/c 0.0) . -> . deep-flomap?) - (deep-flomap? (>/c 0.0) (>/c 0.0) (>/c 0.0) . -> . deep-flomap?))] - [deep-flomap-resize (deep-flomap? (or/c (>/c 0.0) #f) (or/c (>/c 0.0) #f) - (or/c real? #f) (or/c real? #f) - . -> . deep-flomap?)] - ;; z-adjusting - [deep-flomap-scale-z (deep-flomap? (or/c flomap? real?) . -> . deep-flomap?)] - [deep-flomap-smooth-z (deep-flomap? real? . -> . deep-flomap?)] - [deep-flomap-raise (deep-flomap? (or/c flomap? real?) . -> . deep-flomap?)] - [deep-flomap-tilt (deep-flomap? real? real? real? real? . -> . deep-flomap?)] - [deep-flomap-emboss (deep-flomap? real? real? . -> . deep-flomap?)] - [deep-flomap-bulge (deep-flomap? (flonum? flonum? . -> . real?) . -> . deep-flomap?)] - [deep-flomap-bulge-round (deep-flomap? real? . -> . deep-flomap?)] - [deep-flomap-bulge-round-rect (deep-flomap? real? . -> . deep-flomap?)] - [deep-flomap-bulge-spheroid (deep-flomap? real? . -> . deep-flomap?)] - [deep-flomap-bulge-horizontal (deep-flomap? real? . -> . deep-flomap?)] - [deep-flomap-bulge-vertical (deep-flomap? real? . -> . deep-flomap?)] - [deep-flomap-bulge-ripple (deep-flomap? real? real? . -> . deep-flomap?)] - ;; combining - [deep-flomap-pin (->* [deep-flomap? real? real? deep-flomap? real? real?] - [#:z-mode (one-of/c 'place 'replace 'add 'blend)] - deep-flomap?)] - [deep-flomap-pin* (->* [real? real? real? real? deep-flomap?] - [#:z-mode (one-of/c 'place 'replace 'add 'blend)] - #:rest (listof deep-flomap?) - deep-flomap?)] - [deep-flomap-lt-superimpose deep-flomap-superimpose/c] - [deep-flomap-lc-superimpose deep-flomap-superimpose/c] - [deep-flomap-lb-superimpose deep-flomap-superimpose/c] - [deep-flomap-ct-superimpose deep-flomap-superimpose/c] - [deep-flomap-cc-superimpose deep-flomap-superimpose/c] - [deep-flomap-cb-superimpose deep-flomap-superimpose/c] - [deep-flomap-rt-superimpose deep-flomap-superimpose/c] - [deep-flomap-rc-superimpose deep-flomap-superimpose/c] - [deep-flomap-rb-superimpose deep-flomap-superimpose/c] - [deep-flomap-vl-append deep-flomap-append/c] - [deep-flomap-vc-append deep-flomap-append/c] - [deep-flomap-vr-append deep-flomap-append/c] - [deep-flomap-ht-append deep-flomap-append/c] - [deep-flomap-hc-append deep-flomap-append/c] - [deep-flomap-hb-append deep-flomap-append/c] - [deep-flomap-superimpose/c contract?] - [deep-flomap-append/c contract?] - )) - -(struct deep-flomap (argb z) - #:guard - (λ (argb-fm z-fm name) - (match-define (flomap _ 4 w h) argb-fm) - (match-define (flomap _ 1 zw zh) z-fm) - (unless (and (= w zw) (= h zh)) - (error 'deep-flomap - "expected flomaps of equal dimension; given dimensions ~e×~e and ~e×~e" w h zw zh)) - (values argb-fm z-fm))) - -(define (flomap->deep-flomap argb-fm) - (match-define (flomap _ 4 w h) argb-fm) - (deep-flomap argb-fm (make-flomap 1 w h))) - -(define (bitmap->deep-flomap bm) - (flomap->deep-flomap (bitmap->flomap bm))) - -(define (deep-flomap-width dfm) - (flomap-width (deep-flomap-argb dfm))) - -(define (deep-flomap-height dfm) - (flomap-height (deep-flomap-argb dfm))) - -(define (deep-flomap-z-min dfm) - (flomap-min-value (deep-flomap-z dfm))) - -(define (deep-flomap-z-max dfm) - (flomap-max-value (deep-flomap-z dfm))) - -(define (deep-flomap-size dfm) - (values (deep-flomap-width dfm) (deep-flomap-height dfm))) - -(define (deep-flomap-alpha dfm) - (flomap-ref-component (deep-flomap-argb dfm) 0)) - -(define (deep-flomap-rgb dfm) - (flomap-drop-components (deep-flomap-argb dfm) 1)) - -;; =================================================================================================== -;; Z adjusters - -(define (deep-flomap-scale-z dfm z) - (match-define (deep-flomap argb-fm z-fm) dfm) - (deep-flomap argb-fm (fm* z-fm z))) - -(define (deep-flomap-smooth-z dfm σ) - (let ([σ (exact->inexact σ)]) - (match-define (deep-flomap argb-fm z-fm) dfm) - (define new-z-fm (flomap-blur z-fm σ)) - (deep-flomap argb-fm new-z-fm))) - -;; deep-flomap-raise and everything derived from it observe an invariant: -;; when z is added, added z must be 0.0 everywhere alpha is 0.0 - -(define (deep-flomap-raise dfm z) - (match-define (deep-flomap argb-fm z-fm) dfm) - (define alpha-fm (deep-flomap-alpha dfm)) - (deep-flomap argb-fm (fm+ z-fm (fm* alpha-fm z)))) - -(define (deep-flomap-emboss dfm xy-amt z-amt) - (let ([σ (/ xy-amt 3.0)]) - (define z-fm (flomap-normalize (deep-flomap-alpha dfm))) - (define new-z-fm (fm* (flomap-blur z-fm σ) - (exact->inexact z-amt))) - (deep-flomap-raise dfm new-z-fm))) - -(define-syntax-rule (unsafe-deep-flomap-bulge dfm f) - (let () - (define-values (w h) (deep-flomap-size dfm)) - (define half-x-size (unsafe-fl- (unsafe-fl* 0.5 (unsafe-fx->fl w)) 0.5)) - (define half-y-size (unsafe-fl- (unsafe-fl* 0.5 (unsafe-fx->fl h)) 0.5)) - (define z-fm - (unsafe-build-flomap - 1 w h - (λ (_ x y) - (f (unsafe-fl- (unsafe-fl/ (unsafe-fx->fl x) half-x-size) 1.0) - (unsafe-fl- (unsafe-fl/ (unsafe-fx->fl y) half-y-size) 1.0))))) - (deep-flomap-raise dfm z-fm))) - -(define (deep-flomap-bulge dfm f) - (unsafe-deep-flomap-bulge dfm (λ (cx cy) (exact->inexact (f cx cy))))) - -(define (deep-flomap-tilt dfm left-z-amt top-z-amt right-z-amt bottom-z-amt) - (let ([l (exact->inexact left-z-amt)] - [t (exact->inexact top-z-amt)] - [r (exact->inexact right-z-amt)] - [b (exact->inexact bottom-z-amt)]) - (define (f x y) - (define α (unsafe-fl/ (unsafe-fl+ x 1.0) 2.0)) - (define β (unsafe-fl/ (unsafe-fl+ y 1.0) 2.0)) - (unsafe-flsum (unsafe-fl* (unsafe-fl- 1.0 α) l) (unsafe-fl* α r) - (unsafe-fl* (unsafe-fl- 1.0 β) t) (unsafe-fl* β b))) - (unsafe-deep-flomap-bulge dfm f))) - -(define (deep-flomap-bulge-round dfm z-amt) - (let ([z-amt (exact->inexact z-amt)]) - (define (f x y) - (define d^2 (unsafe-fl+ (unsafe-fl* x x) (unsafe-fl* y y))) - (unsafe-fl* z-amt (unsafe-flsqrt (unsafe-fl/ (unsafe-fl- 2.0 d^2) 2.0)))) - (unsafe-deep-flomap-bulge dfm f))) - -(define (deep-flomap-bulge-round-rect dfm z-amt) - (let ([z-amt (exact->inexact z-amt)]) - (define (f x y) - (unsafe-fl* z-amt (unsafe-flsqrt - (unsafe-fl* (unsafe-fl- 1.0 (unsafe-fl* x x)) - (unsafe-fl- 1.0 (unsafe-fl* y y)))))) - (unsafe-deep-flomap-bulge dfm f))) - -(define (deep-flomap-bulge-spheroid dfm z-amt) - (let ([z-amt (exact->inexact z-amt)]) - (define (f x y) - (define d^2 (unsafe-fl+ (unsafe-fl* x x) (unsafe-fl* y y))) - (cond [(d^2 . unsafe-fl< . 1.0) - (unsafe-fl* z-amt (unsafe-flsqrt (unsafe-fl- 1.0 d^2)))] - [else 0.0])) - (unsafe-deep-flomap-bulge dfm f))) - -(define (deep-flomap-bulge-horizontal dfm z-amt) - (let ([z-amt (exact->inexact z-amt)]) - (define (f x _) - (define d^2 (unsafe-fl* x x)) - (unsafe-fl* z-amt (unsafe-flsqrt (unsafe-fl- 1.0 d^2)))) - (unsafe-deep-flomap-bulge dfm f))) - -(define (deep-flomap-bulge-vertical dfm z-amt) - (let ([z-amt (exact->inexact z-amt)]) - (define (f _ y) - (define d^2 (unsafe-fl* y y)) - (unsafe-fl* z-amt (unsafe-flsqrt (unsafe-fl- 1.0 d^2)))) - (unsafe-deep-flomap-bulge dfm f))) - -(define (deep-flomap-bulge-ripple dfm freq z-amt) - (let ([freq (exact->inexact freq)] - [z-amt (exact->inexact z-amt)]) - (define (f x y) - (define d^2 (unsafe-fl+ (unsafe-fl* x x) (unsafe-fl* y y))) - (define d (unsafe-flproduct freq pi (unsafe-flsqrt d^2))) - (unsafe-flproduct z-amt 0.5 (unsafe-fl- 1.0 (unsafe-flcos d)))) - (unsafe-deep-flomap-bulge dfm f))) - -;; =================================================================================================== -;; Sizing - -(define deep-flomap-inset - (case-lambda - [(dfm amt) - (deep-flomap-inset dfm amt amt amt amt)] - [(dfm h-amt v-amt) - (deep-flomap-inset dfm h-amt v-amt h-amt v-amt)] - [(dfm l-amt t-amt r-amt b-amt) - (match-define (deep-flomap argb-fm z-fm) dfm) - (deep-flomap (flomap-inset argb-fm l-amt t-amt r-amt b-amt) - (flomap-inset z-fm l-amt t-amt r-amt b-amt))])) - -(define (deep-flomap-trim dfm) - (define-values (w h) (deep-flomap-size dfm)) - (define-values (_k-min x-min y-min _k-max x-max y-max) - (flomap-nonzero-rect (deep-flomap-alpha dfm))) - (deep-flomap-inset dfm (- x-min) (- y-min) (- x-max w) (- y-max h))) - -(define deep-flomap-scale - (case-lambda - [(dfm scale) - (match-define (deep-flomap argb-fm z-fm) (deep-flomap-scale-z dfm scale)) - (deep-flomap (flomap-scale argb-fm scale) - (flomap-scale z-fm scale))] - [(dfm x-scale y-scale z-scale) - (match-define (deep-flomap argb-fm z-fm) (deep-flomap-scale-z dfm z-scale)) - (deep-flomap (flomap-scale argb-fm x-scale y-scale) - (flomap-scale z-fm x-scale y-scale))])) - -(define (deep-flomap-resize dfm width height z-min z-max) - (match-define (deep-flomap argb-fm z-fm) dfm) - (define new-z-fm - (cond [(or z-min z-max) - (let ([z-min (if z-min z-min (flomap-min-value z-fm))] - [z-max (if z-max z-max (flomap-max-value z-fm))]) - (fm+ (fm* (flomap-normalize z-fm) (- z-max z-min)) z-min))] - [else z-fm])) - (deep-flomap (flomap-resize argb-fm width height) - (flomap-resize new-z-fm width height))) - -;; =================================================================================================== -;; Combining - -(define (deep-flomap-pin dfm1 x1 y1 dfm2 x2 y2 #:z-mode [z-mode 'blend]) - (cond - [(not (and (zero? x2) (zero? y2))) - (deep-flomap-pin dfm1 (- x1 x2) (- y1 y2) dfm2 0 0 #:z-mode z-mode)] - [else - (define-values (w1 h1) (deep-flomap-size dfm1)) - (define-values (w2 h2) (deep-flomap-size dfm2)) - - ;; dfm1 and dfm2 offsets, in final image coordinates - (define dx1 (inexact->exact (round (max 0 (- x1))))) - (define dy1 (inexact->exact (round (max 0 (- y1))))) - (define dx2 (inexact->exact (round (max 0 x1)))) - (define dy2 (inexact->exact (round (max 0 y1)))) - ;; final image size - (define w (max (+ dx1 w1) (+ dx2 w2))) - (define h (max (+ dy1 h1) (+ dy2 h2))) - - (case z-mode - [(place) (deep-flomap-superimpose/place w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2)] - [(blend) (deep-flomap-superimpose/blend w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2)] - [(replace add) (deep-flomap-superimpose/replace w h - dfm1 dx1 dy1 w1 h1 - dfm2 dx2 dy2 w2 h2 z-mode)])])) - -(define (deep-flomap-superimpose/replace w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2 z-mode) - (match-define (deep-flomap argb1-fm z1-fm) dfm1) - (match-define (deep-flomap argb2-fm z2-fm) dfm2) - (define argb1-vs (flomap-values argb1-fm)) - (define argb2-vs (flomap-values argb2-fm)) - (define z1-vs (flomap-values z1-fm)) - (define z2-vs (flomap-values z2-fm)) - - (define-syntax-rule (get-argbz-pixel argb-vs z-vs dx dy w h x y) - (let ([x (unsafe-fx- x dx)] - [y (unsafe-fx- y dy)]) - (cond [(and (x . unsafe-fx>= . 0) (x . unsafe-fx< . w) - (y . unsafe-fx>= . 0) (y . unsafe-fx< . h)) - (define i (unsafe-fx+ x (unsafe-fx* y w))) - (define-values (a r g b) (unsafe-flvector-4ref argb-vs (unsafe-fx* 4 i))) - (define z (unsafe-flvector-ref z-vs i)) - (values a r g b z)] - [else - (values 0.0 0.0 0.0 0.0 0.0)]))) - - (define argb-vs (make-flvector (* 4 w h))) - (define z-vs (make-flvector (* w h))) - (for* ([y (in-range h)] [x (in-range w)]) - (define-values (a1 r1 g1 b1 z1) (get-argbz-pixel argb1-vs z1-vs dx1 dy1 w1 h1 x y)) - (define-values (a2 r2 g2 b2 z2) (get-argbz-pixel argb2-vs z2-vs dx2 dy2 w2 h2 x y)) - - (define i (unsafe-fx+ x (unsafe-fx* y w))) - (unsafe-flvector-4set! argb-vs (unsafe-fx* 4 i) - (unsafe-fl-alpha-blend a1 a2 a2) - (unsafe-fl-alpha-blend r1 r2 a2) - (unsafe-fl-alpha-blend g1 g2 a2) - (unsafe-fl-alpha-blend b1 b2 a2)) - (unsafe-flvector-set! z-vs i - (case z-mode - [(replace) (unsafe-fl-alpha-blend z1 z2 a2)] - [else (unsafe-fl+ z1 z2)]))) - - (deep-flomap (flomap argb-vs 4 w h) - (flomap z-vs 1 w h))) - -(define (deep-flomap-superimpose/place w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2) - (match-define (deep-flomap argb1-fm z1-fm) dfm1) - (match-define (deep-flomap argb2-fm z2-fm) dfm2) - (match-define (flomap argb1-vs 4 argb1-w argb1-h) argb1-fm) - (match-define (flomap argb2-vs 4 argb2-w argb2-h) argb2-fm) - (match-define (flomap z1-vs 1 z1-w z1-h) z1-fm) - (match-define (flomap z2-vs 1 z2-w z2-h) z2-fm) - - (define-syntax-rule (get-alpha-pixel vs dx dy w h x y) - (let ([x (unsafe-fx- x dx)] - [y (unsafe-fx- y dy)]) - (cond [(and (x . unsafe-fx>= . 0) (x . unsafe-fx< . w) - (y . unsafe-fx>= . 0) (y . unsafe-fx< . h)) - (unsafe-flvector-ref vs (unsafe-fx* 4 (unsafe-fx+ x (unsafe-fx* y w))))] - [else 0.0]))) - - (define-syntax-rule (get-z-pixel vs dx dy w h x y) - (let ([x (unsafe-fx- x dx)] - [y (unsafe-fx- y dy)]) - (cond [(and (x . unsafe-fx>= . 0) (x . unsafe-fx< . w) - (y . unsafe-fx>= . 0) (y . unsafe-fx< . h)) - (unsafe-flvector-ref vs (unsafe-fx+ x (unsafe-fx* y w)))] - [else 0.0]))) - - (define z1-max - (for*/fold ([z1-max -inf.0]) ([y (in-range h)] [x (in-range w)]) - (define a1 (get-alpha-pixel argb1-vs dx1 dy1 w1 h1 x y)) - (define a2 (get-alpha-pixel argb2-vs dx2 dy2 w2 h2 x y)) - (cond [(and (a1 . unsafe-fl> . 0.0) (a2 . unsafe-fl> . 0.0)) - (define z1 (get-z-pixel z1-vs dx1 dy1 w1 h1 x y)) - (unsafe-flmax z1-max z1)] - [else z1-max]))) - - (define new-dfm2 (deep-flomap argb2-fm (fm+ z2-fm z1-max))) - (deep-flomap-superimpose/replace w h dfm1 dx1 dy1 w1 h1 new-dfm2 dx2 dy2 w2 h2 'replace)) - -(define (deep-flomap-superimpose/blend w h dfm1 dx1 dy1 w1 h1 dfm2 dx2 dy2 w2 h2) - (match-define (deep-flomap argb1-fm z1-fm) dfm1) - (match-define (deep-flomap argb2-fm z2-fm) dfm2) - (define argb1-vs (flomap-values argb1-fm)) - (define argb2-vs (flomap-values argb2-fm)) - (define z1-vs (flomap-values z1-fm)) - (define z2-vs (flomap-values z2-fm)) - - (define-values (u1-fm v1-fm) (flomap-gradient z1-fm)) - (define-values (u2-fm v2-fm) (flomap-gradient z2-fm)) - (define u1-vs (flomap-values u1-fm)) - (define v1-vs (flomap-values v1-fm)) - (define u2-vs (flomap-values u2-fm)) - (define v2-vs (flomap-values v2-fm)) - - (define-syntax-rule (get-argbzuv-pixel argb-vs z-vs u-vs v-vs dx dy w h x y) - (let ([x (unsafe-fx- x dx)] - [y (unsafe-fx- y dy)]) - (cond [(and (x . unsafe-fx>= . 0) (x . unsafe-fx< . w) - (y . unsafe-fx>= . 0) (y . unsafe-fx< . h)) - (define i (unsafe-fx+ x (unsafe-fx* y w))) - (define-values (a r g b) (unsafe-flvector-4ref argb-vs (unsafe-fx* 4 i))) - (define z (unsafe-flvector-ref z-vs i)) - (define u (unsafe-flvector-ref u-vs i)) - (define v (unsafe-flvector-ref v-vs i)) - (values a r g b z u v)] - [else - (values 0.0 0.0 0.0 0.0 0.0 0.0 0.0)]))) - - (define argb-vs (make-flvector (* 4 w h))) - (define z-vs (make-flvector (* w h))) - (for* ([y (in-range h)] [x (in-range w)]) - (define-values (a1 r1 g1 b1 z1 u1 v1) - (get-argbzuv-pixel argb1-vs z1-vs u1-vs v1-vs dx1 dy1 w1 h1 x y)) - (define-values (a2 r2 g2 b2 z2 u2 v2) - (get-argbzuv-pixel argb2-vs z2-vs u2-vs v2-vs dx2 dy2 w2 h2 x y)) - - #;; max blending: if both alphas nonzero and unequal, keep the pixel with greatest z - (define α - (cond [(and (a1 . unsafe-fl> . 0.0) (a2 . unsafe-fl> . 0.0)) - (cond [(a1 . unsafe-fl> . a2) 0.0] - [(a2 . unsafe-fl> . a1) 1.0] - [else (cond [(z1 . unsafe-fl> . z2) 0.0] - [(z2 . unsafe-fl> . z1) 1.0] - [else 0.5])])] - [(a1 . unsafe-fl> . 0.0) 0.0] - [(a2 . unsafe-fl> . 0.0) 1.0] - [else 0.5])) - ;; softmax blending - (define α - (cond [(and (a1 . unsafe-fl> . 0.0) (a2 . unsafe-fl> . 0.0)) - (define u (unsafe-fl- (unsafe-fl* a2 u2) (unsafe-fl* a1 u1))) - (define v (unsafe-fl- (unsafe-fl* a2 v2) (unsafe-fl* a1 v1))) - (define β (unsafe-fl/ (unsafe-fl- (unsafe-fl* a2 z2) (unsafe-fl* a1 z1)) - (unsafe-flsqrt (unsafe-fl+ (unsafe-fl* u u) (unsafe-fl* v v))))) - (unsafe-flsigmoid (unsafe-fl* 15.0 β))] - [(a1 . unsafe-fl> . 0.0) 0.0] - [(a2 . unsafe-fl> . 0.0) 1.0] - [else 0.5])) - - (define i (unsafe-fx+ x (unsafe-fx* y w))) - (unsafe-flvector-4set! argb-vs (unsafe-fx* 4 i) - (unsafe-fl-convex-combination a1 a2 α) - (unsafe-fl-convex-combination r1 r2 α) - (unsafe-fl-convex-combination g1 g2 α) - (unsafe-fl-convex-combination b1 b2 α)) - (unsafe-flvector-set! z-vs i (unsafe-fl-convex-combination z1 z2 α))) - - (deep-flomap (flomap argb-vs 4 w h) - (flomap z-vs 1 w h))) - -(define (deep-flomap-pin* x1-frac y1-frac x2-frac y2-frac dfm #:z-mode [z-mode 'blend] . dfms) - (for/fold ([dfm1 dfm]) ([dfm2 (in-list dfms)]) - (define-values (w1 h1) (deep-flomap-size dfm1)) - (define-values (w2 h2) (deep-flomap-size dfm2)) - (deep-flomap-pin dfm1 (* x1-frac w1) (* y1-frac h1) - dfm2 (* x2-frac w2) (* y2-frac h2) #:z-mode z-mode))) - -(define deep-flomap-superimpose/c (->* [deep-flomap?] - [#:z-mode (one-of/c 'place 'replace 'add 'blend)] - #:rest (listof deep-flomap?) - deep-flomap?)) - -(define (deep-flomap-lt-superimpose dfm #:z-mode [z-mode 'blend] . dfms) - (apply deep-flomap-pin* 0 0 0 0 dfm dfms #:z-mode z-mode)) - -(define (deep-flomap-lc-superimpose dfm #:z-mode [z-mode 'blend] . dfms) - (apply deep-flomap-pin* 0 1/2 0 1/2 dfm dfms #:z-mode z-mode)) - -(define (deep-flomap-lb-superimpose dfm #:z-mode [z-mode 'blend] . dfms) - (apply deep-flomap-pin* 0 1 0 1 dfm dfms #:z-mode z-mode)) - -(define (deep-flomap-ct-superimpose dfm #:z-mode [z-mode 'blend] . dfms) - (apply deep-flomap-pin* 1/2 0 1/2 0 dfm dfms #:z-mode z-mode)) - -(define (deep-flomap-cc-superimpose dfm #:z-mode [z-mode 'blend] . dfms) - (apply deep-flomap-pin* 1/2 1/2 1/2 1/2 dfm dfms #:z-mode z-mode)) - -(define (deep-flomap-cb-superimpose dfm #:z-mode [z-mode 'blend] . dfms) - (apply deep-flomap-pin* 1/2 1 1/2 1 dfm dfms #:z-mode z-mode)) - -(define (deep-flomap-rt-superimpose dfm #:z-mode [z-mode 'blend] . dfms) - (apply deep-flomap-pin* 1 0 1 0 dfm dfms #:z-mode z-mode)) - -(define (deep-flomap-rc-superimpose dfm #:z-mode [z-mode 'blend] . dfms) - (apply deep-flomap-pin* 1 1/2 1 1/2 dfm dfms #:z-mode z-mode)) - -(define (deep-flomap-rb-superimpose dfm #:z-mode [z-mode 'blend] . dfms) - (apply deep-flomap-pin* 1 1 1 1 dfm dfms #:z-mode z-mode)) - -(define deep-flomap-append/c (->* [deep-flomap?] - #:rest (listof deep-flomap?) - deep-flomap?)) - -(define (deep-flomap-vl-append dfm . dfms) - (apply deep-flomap-pin* 0 1 0 0 dfm dfms #:z-mode 'add)) - -(define (deep-flomap-vc-append dfm . dfms) - (apply deep-flomap-pin* 1/2 1 1/2 0 dfm dfms #:z-mode 'add)) - -(define (deep-flomap-vr-append dfm . dfms) - (apply deep-flomap-pin* 1 1 1 0 dfm dfms #:z-mode 'add)) - -(define (deep-flomap-ht-append dfm . dfms) - (apply deep-flomap-pin* 1 0 0 0 dfm dfms #:z-mode 'add)) - -(define (deep-flomap-hc-append dfm . dfms) - (apply deep-flomap-pin* 1 1/2 0 1/2 dfm dfms #:z-mode 'add)) - -(define (deep-flomap-hb-append dfm . dfms) - (apply deep-flomap-pin* 1 1 0 1 dfm dfms #:z-mode 'add)) +(provide (all-from-out "deep-flomap-struct.rkt" + "deep-flomap-parameters.rkt" + "deep-flomap-render.rkt")) diff --git a/collects/images/private/draw-predicates.rkt b/collects/images/private/draw-predicates.rkt new file mode 100644 index 0000000000..b0a9c4a011 --- /dev/null +++ b/collects/images/private/draw-predicates.rkt @@ -0,0 +1,11 @@ +#lang racket/base + +(require racket/draw racket/class) + +(provide bitmap? dc?) + +(define (bitmap? bm) + (bm . is-a? . bitmap%)) + +(define (dc? dc) + (dc . is-a? . dc<%>)) diff --git a/collects/images/private/flomap-blur.rkt b/collects/images/private/flomap-blur.rkt new file mode 100644 index 0000000000..22b75829af --- /dev/null +++ b/collects/images/private/flomap-blur.rkt @@ -0,0 +1,338 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match racket/math + "flonum.rkt" + "flomap-struct.rkt") + +(provide flomap-gaussian-blur-x flomap-gaussian-blur-y flomap-gaussian-blur + flomap-box-blur-x flomap-box-blur-y flomap-box-blur + flomap-blur-x flomap-blur-y flomap-blur) + +;; =================================================================================================== +;; Gaussian blur + +(: flomap-gaussian-blur (case-> (flomap Real -> flomap) + (flomap Real Real -> flomap))) +(define flomap-gaussian-blur + (case-lambda + [(fm xσ) (flomap-gaussian-blur fm xσ xσ)] + [(fm xσ yσ) + (flomap-gaussian-blur-y (flomap-gaussian-blur-x fm (abs (exact->inexact xσ))) + (abs (exact->inexact yσ)))])) + +(: flomap-gaussian-blur-x (flomap Flonum -> flomap)) +(define (flomap-gaussian-blur-x fm σ) + (cond + [(σ . = . 0.0) fm] + [else + (define dx-min (fl->fx (floor (* (- 3.0) σ)))) + (define dx-max (fx+ 1 (fl->fx (ceiling (* 3.0 σ))))) + (define ss (gaussian-kernel-1d dx-min dx-max σ)) + + (match-define (flomap vs c w h) fm) + (inline-build-flomap + c w h + (λ (k x y i) + (define dx-start (fx- (fxmax (fx+ x dx-min) 0) x)) + (define dx-end (fx- (fxmin (fx+ x dx-max) w) x)) + (define j (fx+ i (fx* c dx-start))) + (let: src-loop : Flonum ([sum : Flonum 0.0] [dx : Fixnum dx-start] [j : Fixnum j]) + (cond [(dx . fx< . dx-end) (define s (unsafe-flvector-ref ss (fx- dx dx-min))) + (src-loop (+ sum (* s (unsafe-flvector-ref vs j))) + (fx+ dx 1) + (fx+ j c))] + [else sum]))))])) + +(: flomap-gaussian-blur-y (flomap Flonum -> flomap)) +(define (flomap-gaussian-blur-y fm σ) + (cond + [(σ . = . 0.0) fm] + [else + (define dy-min (fl->fx (floor (* (- 3.0) σ)))) + (define dy-max (fx+ 1 (fl->fx (ceiling (* 3.0 σ))))) + (define ss (gaussian-kernel-1d dy-min dy-max σ)) + + (match-define (flomap vs c w h) fm) + (define cw (* c w)) + (inline-build-flomap + c w h + (λ (k x y i) + (define dy-start (fx- (fxmax (fx+ y dy-min) 0) y)) + (define dy-end (fx- (fxmin (fx+ y dy-max) h) y)) + (define j (fx+ i (fx* cw dy-start))) + (let: src-loop : Flonum ([sum : Flonum 0.0] [dy : Fixnum dy-start] [j : Fixnum j]) + (cond [(dy . fx< . dy-end) (define s (unsafe-flvector-ref ss (fx- dy dy-min))) + (src-loop (+ sum (* s (unsafe-flvector-ref vs j))) + (fx+ dy 1) + (fx+ j cw))] + [else sum]))))])) + +(: gaussian-kernel-1d (Fixnum Fixnum Flonum -> FlVector)) +(define (gaussian-kernel-1d mn mx σ) + (define n (fx- mx mn)) + (define ys (make-flvector n)) + (define sum + (let: loop : Flonum ([i : Fixnum 0] [sum : Flonum 0.0]) + (cond [(i . fx< . n) (define v (flgaussian (fx->fl (fx+ i mn)) σ)) + (unsafe-flvector-set! ys i v) + (loop (fx+ i 1) (+ sum v))] + [else sum]))) + (let: loop : FlVector ([i : Integer 0]) + (cond [(i . fx< . n) (unsafe-flvector-set! ys i (/ (unsafe-flvector-ref ys i) sum)) + (loop (fx+ i 1))] + [else ys]))) + + +;; =================================================================================================== +;; Integral images + +(: flomap-integral (flomap -> flomap)) +(define (flomap-integral fm) + (match-define (flomap vs c w h) fm) + (define w+1 (fx+ w 1)) + (define c*w+1 (fx* c w+1)) + (define h+1 (fx+ h 1)) + (define new-vs (make-flvector (* c w+1 h+1))) + (let: y-loop : Void ([y : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum 0]) + (when (y . fx< . h) + (let: x-loop : Void ([x : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum i]) + (cond [(x . fx< . w) + (let: k-loop : Void ([k : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum i]) + (cond [(k . fx< . c) + (define j00 (coords->index c w+1 k x y)) + (define j01 (fx+ j00 c*w+1)) + (unsafe-flvector-set! new-vs (fx+ j01 c) + (- (+ (unsafe-flvector-ref vs i) + (unsafe-flvector-ref new-vs j01) + (unsafe-flvector-ref new-vs (fx+ j00 c))) + (unsafe-flvector-ref new-vs j00))) + (k-loop (fx+ k 1) (fx+ i 1))] + [else (x-loop (fx+ x 1) i)]))] + [else (y-loop (fx+ y 1) i)])))) + (flomap new-vs c w+1 h+1)) + +(: flomap-integral-x (flomap -> flomap)) +(define (flomap-integral-x fm) + (match-define (flomap vs c w h) fm) + (define w+1 (fx+ w 1)) + (define new-vs (make-flvector (* c w+1 h))) + (let: y-loop : Void ([y : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum 0]) + (when (y . fx< . h) + (let: x-loop : Void ([x : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum i]) + (cond [(x . fx< . w) + (let: k-loop : Void ([k : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum i]) + (cond [(k . fx< . c) + (define j0 (coords->index c w+1 k x y)) + (define j1 (fx+ j0 c)) + (unsafe-flvector-set! new-vs j1 (+ (unsafe-flvector-ref vs i) + (unsafe-flvector-ref new-vs j0))) + (k-loop (fx+ k 1) (fx+ i 1))] + [else (x-loop (fx+ x 1) i)]))] + [else (y-loop (fx+ y 1) i)])))) + (flomap new-vs c w+1 h)) + +(: flomap-integral-y (flomap -> flomap)) +(define (flomap-integral-y fm) + (match-define (flomap vs c w h) fm) + (define h+1 (fx+ h 1)) + (define cw (fx* c w)) + (define new-vs (make-flvector (* c w h+1))) + (let: y-loop : Void ([y : Nonnegative-Fixnum 0]) + (when (y . fx< . h) + (let: x-loop : Void ([x : Nonnegative-Fixnum 0]) + (cond [(x . fx< . w) + (let: k-loop : Void ([k : Nonnegative-Fixnum 0]) + (cond [(k . fx< . c) + (define j0 (coords->index c w k x y)) + (define j1 (fx+ j0 cw)) + (unsafe-flvector-set! new-vs j1 (+ (unsafe-flvector-ref vs j0) + (unsafe-flvector-ref new-vs j0))) + (k-loop (fx+ k 1))] + [else (x-loop (fx+ x 1))]))] + [else (y-loop (fx+ y 1))])))) + (flomap new-vs c w h+1)) + +(: raw-flomap-integral-sum (FlVector Integer Integer Integer + Integer Integer Integer Integer Integer + -> Flonum)) +(define (raw-flomap-integral-sum vs c w h k x-start y-start x-end y-end) + (define w-1 (fx- w 1)) + (define h-1 (fx- h 1)) + (define x1 (fxmax 0 (fxmin x-start w-1))) + (define x2 (fxmax 0 (fxmin x-end w-1))) + (define y1 (fxmax 0 (fxmin y-start h-1))) + (define y2 (fxmax 0 (fxmin y-end h-1))) + (- (+ (unsafe-flvector-ref vs (coords->index c w k x1 y1)) + (unsafe-flvector-ref vs (coords->index c w k x2 y2))) + (+ (unsafe-flvector-ref vs (coords->index c w k x1 y2)) + (unsafe-flvector-ref vs (coords->index c w k x2 y1))))) + +(: raw-flomap-integral-x-sum (FlVector Integer Integer + Integer Integer Integer Integer -> Flonum)) +(define (raw-flomap-integral-x-sum vs c w k x-start x-end y) + (define w-1 (fx- w 1)) + (define x1 (fxmax 0 (fxmin x-start w-1))) + (define x2 (fxmax 0 (fxmin x-end w-1))) + (- (unsafe-flvector-ref vs (coords->index c w k x2 y)) + (unsafe-flvector-ref vs (coords->index c w k x1 y)))) + +(: raw-flomap-integral-y-sum (FlVector Integer Integer Integer + Integer Integer Integer Integer -> Flonum)) +(define (raw-flomap-integral-y-sum vs c w h k x y-start y-end) + (define h-1 (fx- h 1)) + (define y1 (fxmax 0 (fxmin y-start h-1))) + (define y2 (fxmax 0 (fxmin y-end h-1))) + (- (unsafe-flvector-ref vs (coords->index c w k x y2)) + (unsafe-flvector-ref vs (coords->index c w k x y1)))) + +;; =================================================================================================== +;; Box blur + +(: flomap-box-blur (case-> (flomap Real -> flomap) + (flomap Real Real -> flomap))) +(define flomap-box-blur + (case-lambda + [(fm xr) (flomap-box-blur fm xr xr)] + [(fm xr yr) + (let ([xr (abs (exact->inexact xr))] [yr (abs (exact->inexact yr))]) + (cond [(and (integer? xr) (integer? yr)) + (let ([xr (fl->fx xr)] [yr (fl->fx yr)]) + (with-asserts ([xr nonnegative-fixnum?] [yr nonnegative-fixnum?]) + (flomap-box-blur/int fm xr yr)))] + [else + (flomap-box-blur-y (flomap-box-blur-x fm xr) yr)]))])) + +(: flomap-box-blur-x (flomap Flonum -> flomap)) +(define (flomap-box-blur-x fm r) + (cond + [(integer? r) (let ([r (fl->fx r)]) + (with-asserts ([r nonnegative-fixnum?]) + (flomap-box-blur-x/int fm r)))] + [else + (define r1 (fl->fx (floor r))) + (define r2 (fx+ r1 1)) + (define s (+ 1.0 (* 2.0 r))) + (define s1 (+ 1.0 (* 2.0 r1))) + (define s2 (+ 1.0 (* 2.0 r2))) + (define α (/ (- (sqr s2) (sqr s)) (- (sqr s2) (sqr s1)))) + (define norm1 (/ α s1)) + (define norm2 (/ (- 1.0 α) s2)) + (define r1+1 (fx+ r1 1)) + (define r2+1 (fx+ r2 1)) + (match-define (flomap _ c w h) fm) + (match-define (flomap int-vs int-c int-w int-h) (flomap-integral-x fm)) + (inline-build-flomap + c w h + (λ (k x y _i) + (+ (* norm1 (raw-flomap-integral-x-sum int-vs int-c int-w k (fx- x r1) (fx+ x r1+1) y)) + (* norm2 (raw-flomap-integral-x-sum int-vs int-c int-w k (fx- x r2) (fx+ x r2+1) y)) + )))])) + +(: flomap-box-blur-y (flomap Flonum -> flomap)) +(define (flomap-box-blur-y fm r) + (cond + [(integer? r) (let ([r (fl->fx r)]) + (with-asserts ([r nonnegative-fixnum?]) + (flomap-box-blur-y/int fm r)))] + [else + (define r1 (fl->fx (floor r))) + (define r2 (fx+ r1 1)) + (define s (+ 1.0 (* 2.0 r))) + (define s1 (+ 1.0 (* 2.0 r1))) + (define s2 (+ 1.0 (* 2.0 r2))) + (define α (/ (- (sqr s2) (sqr s)) (- (sqr s2) (sqr s1)))) + (define norm1 (/ α s1)) + (define norm2 (/ (- 1.0 α) s2)) + (define r1+1 (fx+ r1 1)) + (define r2+1 (fx+ r2 1)) + (match-define (flomap _ c w h) fm) + (match-define (flomap int-vs int-c int-w int-h) (flomap-integral-y fm)) + (inline-build-flomap + c w h + (λ (k x y _i) + (+ (* norm1 (raw-flomap-integral-y-sum int-vs int-c int-w int-h k x (fx- y r1) (fx+ y r1+1))) + (* norm2 (raw-flomap-integral-y-sum int-vs int-c int-w int-h k x (fx- y r2) (fx+ y r2+1))) + )))])) + +(: flomap-box-blur/int (flomap Nonnegative-Fixnum Nonnegative-Fixnum -> flomap)) +(define (flomap-box-blur/int fm xr yr) + (define norm (/ 1.0 (* (+ 1.0 (* 2.0 xr)) (+ 1.0 (* 2.0 yr))))) + (define xr+1 (fx+ xr 1)) + (define yr+1 (fx+ yr 1)) + (match-define (flomap _ c w h) fm) + (match-define (flomap int-vs int-c int-w int-h) (flomap-integral fm)) + (inline-build-flomap + c w h + (λ (k x y _i) + (* norm (raw-flomap-integral-sum int-vs int-c int-w int-h k + (fx- x xr) (fx- y yr) + (fx+ x xr+1) (fx+ y yr+1)))))) + +(: flomap-box-blur-x/int (flomap Nonnegative-Fixnum -> flomap)) +(define (flomap-box-blur-x/int fm r) + (define norm (/ 1.0 (+ 1.0 (* 2.0 r)))) + (define r+1 (fx+ r 1)) + (match-define (flomap _ c w h) fm) + (match-define (flomap int-vs int-c int-w int-h) (flomap-integral-x fm)) + (inline-build-flomap + c w h + (λ (k x y _i) + (* norm (raw-flomap-integral-x-sum int-vs int-c int-w k (fx- x r) (fx+ x r+1) y))))) + +(: flomap-box-blur-y/int (flomap Nonnegative-Fixnum -> flomap)) +(define (flomap-box-blur-y/int fm r) + (define norm (/ 1.0 (+ 1.0 (* 2.0 r)))) + (define r+1 (fx+ r 1)) + (match-define (flomap _ c w h) fm) + (match-define (flomap int-vs int-c int-w int-h) (flomap-integral-y fm)) + (inline-build-flomap + c w h + (λ (k x y _i) + (* norm (raw-flomap-integral-y-sum int-vs int-c int-w int-h k x (fx- y r) (fx+ y r+1)))))) + +;; =================================================================================================== +;; Default blur + +(: box-radius->variance (Flonum -> Flonum)) +(define (box-radius->variance r) + (* 1/12 (sqr (+ 1 (* 2 r))))) + +(: variance->box-radius (Flonum -> Flonum)) +(define (variance->box-radius σ^2) + (* 1/2 (- (flsqrt (* 12 σ^2)) 1))) + +(: flomap-blur (case-> (flomap Real -> flomap) + (flomap Real Real -> flomap))) +(define flomap-blur + (case-lambda + [(fm σ) (flomap-blur fm σ σ)] + [(fm xσ yσ) + (let ([xσ (abs (exact->inexact xσ))] [yσ (abs (exact->inexact yσ))]) + (cond + [(and (xσ . >= . 1.5) (yσ . >= . 1.5)) + (define xσ^2 (sqr xσ)) + (define yσ^2 (sqr yσ)) + (define xr (floor (variance->box-radius (/ xσ^2 3.0)))) + (define yr (floor (variance->box-radius (/ yσ^2 3.0)))) + (flomap-box-blur (flomap-box-blur (flomap-box-blur fm xr yr) xr yr) + (variance->box-radius (- xσ^2 (* 2.0 (box-radius->variance xr)))) + (variance->box-radius (- yσ^2 (* 2.0 (box-radius->variance yr)))))] + [else + (flomap-blur-x (flomap-blur-y fm yσ) xσ)]))])) + +(: make-flomap-blur-dimension + ((flomap Flonum -> flomap) (flomap Flonum -> flomap) -> (flomap Flonum -> flomap))) +(define ((make-flomap-blur-dimension gaussian-blur box-blur) fm σ) + (cond + [(σ . = . 0.0) fm] + [(σ . < . 1.5) (gaussian-blur fm σ)] + [else + (define σ^2 (sqr σ)) + (define r (floor (variance->box-radius (/ σ^2 3.0)))) + (box-blur (box-blur (box-blur fm r) r) + (variance->box-radius (- σ^2 (* 2.0 (box-radius->variance r)))))])) + +(define flomap-blur-x (make-flomap-blur-dimension flomap-gaussian-blur-x flomap-box-blur-x)) +(define flomap-blur-y (make-flomap-blur-dimension flomap-gaussian-blur-y flomap-box-blur-y)) diff --git a/collects/images/private/flomap-composite.rkt b/collects/images/private/flomap-composite.rkt new file mode 100644 index 0000000000..b5c925a85c --- /dev/null +++ b/collects/images/private/flomap-composite.rkt @@ -0,0 +1,103 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match + "flonum.rkt" + "flomap-struct.rkt") + +(provide flomap-pin flomap-pin* + flomap-lt-superimpose flomap-lc-superimpose flomap-lb-superimpose + flomap-ct-superimpose flomap-cc-superimpose flomap-cb-superimpose + flomap-rt-superimpose flomap-rc-superimpose flomap-rb-superimpose + flomap-vl-append flomap-vc-append flomap-vr-append + flomap-ht-append flomap-hc-append flomap-hb-append) + +(: flomap-pin (flomap Real Real flomap Real Real -> flomap)) +(define (flomap-pin fm1 x1 y1 fm2 x2 y2) + (cond + [(not (and (zero? x2) (zero? y2))) + (flomap-pin fm1 (- x1 x2) (- y1 y2) fm2 0 0)] + [else + (let ([x1 (exact->inexact x1)] [y1 (exact->inexact y1)]) + (match-define (flomap argb1-vs 4 w1 h1) fm1) + (match-define (flomap argb2-vs 4 w2 h2) fm2) + + ;; fm1 and fm2 offsets, in final image coordinates + (define dx1 (fl->fx (round (max 0.0 (- x1))))) + (define dy1 (fl->fx (round (max 0.0 (- y1))))) + (define dx2 (fl->fx (round (max 0.0 x1)))) + (define dy2 (fl->fx (round (max 0.0 y1)))) + + ;; final image size + (define w (fxmax (fx+ dx1 w1) (fx+ dx2 w2))) + (define h (fxmax (fx+ dy1 h1) (fx+ dy2 h2))) + + (define-syntax-rule (get-argb-pixel argb-vs dx dy w h x y) + (let ([x (fx- x dx)] [y (fx- y dy)]) + (cond [(and (x . fx>= . 0) (x . fx< . w) (y . fx>= . 0) (y . fx< . h)) + (define i (coords->index 4 w 0 x y)) + (values (unsafe-flvector-ref argb-vs i) + (unsafe-flvector-ref argb-vs (fx+ i 1)) + (unsafe-flvector-ref argb-vs (fx+ i 2)) + (unsafe-flvector-ref argb-vs (fx+ i 3)))] + [else (values 0.0 0.0 0.0 0.0)]))) + + (define argb-vs (make-flvector (* 4 w h))) + (let: y-loop : Void ([y : Nonnegative-Fixnum 0]) + (when (y . fx< . h) + (let: x-loop : Void ([x : Nonnegative-Fixnum 0]) + (cond + [(x . fx< . w) + (define-values (a1 r1 g1 b1) (get-argb-pixel argb1-vs dx1 dy1 w1 h1 x y)) + (define-values (a2 r2 g2 b2) (get-argb-pixel argb2-vs dx2 dy2 w2 h2 x y)) + (define i (coords->index 4 w 0 x y)) + (unsafe-flvector-set! argb-vs i (fl-alpha-blend a1 a2 a2)) + (unsafe-flvector-set! argb-vs (fx+ i 1) (fl-alpha-blend r1 r2 a2)) + (unsafe-flvector-set! argb-vs (fx+ i 2) (fl-alpha-blend g1 g2 a2)) + (unsafe-flvector-set! argb-vs (fx+ i 3) (fl-alpha-blend b1 b2 a2)) + (x-loop (fx+ x 1))] + [else (y-loop (fx+ y 1))])))) + (flomap argb-vs 4 w h))])) + +(: flomap-pin* (Real Real Real Real flomap flomap * -> flomap)) +(define (flomap-pin* x1-frac y1-frac x2-frac y2-frac fm . fms) + (for/fold ([fm1 fm]) ([fm2 (in-list fms)]) + (define-values (w1 h1) (flomap-size fm1)) + (define-values (w2 h2) (flomap-size fm2)) + (flomap-pin fm1 (* x1-frac w1) (* y1-frac h1) + fm2 (* x2-frac w2) (* y2-frac h2)))) + +(: flomap-lt-superimpose (flomap flomap * -> flomap)) +(: flomap-lc-superimpose (flomap flomap * -> flomap)) +(: flomap-lb-superimpose (flomap flomap * -> flomap)) +(: flomap-ct-superimpose (flomap flomap * -> flomap)) +(: flomap-cc-superimpose (flomap flomap * -> flomap)) +(: flomap-cb-superimpose (flomap flomap * -> flomap)) +(: flomap-rt-superimpose (flomap flomap * -> flomap)) +(: flomap-rc-superimpose (flomap flomap * -> flomap)) +(: flomap-rb-superimpose (flomap flomap * -> flomap)) + +(define (flomap-lt-superimpose fm . fms) (apply flomap-pin* 0 0 0 0 fm fms)) +(define (flomap-lc-superimpose fm . fms) (apply flomap-pin* 0 1/2 0 1/2 fm fms)) +(define (flomap-lb-superimpose fm . fms) (apply flomap-pin* 0 1 0 1 fm fms)) +(define (flomap-ct-superimpose fm . fms) (apply flomap-pin* 1/2 0 1/2 0 fm fms)) +(define (flomap-cc-superimpose fm . fms) (apply flomap-pin* 1/2 1/2 1/2 1/2 fm fms)) +(define (flomap-cb-superimpose fm . fms) (apply flomap-pin* 1/2 1 1/2 1 fm fms)) +(define (flomap-rt-superimpose fm . fms) (apply flomap-pin* 1 0 1 0 fm fms)) +(define (flomap-rc-superimpose fm . fms) (apply flomap-pin* 1 1/2 1 1/2 fm fms)) +(define (flomap-rb-superimpose fm . fms) (apply flomap-pin* 1 1 1 1 fm fms)) + +(: flomap-vl-append (flomap flomap * -> flomap)) +(: flomap-vc-append (flomap flomap * -> flomap)) +(: flomap-vr-append (flomap flomap * -> flomap)) +(: flomap-ht-append (flomap flomap * -> flomap)) +(: flomap-hc-append (flomap flomap * -> flomap)) +(: flomap-hb-append (flomap flomap * -> flomap)) + +(define (flomap-vl-append fm . fms) (apply flomap-pin* 0 1 0 0 fm fms)) +(define (flomap-vc-append fm . fms) (apply flomap-pin* 1/2 1 1/2 0 fm fms)) +(define (flomap-vr-append fm . fms) (apply flomap-pin* 1 1 1 0 fm fms)) +(define (flomap-ht-append fm . fms) (apply flomap-pin* 1 0 0 0 fm fms)) +(define (flomap-hc-append fm . fms) (apply flomap-pin* 1 1/2 0 1/2 fm fms)) +(define (flomap-hb-append fm . fms) (apply flomap-pin* 1 1 0 1 fm fms)) diff --git a/collects/images/private/flomap-convert.rkt b/collects/images/private/flomap-convert.rkt new file mode 100644 index 0000000000..47d359ce89 --- /dev/null +++ b/collects/images/private/flomap-convert.rkt @@ -0,0 +1,87 @@ +#lang racket/base + +(require racket/draw racket/class racket/match + racket/unsafe/ops + "flomap-struct.rkt" + "flomap-pointwise.rkt" + "flomap-resize.rkt") + +(provide bitmap->flomap flomap->bitmap draw-flomap) + +(define-syntax-rule (unsafe-fl->byte y) + (let ([x (unsafe-flmax 0.0 (unsafe-flmin 255.0 y))]) + (cond [(and (x . unsafe-fl> . -inf.0) (x . unsafe-fl< . +inf.0)) + (unsafe-fl->fx (unsafe-flround x))] + [else 0.0]))) + +(define (bitmap->flomap bm) + (define w (send bm get-width)) + (define h (send bm get-height)) + (define bs (make-bytes (* 4 w h))) + ;; get bytes without premultiplying alpha because doing it in flonums maintains precision + ;; (if RGB bytes are stored without premultiplying alpha) + (send bm get-argb-pixels 0 0 w h bs #t) + (send bm get-argb-pixels 0 0 w h bs #f) + + (define argb-fm (make-flomap 4 w h)) + (define argb-vs (flomap-values argb-fm)) + (for ([i0 (in-range 0 (* 4 w h) 4)]) + (define i1 (unsafe-fx+ i0 1)) + (define i2 (unsafe-fx+ i0 2)) + (define i3 (unsafe-fx+ i0 3)) + (define a (unsafe-bytes-ref bs i0)) + (define r (unsafe-bytes-ref bs i1)) + (define g (unsafe-bytes-ref bs i2)) + (define b (unsafe-bytes-ref bs i3)) + (unsafe-flvector-set! argb-vs i0 (unsafe-fl/ (unsafe-fx->fl a) 255.0)) + (unsafe-flvector-set! argb-vs i1 (unsafe-fl/ (unsafe-fx->fl r) 255.0)) + (unsafe-flvector-set! argb-vs i2 (unsafe-fl/ (unsafe-fx->fl g) 255.0)) + (unsafe-flvector-set! argb-vs i3 (unsafe-fl/ (unsafe-fx->fl b) 255.0))) + + (flomap-multiply-alpha argb-fm)) + +(define (flomap->bitmap fm) + (match-define (flomap vs c w h) fm) + (let* ([fm (case c + [(0) (make-flomap 4 w h)] + [(1) (flomap-append-components (make-flomap 1 w h 1.0) fm fm fm)] + [(2) (define alpha-fm (flomap-ref-component fm 0)) + (define value-fm (flomap-drop-components fm 1)) + (flomap-append-components alpha-fm value-fm value-fm value-fm)] + [(3) (flomap-append-components (make-flomap 1 w h 1.0) fm)] + [(4) fm] + [else (raise-type-error 'flomap->bitmap "flomap with 1, 2, 3 or 4 components" fm)])] + ;; inset if zero (bitmaps can't have zero size) + [fm (flomap-inset fm 0 0 (if (= w 0) 1 0) (if (= h 0) 1 0))] + ;; divide alphas before converting + [fm (flomap-divide-alpha fm)]) + ;; guaranteed an ARGB flomap now + (match-define (flomap vs 4 w h) fm) + (define bs (make-bytes (* 4 w h))) + (for ([i0 (in-range 0 (* 4 w h) 4)]) + (define i1 (unsafe-fx+ i0 1)) + (define i2 (unsafe-fx+ i0 2)) + (define i3 (unsafe-fx+ i0 3)) + (define a (unsafe-flvector-ref vs i0)) + (define r (unsafe-flvector-ref vs i1)) + (define g (unsafe-flvector-ref vs i2)) + (define b (unsafe-flvector-ref vs i3)) + (unsafe-bytes-set! bs i0 (unsafe-fl->byte (unsafe-fl* 255.0 a))) + (unsafe-bytes-set! bs i1 (unsafe-fl->byte (unsafe-fl* 255.0 r))) + (unsafe-bytes-set! bs i2 (unsafe-fl->byte (unsafe-fl* 255.0 g))) + (unsafe-bytes-set! bs i3 (unsafe-fl->byte (unsafe-fl* 255.0 b)))) + + (define bm (make-bitmap w h)) + (send bm set-argb-pixels 0 0 w h bs #t) + (send bm set-argb-pixels 0 0 w h bs #f) + bm)) + +(define (draw-flomap w h draw-proc) + (unless (w . >= . 0) (raise-type-error 'draw-flomap "nonnegative fixnum" 0 w h draw-proc)) + (unless (h . >= . 0) (raise-type-error 'draw-flomap "nonnegative fixnum" 1 w h draw-proc)) + + (define bm (make-bitmap (max w 1) (max h 1))) + (define dc (make-object bitmap-dc% bm)) + (send dc set-smoothing 'smoothed) + (draw-proc dc) + (flomap-inset (bitmap->flomap bm) 0 0 (if (= w 0) -1 0) (if (= h 0) -1 0))) diff --git a/collects/images/private/flomap-effects.rkt b/collects/images/private/flomap-effects.rkt new file mode 100644 index 0000000000..d0222bc49b --- /dev/null +++ b/collects/images/private/flomap-effects.rkt @@ -0,0 +1,67 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match racket/list + "flonum.rkt" + "flomap-struct.rkt" + "flomap-pointwise.rkt" + "flomap-blur.rkt" + "flomap-composite.rkt") + +(provide flomap-outline flomap-outlined + flomap-shadow flomap-shadowed) + +(: colorize-alpha (flomap (Listof Real) -> flomap)) +(define (colorize-alpha fm color) + (match-define (flomap _ 1 w h) fm) + (flomap-append-components fm (fm* fm (make-flomap/components w h color)))) + +(: flomap-shadow (case-> (flomap Real -> flomap) + (flomap Real (Option (Listof Real)) -> flomap))) +(define flomap-shadow + (case-lambda + [(fm σ) (flomap-shadow fm σ #f)] + [(fm σ color) + (match-define (flomap _ c w h) fm) + (cond [(c . = . 0) fm] + [else (define alpha-fm (flomap-ref-component fm 0)) + (define color-vs (if (list? color) color (make-list (- c 1) 0.0))) + (colorize-alpha (flomap-blur alpha-fm σ) color-vs)])])) + +(: flomap-shadowed (case-> (flomap Real -> flomap) + (flomap Real (Option (Listof Real)) -> flomap))) +(define flomap-shadowed + (case-lambda + [(fm σ) (flomap-shadowed fm σ #f)] + [(fm σ c) (flomap-cc-superimpose (flomap-shadow fm σ c) fm)])) + +(: flomap-outline (case-> (flomap Real -> flomap) + (flomap Real (Option (Listof Real)) -> flomap))) +(define flomap-outline + (case-lambda + [(fm amt) (flomap-outline fm amt #f)] + [(fm amt color) + (match-define (flomap _ c w h) fm) + (let ([amt (exact->inexact amt)]) + (define σ (* 0.5 (max 1.0 amt))) + (define ceiling-amt (fl->fx (ceiling amt))) + (define test-size (fx* 2 (fx+ 1 ceiling-amt))) + (define test-mid (fxquotient test-size 2)) + (define test-fm (inline-build-flomap 1 test-size test-size + (λ (k x y i) (if (x . fx>= . test-mid) 1.0 0.0)))) + (define blur-fm (flomap-blur test-fm σ)) + (define v-max (flomap-bilinear-ref blur-fm 0 (+ 0.5 (- test-mid amt)) test-mid)) + (define v-min (flomap-bilinear-ref blur-fm 0 (+ 0.5 (- test-mid amt 1)) test-mid)) + (define alpha-fm (flomap-ref-component fm 0)) + (define new-alpha-fm (fmmax 0.0 (fmmin 1.0 (fm/ (fm- (flomap-blur alpha-fm σ) v-min) + (- v-max v-min))))) + (define color-vs (if (list? color) color (make-list (- c 1) 0.0))) + (colorize-alpha new-alpha-fm color-vs))])) + +(: flomap-outlined (case-> (flomap Real -> flomap) + (flomap Real (Option (Listof Real)) -> flomap))) +(define flomap-outlined + (case-lambda + [(fm amt) (flomap-outlined fm amt #f)] + [(fm amt c) (flomap-cc-superimpose (flomap-outline fm amt c) fm)])) diff --git a/collects/images/private/flomap-gradient.rkt b/collects/images/private/flomap-gradient.rkt new file mode 100644 index 0000000000..29986297fc --- /dev/null +++ b/collects/images/private/flomap-gradient.rkt @@ -0,0 +1,74 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match + "flonum.rkt" + "flomap-struct.rkt") + +(provide flomap-gradient-x flomap-gradient-y flomap-gradient flomap-gradient-normal) + +;; =================================================================================================== +;; Derivatives (Schurr operator) + +(: flomap-gradient-x (flomap -> flomap)) +(define (flomap-gradient-x fm) + (match-define (flomap vs c w h) fm) + (define cw (fx* c w)) + (define d20 (fx- 1 cw)) + (define d22 (fx+ cw 1)) + (define w-1 (fx- w 1)) + (define h-1 (fx- h 1)) + (inline-build-flomap + c w h + (λ (_k x y i) + (cond [(and (x . fx> . 0) (x . fx< . w-1) + (y . fx> . 0) (y . fx< . h-1)) + (+ (- (* 0.1875 (unsafe-flvector-ref vs (fx+ i d20))) + (* 0.1875 (unsafe-flvector-ref vs (fx- i d22)))) + (- (* 0.6250 (unsafe-flvector-ref vs (fx+ i 1))) + (* 0.6250 (unsafe-flvector-ref vs (fx- i 1)))) + (- (* 0.1875 (unsafe-flvector-ref vs (fx+ i d22))) + (* 0.1875 (unsafe-flvector-ref vs (fx- i d20)))))] + [else 0.0])))) + +(: flomap-gradient-y (flomap -> flomap)) +(define (flomap-gradient-y fm) + (match-define (flomap vs c w h) fm) + (define cw (fx* c w)) + (define d02 (fx- cw 1)) + (define d22 (fx+ cw 1)) + (define w-1 (fx- w 1)) + (define h-1 (fx- h 1)) + (inline-build-flomap + c w h + (λ (_k x y i) + (cond [(and (x . fx> . 0) (x . fx< . w-1) + (y . fx> . 0) (y . fx< . h-1)) + (+ (- (* 0.1875 (unsafe-flvector-ref vs (fx+ i d02))) + (* 0.1875 (unsafe-flvector-ref vs (fx- i d22)))) + (- (* 0.6250 (unsafe-flvector-ref vs (fx+ i cw))) + (* 0.6250 (unsafe-flvector-ref vs (fx- i cw)))) + (- (* 0.1875 (unsafe-flvector-ref vs (fx+ i d22))) + (* 0.1875 (unsafe-flvector-ref vs (fx- i d02)))))] + [else 0.0])))) + +(: flomap-gradient (flomap -> (values flomap flomap))) +(define (flomap-gradient fm) + (values (flomap-gradient-x fm) (flomap-gradient-y fm))) + +(: flomap-gradient-normal (flomap -> flomap)) +(define (flomap-gradient-normal z-fm) + (define-values (dx-fm dy-fm) (flomap-gradient z-fm)) + (match-define (flomap dx-vs 1 w h) dx-fm) + (match-define (flomap dy-vs 1 _w _h) dy-fm) + (define normal-vs (make-flvector (* 3 w h))) + (for ([i (in-range (* w h))]) + (define dx (unsafe-flvector-ref dx-vs i)) + (define dy (unsafe-flvector-ref dy-vs i)) + (define-values (nx ny nz) (fl3normalize (- dx) (- dy) 2.0)) + (define j (fx* 3 i)) + (unsafe-flvector-set! normal-vs j nx) + (unsafe-flvector-set! normal-vs (fx+ j 1) ny) + (unsafe-flvector-set! normal-vs (fx+ j 2) nz)) + (flomap normal-vs 3 w h)) diff --git a/collects/images/private/flomap-pointwise.rkt b/collects/images/private/flomap-pointwise.rkt new file mode 100644 index 0000000000..ae2eb1513b --- /dev/null +++ b/collects/images/private/flomap-pointwise.rkt @@ -0,0 +1,121 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match racket/math + "flonum.rkt" + "flomap-struct.rkt" + "flomap-stats.rkt") + +(provide flomap-lift flomap-lift2 inline-flomap-lift inline-flomap-lift2 + fmneg fmabs fmsqr fmsin fmcos fmtan fmlog fmexp fmsqrt fmasin fmacos fmatan + fmround fmfloor fmceiling fmtruncate fmzero + fm+ fm- fm* fm/ fmmin fmmax + flomap-normalize flomap-multiply-alpha flomap-divide-alpha) + +;; =================================================================================================== +;; Unary + +(define-syntax-rule (inline-flomap-lift f) + (λ: ([fm : flomap]) + (match-define (flomap vs c w h) fm) + (flomap (inline-build-flvector (* c w h) (λ (i) (f (unsafe-flvector-ref vs i)))) + c w h))) + +(: flomap-lift ((Flonum -> Real) -> (flomap -> flomap))) +(define (flomap-lift op) + (inline-flomap-lift (λ (x) (exact->inexact (op x))))) + +(define fmneg (inline-flomap-lift -)) +(define fmabs (inline-flomap-lift abs)) +(define fmsqr (inline-flomap-lift sqr)) +(define fmsin (inline-flomap-lift sin)) +(define fmcos (inline-flomap-lift cos)) +(define fmtan (inline-flomap-lift tan)) +(define fmlog (inline-flomap-lift fllog)) +(define fmexp (inline-flomap-lift exp)) +(define fmsqrt (inline-flomap-lift flsqrt)) +(define fmasin (inline-flomap-lift asin)) +(define fmacos (inline-flomap-lift acos)) +(define fmatan (inline-flomap-lift atan)) +(define fmround (inline-flomap-lift round)) +(define fmfloor (inline-flomap-lift floor)) +(define fmceiling (inline-flomap-lift ceiling)) +(define fmtruncate (inline-flomap-lift truncate)) +(define fmzero (inline-flomap-lift (λ (x) (if (x . = . 0.0) 1.0 0.0)))) + +;; =================================================================================================== +;; Binary + +(define-syntax-rule (inline-flomap-lift2 name f) + (let: () + (λ: ([fm1 : (U Real flomap)] [fm2 : (U Real flomap)]) + (cond + [(and (real? fm1) (real? fm2)) + (error name "expected at least one flomap argument; given ~e and ~e" fm1 fm2)] + [(real? fm1) (let ([fm1 (exact->inexact fm1)]) + ((inline-flomap-lift (λ (v) (f fm1 v))) fm2))] + [(real? fm2) (let ([fm2 (exact->inexact fm2)]) + ((inline-flomap-lift (λ (v) (f v fm2))) fm1))] + [else + (match-define (flomap vs1 c1 w h) fm1) + (match-define (flomap vs2 c2 w2 h2) fm2) + (cond + [(not (and (= w w2) (= h h2))) + (error name "expected same-size flomaps; given sizes ~e×~e and ~e×~e" w h w2 h2)] + [(= c1 c2) (define n (* c1 w h)) + (define res-vs (make-flvector n)) + (flomap (inline-build-flvector n (λ (i) (f (unsafe-flvector-ref vs1 i) + (unsafe-flvector-ref vs2 i)))) + c1 w h)] + [(= c1 1) (inline-build-flomap + c2 w h + (λ (k x y i) (f (unsafe-flvector-ref vs1 (coords->index 1 w 0 x y)) + (unsafe-flvector-ref vs2 i))))] + [(= c2 1) (inline-build-flomap + c1 w h + (λ (k x y i) (f (unsafe-flvector-ref vs1 i) + (unsafe-flvector-ref vs2 (coords->index 1 w 0 x y)))))] + [else + (error name (string-append "expected flomaps with the same number of components, " + "or a flomap with 1 component and any same-size flomap; " + "given flomaps with ~e and ~e components") + c1 c2)])])))) + +(: flomap-lift2 (Symbol (Flonum Flonum -> Real) -> ((U Real flomap) (U Real flomap) -> flomap))) +(define (flomap-lift2 name f) + (inline-flomap-lift2 name (λ (x y) (exact->inexact (f x y))))) + +(define fm+ (inline-flomap-lift2 'fm+ +)) +(define fm- (inline-flomap-lift2 'fm- -)) +(define fm* (inline-flomap-lift2 'fm* *)) +(define fm/ (inline-flomap-lift2 'fm/ /)) +(define fmmin (inline-flomap-lift2 'fmmin min)) +(define fmmax (inline-flomap-lift2 'fmmax max)) + +(: flomap-normalize (flomap -> flomap)) +(define (flomap-normalize fm) + (define-values (v-min v-max) (flomap-extreme-values fm)) + (define v-size (- v-max v-min)) + (let* ([fm (fm- fm v-min)] + [fm (if (v-size . = . 0.0) fm (fm/ fm v-size))]) + fm)) + +(define fmdiv/zero + (inline-flomap-lift2 'fmdiv/zero (λ (x y) (if (y . = . 0.0) 0.0 (/ x y))))) + +(: flomap-divide-alpha (flomap -> flomap)) +(define (flomap-divide-alpha fm) + (match-define (flomap _ c w h) fm) + (cond [(c . <= . 1) fm] + [else + (define alpha-fm (flomap-ref-component fm 0)) + (flomap-append-components alpha-fm (fmdiv/zero (flomap-drop-components fm 1) alpha-fm))])) + +(: flomap-multiply-alpha (flomap -> flomap)) +(define (flomap-multiply-alpha fm) + (match-define (flomap _ c w h) fm) + (cond [(c . > . 1) + (define alpha-fm (flomap-ref-component fm 0)) + (flomap-append-components alpha-fm (fm* (flomap-drop-components fm 1) alpha-fm))] + [else fm])) diff --git a/collects/images/private/flomap-resize.rkt b/collects/images/private/flomap-resize.rkt new file mode 100644 index 0000000000..84969621e1 --- /dev/null +++ b/collects/images/private/flomap-resize.rkt @@ -0,0 +1,221 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match racket/math + "flonum.rkt" + "flomap-struct.rkt" + "flomap-stats.rkt" + "flomap-blur.rkt") + +(provide flomap-inset flomap-trim flomap-crop + flomap-lt-crop flomap-lc-crop flomap-lb-crop + flomap-ct-crop flomap-cc-crop flomap-cb-crop + flomap-rt-crop flomap-rc-crop flomap-rb-crop + flomap-scale flomap-resize) + +(: flomap-inset (case-> (flomap Integer -> flomap) + (flomap Integer Integer -> flomap) + (flomap Integer Integer Integer Integer -> flomap))) +(define flomap-inset + (case-lambda + [(fm amt) (flomap-inset fm amt amt amt amt)] + [(fm h-amt v-amt) (flomap-inset fm h-amt v-amt h-amt v-amt)] + [(fm l-amt t-amt r-amt b-amt) + (cond [(and (= l-amt 0) (= t-amt 0) (= r-amt 0) (= b-amt 0)) fm] + [else + (match-define (flomap src-vs c src-w src-h) fm) + (define dst-w (fxmax 0 (fx+ src-w (fx+ l-amt r-amt)))) + (define dst-h (fxmax 0 (fx+ src-h (fx+ t-amt b-amt)))) + (define dst-vs (make-flvector (* c dst-w dst-h))) + (cond + [(or (dst-w . fx= . 0) (dst-h . fx= . 0)) + (flomap dst-vs c dst-w dst-h)] + [else + (let: y-loop : Void ([dst-y : Nonnegative-Fixnum 0]) + (when (dst-y . fx< . dst-h) + (define src-y (fx- dst-y t-amt)) + (when (and (src-y . fx>= . 0) (src-y . fx< . src-h)) + (let: x-loop : Void ([dst-x : Nonnegative-Fixnum 0]) + (when (dst-x . fx< . dst-w) + (define src-x (fx- dst-x l-amt)) + (when (and (src-x . fx>= . 0) (src-x . fx< . src-w)) + (let: k-loop : Void ([k : Nonnegative-Fixnum 0]) + (when (k . fx< . c) + (define src-i (coords->index c src-w k src-x src-y)) + (define dst-i (coords->index c dst-w k dst-x dst-y)) + (unsafe-flvector-set! dst-vs dst-i (unsafe-flvector-ref src-vs src-i)) + (k-loop (fx+ k 1))))) + (x-loop (fx+ dst-x 1))))) + (y-loop (fx+ dst-y 1)))) + (flomap dst-vs c dst-w dst-h)])])])) + +(: flomap-trim (flomap -> flomap)) +(define (flomap-trim fm) + (match-define (flomap _ c w h) fm) + (cond [(c . = . 0) (make-flomap 0 0 0)] + [else (define-values (_k-min x-min y-min _k-max x-max y-max) + (flomap-nonzero-rect (flomap-ref-component fm 0))) + (flomap-inset fm (- x-min) (- y-min) (- x-max w) (- y-max h))])) + +(: flomap-crop (flomap Integer Integer Real Real -> flomap)) +(define (flomap-crop fm width height x-frac y-frac) + (unless (width . >= . 0) + (raise-type-error 'flomap-crop "nonnegative integer" 1 fm width height x-frac y-frac)) + (unless (height . >= . 0) + (raise-type-error 'flomap-crop "nonnegative integer" 2 fm width height x-frac y-frac)) + (let ([x-frac (exact->inexact x-frac)] + [y-frac (exact->inexact y-frac)]) + (match-define (flomap _ c w h) fm) + (define l-amt (fl->fx (round (* x-frac (fx->fl (fx- width w)))))) + (define r-amt (fx- (fx- width w) l-amt)) + (define t-amt (fl->fx (round (* y-frac (fx->fl (fx- height h)))))) + (define b-amt (fx- (fx- height h) t-amt)) + (flomap-inset fm l-amt t-amt r-amt b-amt))) + +(: flomap-lt-crop (flomap Integer Integer -> flomap)) +(: flomap-lc-crop (flomap Integer Integer -> flomap)) +(: flomap-lb-crop (flomap Integer Integer -> flomap)) +(: flomap-ct-crop (flomap Integer Integer -> flomap)) +(: flomap-cc-crop (flomap Integer Integer -> flomap)) +(: flomap-cb-crop (flomap Integer Integer -> flomap)) +(: flomap-rt-crop (flomap Integer Integer -> flomap)) +(: flomap-rc-crop (flomap Integer Integer -> flomap)) +(: flomap-rb-crop (flomap Integer Integer -> flomap)) + +(define (flomap-lt-crop fm w h) (flomap-crop fm w h 0 0)) +(define (flomap-lc-crop fm w h) (flomap-crop fm w h 0 1/2)) +(define (flomap-lb-crop fm w h) (flomap-crop fm w h 0 1)) +(define (flomap-ct-crop fm w h) (flomap-crop fm w h 1/2 0)) +(define (flomap-cc-crop fm w h) (flomap-crop fm w h 1/2 1/2)) +(define (flomap-cb-crop fm w h) (flomap-crop fm w h 1/2 1)) +(define (flomap-rt-crop fm w h) (flomap-crop fm w h 1 0)) +(define (flomap-rc-crop fm w h) (flomap-crop fm w h 1 1/2)) +(define (flomap-rb-crop fm w h) (flomap-crop fm w h 1 1)) + +(: flomap-scale (case-> (flomap Real -> flomap) + (flomap Real Real -> flomap))) +(define flomap-scale + (case-lambda + [(fm scale) + (cond [(< scale 0) (raise-type-error 'flomap-scale "nonnegative real" 1 fm scale)] + [else (flomap-scale fm scale scale)])] + [(fm x-scale y-scale) + (cond [(< x-scale 0) (raise-type-error 'flomap-scale "nonnegative real" 1 fm x-scale y-scale)] + [(< y-scale 0) (raise-type-error 'flomap-scale "nonnegative real" 2 fm x-scale y-scale)] + [else (flomap-scale-x (flomap-scale-y fm (exact->inexact y-scale)) + (exact->inexact x-scale))])])) + +(: flomap-resize (flomap (Option Integer) (Option Integer) -> flomap)) +(define (flomap-resize fm width height) + (when (and width (width . < . 0)) + (raise-type-error 'flomap-resize "nonnegative integer" 1 fm width height)) + (when (and height (height . < . 0)) + (raise-type-error 'flomap-resize "nonnegative integer" 2 fm width height)) + (match-define (flomap _ c w h) fm) + (cond [(and width height) (flomap-resize-x (flomap-resize-y fm height) width)] + [width (cond [(= w 0) (error 'flomap-resize + "cannot proportionally scale ~e×~e flomap's height" + w h)] + [else (define s (exact->inexact (/ width w))) + (flomap-resize-x (flomap-scale-y fm s) width)])] + [height (cond [(= h 0) (error 'flomap-resize + "cannot proportionally scale ~e×~e flomap's width" + w h)] + [else (define s (exact->inexact (/ height h))) + (flomap-scale-x (flomap-resize-y fm height) s)])] + [else (error 'flomap-resize "can't happen")])) + +(: flomap-scale-x (flomap Flonum -> flomap)) +(define (flomap-scale-x fm scale) + (match-define (flomap _ c w h) fm) + (cond [(= 0 scale) (make-flomap c 0 h)] + [else (let ([scale (abs scale)]) + (flomap-scale*-x fm scale (abs (fl->fx (ceiling (* (exact->inexact w) scale))))))])) + +(: flomap-scale-y (flomap Flonum -> flomap)) +(define (flomap-scale-y fm scale) + (match-define (flomap _ c w h) fm) + (cond [(= 0 scale) (make-flomap c w 0)] + [else (let ([scale (abs scale)]) + (flomap-scale*-y fm scale (abs (fl->fx (ceiling (* (exact->inexact h) scale))))))])) + +(: flomap-resize-x (flomap Integer -> flomap)) +(define (flomap-resize-x fm width) + (match-define (flomap _ c w h) fm) + (cond [(= 0 width) (make-flomap c 0 h)] + [else (let ([width (abs width)]) + (flomap-scale*-x fm (abs (exact->inexact (/ width w))) width))])) + +(: flomap-resize-y (flomap Integer -> flomap)) +(define (flomap-resize-y fm height) + (match-define (flomap _ c w h) fm) + (cond [(= 0 height) (make-flomap c w 0)] + [else (let ([height (abs height)]) + (flomap-scale*-y fm (abs (exact->inexact (/ height h))) height))])) + +;; standard deviation of an unscaled box filter (i.e. f([-1/2,1/2]) = {1}, zero elsewhere) +(define box-filter-variance (/ 1.0 12.0)) +;; standard deviation of an unscaled triangle filter (simulates effect of linear interpolation) +(define triangle-filter-variance (/ 1.0 24.0)) + +;; calculates the standard deviation of downscaling blur, assuming linear interpolation will be +;; carried out on the blurred image +(: stddev-for-scale (Nonnegative-Flonum -> Nonnegative-Flonum)) +(define (stddev-for-scale scale) + (define var (- (/ box-filter-variance (sqr scale)) + triangle-filter-variance)) + (abs (flsqrt (max 0.0 var)))) + +(: flomap-scale*-x (flomap Nonnegative-Flonum Exact-Nonnegative-Integer -> flomap)) +(define (flomap-scale*-x fm scale width) + (cond [(scale . = . 1.0) fm] + [(scale . > . 1.0) (flomap-scale*-x/linear fm scale width)] + [else (define low-res-fm + (flomap-gaussian-blur-x fm (stddev-for-scale scale))) + (flomap-scale*-x/linear low-res-fm scale width)])) + +(: flomap-scale*-y (flomap Nonnegative-Flonum Exact-Nonnegative-Integer -> flomap)) +(define (flomap-scale*-y fm scale height) + (cond [(scale . = . 1.0) fm] + [(scale . > . 1.0) (flomap-scale*-y/linear fm scale height)] + [else (define low-res-fm + (flomap-gaussian-blur-y fm (stddev-for-scale scale))) + (flomap-scale*-y/linear low-res-fm scale height)])) + +(: flomap-scale*-x/linear (flomap Nonnegative-Flonum Exact-Nonnegative-Integer -> flomap)) +(define (flomap-scale*-x/linear fm s new-w) + (match-define (flomap vs c w h) fm) + (define w-1 (fx- w 1)) + (inline-build-flomap + c new-w h + (λ (k new-x y _i) + (define scaled-x (- (/ (+ (fx->fl new-x) 0.5) s) 0.5)) + (define floor-scaled-x (floor scaled-x)) + (define x0 (fl->fx floor-scaled-x)) + (cond [(or (x0 . fx< . 0) (x0 . fx>= . w)) 0.0] + [else + (define i0 (coords->index c w k x0 y)) + (define v0 (unsafe-flvector-ref vs i0)) + (define v1 (cond [(x0 . fx= . w-1) 0.0] + [else (unsafe-flvector-ref vs (fx+ i0 c))])) + (fl-convex-combination v0 v1 (- scaled-x floor-scaled-x))])))) + +(: flomap-scale*-y/linear (flomap Nonnegative-Flonum Exact-Nonnegative-Integer -> flomap)) +(define (flomap-scale*-y/linear fm s new-h) + (match-define (flomap vs c w h) fm) + (define h-1 (fx- h 1)) + (define cw (* c w)) + (inline-build-flomap + c w new-h + (λ (k x new-y _i) + (define scaled-y (- (/ (+ (fx->fl new-y) 0.5) s) 0.5)) + (define floor-scaled-y (floor scaled-y)) + (define y0 (fl->fx floor-scaled-y)) + (cond [(or (y0 . fx< . 0) (y0 . fx>= . h)) 0.0] + [else + (define i0 (coords->index c w k x y0)) + (define v0 (unsafe-flvector-ref vs i0)) + (define v1 (cond [(y0 . fx= . h-1) 0.0] + [else (unsafe-flvector-ref vs (fx+ i0 cw))])) + (fl-convex-combination v0 v1 (- scaled-y floor-scaled-y))])))) diff --git a/collects/images/private/flomap-stats.rkt b/collects/images/private/flomap-stats.rkt new file mode 100644 index 0000000000..3a8edeb96a --- /dev/null +++ b/collects/images/private/flomap-stats.rkt @@ -0,0 +1,55 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match + "flonum.rkt" + "flomap-struct.rkt") + +(provide flomap-min-value flomap-max-value flomap-extreme-values + flomap-nonzero-rect) + +(: flomap-min-value (flomap -> Flonum)) +(define (flomap-min-value fm) + (for/fold ([v-min +inf.0]) ([v (in-flvector (flomap-values fm))]) + (min v-min v))) + +(: flomap-max-value (flomap -> Flonum)) +(define (flomap-max-value fm) + (for/fold ([v-max -inf.0]) ([v (in-flvector (flomap-values fm))]) + (max v-max v))) + +(: flomap-extreme-values (flomap -> (values Flonum Flonum))) +(define (flomap-extreme-values fm) + (for/fold: ([v-min : Flonum +inf.0] [v-max : Flonum -inf.0] + ) ([v : Flonum (in-flvector (flomap-values fm))]) + (values (min v-min v) (max v-max v)))) + +(: flomap-nonzero-rect (flomap -> (values Nonnegative-Fixnum Nonnegative-Fixnum Nonnegative-Fixnum + Nonnegative-Fixnum Nonnegative-Fixnum Nonnegative-Fixnum))) +(define (flomap-nonzero-rect fm) + (match-define (flomap vs c w h) fm) + (with-asserts ([c nonnegative-fixnum?] [w nonnegative-fixnum?] [h nonnegative-fixnum?]) + (define: k-min : Nonnegative-Fixnum c) + (define: x-min : Nonnegative-Fixnum w) + (define: y-min : Nonnegative-Fixnum h) + (define: k-max : Nonnegative-Fixnum 0) + (define: x-max : Nonnegative-Fixnum 0) + (define: y-max : Nonnegative-Fixnum 0) + (let: y-loop : Void ([y : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum 0]) + (when (y . fx< . h) + (let: x-loop : Void ([x : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum i]) + (cond [(x . fx< . w) + (let: k-loop : Void ([k : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum i]) + (cond [(k . fx< . c) (define v (unsafe-flvector-ref vs i)) + (when (not (v . = . 0.0)) + (set! k-min (fxmin k-min k)) + (set! x-min (fxmin x-min x)) + (set! y-min (fxmin y-min y)) + (set! k-max (fxmax k-max (fx+ 1 k))) + (set! x-max (fxmax x-max (fx+ 1 x))) + (set! y-max (fxmax y-max (fx+ 1 y)))) + (k-loop (fx+ k 1) (fx+ i 1))] + [else (x-loop (fx+ x 1) i)]))] + [else (y-loop (fx+ y 1) i)])))) + (values k-min x-min y-min k-max x-max y-max))) diff --git a/collects/images/private/flomap-struct.rkt b/collects/images/private/flomap-struct.rkt new file mode 100644 index 0000000000..8d38544f24 --- /dev/null +++ b/collects/images/private/flomap-struct.rkt @@ -0,0 +1,160 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match + (except-in racket/unsafe/ops unsafe-flvector-ref unsafe-flvector-set!) + "flonum.rkt") + +(provide flomap flomap? flomap-values flomap-components flomap-width flomap-height + ;; Accessors + flomap-size flomap-ref flomap-bilinear-ref coords->index + ;; Basic constructors + make-flomap make-flomap/components build-flomap inline-build-flomap + flomap-ref-component flomap-take-components flomap-drop-components flomap-append-components) + +(struct: flomap ([values : FlVector] [components : Integer] [width : Integer] [height : Integer]) + #:transparent + #:guard + (λ (vs c w h name) + (with-asserts ([c nonnegative-fixnum?] [w nonnegative-fixnum?] [h nonnegative-fixnum?]) + (unless (= (flvector-length vs) (* c w h)) + (error 'flomap "expected flvector of length ~e; given one of length ~e" + (* c w h) (flvector-length vs))) + (values vs c w h)))) + +(: flomap-size (flomap -> (values Nonnegative-Fixnum Nonnegative-Fixnum))) +(define (flomap-size fm) + (match-define (flomap _vs _c w h) fm) + (with-asserts ([w nonnegative-fixnum?] [h nonnegative-fixnum?]) + (values w h))) + +#;;(: coords->index (Integer Integer Integer Integer Integer -> Fixnum)) +(define (coords->index c w k x y) + (fx+ k (fx* c (fx+ x (fx* y w))))) + +(define-syntax-rule (coords->index c w k x y) + (fx+ k (fx* c (fx+ x (fx* y w))))) + +(: unsafe-flomap-ref (FlVector Integer Integer Integer Integer Integer Integer -> Flonum)) +(define (unsafe-flomap-ref vs c w h k x y) + (cond [(and (x . fx>= . 0) (x . fx< . w) + (y . fx>= . 0) (y . fx< . h)) + (unsafe-flvector-ref vs (coords->index c w k x y))] + [else 0.0])) + +(: flomap-ref (flomap Integer Integer Integer -> Flonum)) +(define (flomap-ref fm k x y) + (match-define (flomap vs c w h) fm) + (unless (and (k . >= . 0) (k . < . c)) + (raise-type-error 'flomap-ref (format "nonnegative fixnum < ~e" c) k)) + (unsafe-flomap-ref vs c w h k x y)) + +(: flomap-bilinear-ref (flomap Integer Real Real -> Flonum)) +(define (flomap-bilinear-ref fm k x y) + (match-define (flomap vs c w h) fm) + (unless (and (k . >= . 0) (k . < . c)) + (raise-type-error 'flomap-bilinear-ref (format "nonnegative fixnum < ~e" c) k)) + (let ([x (- (exact->inexact x) 0.5)] + [y (- (exact->inexact y) 0.5)]) + (define floor-x (floor x)) + (define floor-y (floor y)) + (define x0 (fl->fx floor-x)) + (define y0 (fl->fx floor-y)) + (define x1 (fx+ x0 1)) + (define y1 (fx+ y0 1)) + (define v00 (unsafe-flomap-ref vs c w h k x0 y0)) + (define v10 (unsafe-flomap-ref vs c w h k x1 y0)) + (define v01 (unsafe-flomap-ref vs c w h k x0 y1)) + (define v11 (unsafe-flomap-ref vs c w h k x1 y1)) + (define xα (- x floor-x)) + (fl-convex-combination (fl-convex-combination v00 v10 xα) + (fl-convex-combination v01 v11 xα) + (- y floor-y)))) + +;; =================================================================================================== +;; Construction and conversion + +(: make-flomap (case-> (Integer Integer Integer -> flomap) + (Integer Integer Integer Real -> flomap))) +(define make-flomap + (case-lambda + [(c w h) (flomap (make-flvector (* c w h)) c w h)] + [(c w h v) (flomap (make-flvector (* c w h) (exact->inexact v)) c w h)])) + +(define-syntax-rule (inline-build-flomap components width height f) + (let: ([c : Integer components] + [w : Integer width] + [h : Integer height]) + (with-asserts ([c nonnegative-fixnum?] [w nonnegative-fixnum?] [h nonnegative-fixnum?]) + (define vs (make-flvector (* c w h))) + (let: y-loop : flomap ([y : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum 0]) + (cond + [(y . fx< . h) + (let: x-loop : flomap ([x : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum i]) + (cond + [(x . fx< . w) + (let: k-loop : flomap ([k : Nonnegative-Fixnum 0] [i : Nonnegative-Fixnum i]) + (cond + [(k . fx< . c) (unsafe-flvector-set! vs i (f k x y i)) + (k-loop (unsafe-fx+ k 1) (unsafe-fx+ i 1))] + [else (x-loop (unsafe-fx+ x 1) i)]))] + [else (y-loop (unsafe-fx+ y 1) i)]))] + [else (flomap vs c w h)]))))) + +(: build-flomap (Integer Integer Integer + (Nonnegative-Fixnum Nonnegative-Fixnum Nonnegative-Fixnum + Nonnegative-Fixnum -> Real) + -> flomap)) +(define (build-flomap components width height fun) + (inline-build-flomap components width height (λ (k x y i) (exact->inexact (fun k x y i))))) + +(: make-flomap/components (Integer Integer (Listof Real) -> flomap)) +(define (make-flomap/components w h vs) + (let ([vs (apply flvector (map exact->inexact vs))]) + (define c (flvector-length vs)) + (inline-build-flomap c w h (λ (k _x _y _i) (unsafe-flvector-ref vs k))))) + +(: flomap-ref-component (flomap Integer -> flomap)) +(define (flomap-ref-component fm k) + (match-define (flomap vs c w h) fm) + (unless (and (k . >= . 0) (k . < . c)) + (raise-type-error 'flomap-ref-components (format "nonnegative fixnum < ~e" c) k)) + (inline-build-flomap 1 w h (λ (_k x y _i) (unsafe-flvector-ref vs (coords->index c w k x y))))) + +(: flomap-take-components (flomap Integer -> flomap)) +(define (flomap-take-components fm c) + (match-define (flomap vs old-c w h) fm) + (unless (and (c . >= . 0) (c . <= . old-c)) + (raise-type-error 'flomap-take-components (format "nonnegative fixnum <= ~e" old-c) c)) + (inline-build-flomap c w h (λ (k x y _i) (unsafe-flvector-ref vs (coords->index old-c w k x y))))) + +(: flomap-drop-components (flomap Integer -> flomap)) +(define (flomap-drop-components fm c) + (match-define (flomap vs old-c w h) fm) + (unless (and (c . >= . 0) (c . <= . old-c)) + (raise-type-error 'flomap-drop-components (format "nonnegative fixnum <= ~e" old-c) c)) + (define new-c (fx- old-c c)) + (with-asserts + ([new-c nonnegative-fixnum?]) + (inline-build-flomap new-c w h (λ (k x y _i) + (unsafe-flvector-ref vs (coords->index old-c w (fx+ k c) x y)))))) + +(: flomap-append-components2 (flomap flomap -> flomap)) +(define (flomap-append-components2 fm1 fm2) + (match-define (flomap vs1 d1 w1 h1) fm1) + (match-define (flomap vs2 d2 w2 h2) fm2) + (unless (and (= w1 w2) (= h1 h2)) + (error 'flomap-append-components + "expected flomaps with equal dimension; given dimensions ~e×~e and ~e×~e" + w1 h1 w2 h2)) + (inline-build-flomap (fx+ d1 d2) w1 h1 + (λ (k x y _i) + (define k2 (fx- k d1)) + (cond [(k2 . fx< . 0) (unsafe-flvector-ref vs1 (coords->index d1 w1 k x y))] + [else (unsafe-flvector-ref vs2 (coords->index d2 w2 k2 x y))])))) + +(: flomap-append-components (flomap flomap * -> flomap)) +(define (flomap-append-components fm . fms) + (for/fold ([fm1 fm]) ([fm2 (in-list fms)]) + (flomap-append-components2 fm1 fm2))) diff --git a/collects/images/private/flomap-transform.rkt b/collects/images/private/flomap-transform.rkt new file mode 100644 index 0000000000..f9d3860a25 --- /dev/null +++ b/collects/images/private/flomap-transform.rkt @@ -0,0 +1,40 @@ +#lang typed/racket/base + +(require racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/match + "flonum.rkt" + "flomap-struct.rkt") + +(provide flomap-flip-horizontal flomap-flip-vertical flomap-transpose + flomap-cw-rotate flomap-ccw-rotate) + +(: flomap-flip-horizontal (flomap -> flomap)) +(define (flomap-flip-horizontal fm) + (match-define (flomap vs c w h) fm) + (define w-1 (fx- w 1)) + (inline-build-flomap c w h (λ (k x y _i) + (unsafe-flvector-ref vs (coords->index c w k (fx- w-1 x) y))))) + +(define (flomap-flip-vertical fm) + (match-define (flomap vs c w h) fm) + (define h-1 (fx- h 1)) + (inline-build-flomap c w h (λ (k x y _i) + (unsafe-flvector-ref vs (coords->index c w k x (fx- h-1 y)))))) + +(define (flomap-transpose fm) + (match-define (flomap vs c w h) fm) + (inline-build-flomap c h w (λ (k x y _i) + (unsafe-flvector-ref vs (coords->index c w k y x))))) + +(define (flomap-cw-rotate fm) + (match-define (flomap vs c w h) fm) + (define h-1 (fx- h 1)) + (inline-build-flomap c h w (λ (k x y _i) + (unsafe-flvector-ref vs (coords->index c w k (fx- h-1 y) x))))) + +(define (flomap-ccw-rotate fm) + (match-define (flomap vs c w h) fm) + (define w-1 (fx- w 1)) + (inline-build-flomap c h w (λ (k x y _i) + (unsafe-flvector-ref vs (coords->index c w k y (fx- w-1 x)))))) diff --git a/collects/images/private/flomap.rkt b/collects/images/private/flomap.rkt index fb986fcfa3..122230a9e5 100644 --- a/collects/images/private/flomap.rkt +++ b/collects/images/private/flomap.rkt @@ -1,1147 +1,34 @@ -#lang racket/base - -(require racket/flonum racket/math racket/list racket/match racket/contract racket/class racket/draw - "unsafe.rkt") - -(provide - (contract-out - ;; Contracts - [fx>=/c (fixnum? . -> . contract?)] - ;; Data types - [struct flomap ([values flvector?] - [components (fx>=/c 0)] - [width (fx>=/c 0)] - [height (fx>=/c 0)])] - [flomap-size (flomap? . -> . (values (fx>=/c 0) (fx>=/c 0)))] - [flomap-ref (flomap? (fx>=/c 0) fixnum? fixnum? . -> . flonum?)] - [flomap-bilinear-ref (flomap? (fx>=/c 0) real? real? . -> . flonum?)] - ;; Construction and conversion - [make-flomap (((fx>=/c 0) (fx>=/c 0) (fx>=/c 0)) (real?) . ->* . flomap?)] - [build-flomap ((fx>=/c 0) (fx>=/c 0) (fx>=/c 0) - ((fx>=/c 0) (fx>=/c 0) (fx>=/c 0) . -> . real?) - . -> . flomap?)] - [make-flomap/components ((fx>=/c 0) (fx>=/c 0) (listof real?) . -> . flomap?)] - [flomap-ref-component (flomap? (fx>=/c 0) . -> . flomap?)] - [flomap-take-components (flomap? (fx>=/c 0) . -> . flomap?)] - [flomap-drop-components (flomap? (fx>=/c 0) . -> . flomap?)] - [flomap-append-components ((flomap?) #:rest (listof flomap?) . ->* . flomap?)] - [flomap-multiply-alpha (flomap? . -> . flomap?)] - [flomap-divide-alpha (flomap? . -> . flomap?)] - [bitmap->flomap ((is-a?/c bitmap%) . -> . flomap?)] - [flomap->bitmap (flomap? . -> . (is-a?/c bitmap%))] - [draw-flomap ((fx>=/c 0) (fx>=/c 0) ((is-a?/c bitmap-dc%) . -> . any/c) . -> . flomap?)] - ;; Pointwise unary operations - [flomap-lift ((flonum? . -> . real?) . -> . (flomap? . -> . flomap?))] - [fmneg (flomap? . -> . flomap?)] - [fmabs (flomap? . -> . flomap?)] - [fmsqr (flomap? . -> . flomap?)] - [fmsin (flomap? . -> . flomap?)] - [fmcos (flomap? . -> . flomap?)] - [fmtan (flomap? . -> . flomap?)] - [fmlog (flomap? . -> . flomap?)] - [fmexp (flomap? . -> . flomap?)] - [fmsqrt (flomap? . -> . flomap?)] - [fmasin (flomap? . -> . flomap?)] - [fmacos (flomap? . -> . flomap?)] - [fmatan (flomap? . -> . flomap?)] - [fmround (flomap? . -> . flomap?)] - [fmfloor (flomap? . -> . flomap?)] - [fmceiling (flomap? . -> . flomap?)] - [fmtruncate (flomap? . -> . flomap?)] - [flomap-normalize (flomap? . -> . flomap?)] - ;; Pointwise binary operations - [flomap-lift2 (symbol? (flonum? flonum? . -> . real?) - . -> . ((or/c flomap? real?) (or/c flomap? real?) . -> . flomap?))] - [fm+ ((or/c flomap? real?) (or/c flomap? real?) . -> . flomap?)] - [fm- ((or/c flomap? real?) (or/c flomap? real?) . -> . flomap?)] - [fm* ((or/c flomap? real?) (or/c flomap? real?) . -> . flomap?)] - [fm/ ((or/c flomap? real?) (or/c flomap? real?) . -> . flomap?)] - [fmmin ((or/c flomap? real?) (or/c flomap? real?) . -> . flomap?)] - [fmmax ((or/c flomap? real?) (or/c flomap? real?) . -> . flomap?)] - ;; Blur - [flomap-gaussian-blur ((flomap? real?) (real? real? real?) . ->* . flomap?)] - [flomap-box-blur ((flomap? real?) (real?) . ->* . flomap?)] - [flomap-blur ((flomap? real?) (real?) . ->* . flomap?)] - ;[flomap-integral (flomap? . -> . flomap?)] - ;; Derivatives - [flomap-gradient-x (flomap? . -> . flomap?)] - [flomap-gradient-y (flomap? . -> . flomap?)] - [flomap-gradient (flomap? . -> . (values flomap? flomap?))] - [flomap-gradient-normal (flomap? . -> . flomap?)] - ;; Statistics - [flomap-extreme-values (flomap? . -> . (values flonum? flonum?))] - [flomap-min-value (flomap? . -> . flonum?)] - [flomap-max-value (flomap? . -> . flonum?)] - [flomap-nonzero-rect (flomap? . -> . (values (fx>=/c 0) (fx>=/c 0) (fx>=/c 0) - (fx>=/c 0) (fx>=/c 0) (fx>=/c 0)))] - ;; Sizing - [flomap-inset (case-> (flomap? fixnum? . -> . flomap?) - (flomap? fixnum? fixnum? . -> . flomap?) - (flomap? fixnum? fixnum? fixnum? fixnum? . -> . flomap?))] - [flomap-trim (flomap? . -> . flomap?)] - [flomap-crop (flomap? (fx>=/c 0) (fx>=/c 0) real? real? . -> . flomap?)] - [flomap-lt-crop (flomap? (fx>=/c 0) (fx>=/c 0) . -> . flomap?)] - [flomap-lc-crop (flomap? (fx>=/c 0) (fx>=/c 0) . -> . flomap?)] - [flomap-lb-crop (flomap? (fx>=/c 0) (fx>=/c 0) . -> . flomap?)] - [flomap-ct-crop (flomap? (fx>=/c 0) (fx>=/c 0) . -> . flomap?)] - [flomap-cc-crop (flomap? (fx>=/c 0) (fx>=/c 0) . -> . flomap?)] - [flomap-cb-crop (flomap? (fx>=/c 0) (fx>=/c 0) . -> . flomap?)] - [flomap-rt-crop (flomap? (fx>=/c 0) (fx>=/c 0) . -> . flomap?)] - [flomap-rc-crop (flomap? (fx>=/c 0) (fx>=/c 0) . -> . flomap?)] - [flomap-rb-crop (flomap? (fx>=/c 0) (fx>=/c 0) . -> . flomap?)] - [flomap-scale (case-> (flomap? (>=/c 0.0) . -> . flomap?) - (flomap? (>=/c 0.0) (>=/c 0.0) . -> . flomap?))] - [flomap-resize (flomap? (or/c (fx>=/c 0) #f) (or/c (fx>=/c 0) #f) . -> . flomap?)] - ;; Transforms - [flomap-flip-horizontal (flomap? . -> . flomap?)] - [flomap-flip-vertical (flomap? . -> . flomap?)] - [flomap-transpose (flomap? . -> . flomap?)] - [flomap-cw-rotate (flomap? . -> . flomap?)] - [flomap-ccw-rotate (flomap? . -> . flomap?)] - ;; Compositing - [flomap-pin (flomap? real? real? flomap? real? real? . -> . flomap?)] - [flomap-pin* ([real? real? real? real? flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-lt-superimpose ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-lc-superimpose ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-lb-superimpose ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-ct-superimpose ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-cc-superimpose ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-cb-superimpose ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-rt-superimpose ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-rc-superimpose ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-rb-superimpose ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-vl-append ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-vc-append ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-vr-append ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-ht-append ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-hc-append ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - [flomap-hb-append ([flomap?] #:rest (listof flomap?) . ->* . flomap?)] - ;; Effects - [flomap-outline ([flomap? real?] [#:color (or/c #f (listof real?))] . ->* . flomap?)] - [flomap-outlined ([flomap? real?] [#:color (or/c #f (listof real?))] . ->* . flomap?)] - [flomap-shadow ([flomap? real?] [#:color (or/c #f (listof real?))] . ->* . flomap?)] - [flomap-shadowed ([flomap? real?] [#:color (or/c #f (listof real?))] . ->* . flomap?)] - ) - unsafe-build-flomap - flomap-lift/unsafe - flomap-lift2/unsafe) - -(struct flomap (values components width height) - #:transparent - #:guard (λ (vs c w h name) - (unless (= (flvector-length vs) (* c w h)) - (error 'flomap "expected flvector of length ~e; given one of length ~e" - (* c w h) (flvector-length vs))) - (values vs c w h))) - -(define (fx>=/c n) (and/c fixnum? (>=/c n))) - -(define (flomap-size fm) - (match-define (flomap _vs _c w h) fm) - (values w h)) - -(define-syntax-rule (unsafe-coords->index c w k x y) - (unsafe-fx+ k (unsafe-fx* c (unsafe-fx+ x (unsafe-fx* y w))))) - -(define (flomap-ref* vs c w h k x y) - (cond [(and (x . unsafe-fx>= . 0) (x . unsafe-fx< . w) - (y . unsafe-fx>= . 0) (y . unsafe-fx< . h)) - (unsafe-flvector-ref vs (unsafe-coords->index c w k x y))] - [else 0.0])) - -(define (flomap-ref fm k x y) - (match-define (flomap vs c w h) fm) - (unless (k . < . c) - (raise-type-error 'flomap-ref (format "nonnegative fixnum < ~e" c) k)) - (flomap-ref* vs c w h k x y)) - -(define (flomap-bilinear-ref fm k x y) - (match-define (flomap vs c w h) fm) - (unless (k . < . c) - (raise-type-error 'flomap-bilinear-ref (format "nonnegative fixnum < ~e" c) k)) - (let ([x (unsafe-fl- (exact->inexact x) 0.5)] - [y (unsafe-fl- (exact->inexact y) 0.5)]) - (define floor-x (unsafe-flfloor x)) - (define floor-y (unsafe-flfloor y)) - (define x0 (unsafe-fl->fx floor-x)) - (define y0 (unsafe-fl->fx floor-y)) - (define x1 (unsafe-fx+ x0 1)) - (define y1 (unsafe-fx+ y0 1)) - (define v00 (flomap-ref* vs c w h k x0 y0)) - (define v10 (flomap-ref* vs c w h k x1 y0)) - (define v01 (flomap-ref* vs c w h k x0 y1)) - (define v11 (flomap-ref* vs c w h k x1 y1)) - (define xα (unsafe-fl- x floor-x)) - (unsafe-fl-convex-combination (unsafe-fl-convex-combination v00 v10 xα) - (unsafe-fl-convex-combination v01 v11 xα) - (unsafe-fl- y floor-y)))) - -;; =================================================================================================== -;; Construction and conversion - -(define (make-flomap c w h [v 0.0]) - (flomap (make-flvector (* c w h) (exact->inexact v)) - c w h)) - -(define (make-flomap/components w h vs) - (let ([vs (apply flvector (map exact->inexact vs))]) - (define c (flvector-length vs)) - (define new-vs - (for*/flvector #:length (* c w h) ([y (in-range h)] [x (in-range w)] [v (in-flvector vs)]) - v)) - (flomap new-vs c w h))) - -(define-syntax-rule (unsafe-build-flomap components width height image-fun) - (let ([c components] [w width] [h height] [f image-fun]) - (define vs (make-flvector (* c w h))) - (let y-loop ([y 0] [i 0]) - (cond - [(y . unsafe-fx< . h) - (let x-loop ([x 0] [i i]) - (cond - [(x . unsafe-fx< . w) - (let k-loop ([k 0] [i i]) - (cond - [(k . unsafe-fx< . c) - (unsafe-flvector-set! vs i (f k x y)) - (k-loop (unsafe-fx+ k 1) (unsafe-fx+ i 1))] - [else - (x-loop (unsafe-fx+ x 1) i)]))] - [else - (y-loop (unsafe-fx+ y 1) i)]))] - [else - (flomap vs c w h)])))) - -(define (build-flomap c w h f) - (unsafe-build-flomap c w h (λ (k x y) (exact->inexact (f k x y))))) - -(define (flomap-ref-component fm k) - (match-define (flomap vs c w h) fm) - (unless (k . < . c) - (error 'flomap-ref-component "expected component index < ~e; given index ~e" c k)) - (unsafe-build-flomap - 1 w h - (λ (_ x y) (unsafe-flvector-ref vs (unsafe-coords->index c w k x y))))) - -(define (flomap-take-components fm c) - (match-define (flomap vs old-c w h) fm) - (unless (c . <= . old-c) - (error 'flomap-take-components "can only take <= ~e components; given ~e" old-c c)) - (unsafe-build-flomap - c w h - (λ (k x y) (unsafe-flvector-ref vs (unsafe-coords->index old-c w k x y))))) - -(define (flomap-drop-components fm c) - (match-define (flomap vs old-c w h) fm) - (unless (c . <= . old-c) - (error 'flomap-drop-components "can only drop <= ~e components; given ~e" old-c c)) - (unsafe-build-flomap - (- old-c c) w h - (λ (k x y) (unsafe-flvector-ref vs (unsafe-coords->index old-c w (unsafe-fx+ k c) x y))))) - -(define (flomap-append-components2 fm1 fm2) - (match-define (flomap vs1 d1 w1 h1) fm1) - (match-define (flomap vs2 d2 w2 h2) fm2) - (unless (and (= w1 w2) (= h1 h2)) - (error 'flomap-append-components - "expected flomaps with equal dimension; given dimensions ~e×~e and ~e×~e" - w1 h1 w2 h2)) - (unsafe-build-flomap - (+ d1 d2) w1 h1 - (λ (k x y) - (cond [(k . unsafe-fx< . d1) (unsafe-flvector-ref vs1 (unsafe-coords->index d1 w1 k x y))] - [else (unsafe-flvector-ref vs2 (unsafe-coords->index d2 w2 (unsafe-fx- k d1) x y))])))) - -(define (flomap-append-components fm . fms) - (for/fold ([fm1 fm]) ([fm2 (in-list fms)]) - (flomap-append-components2 fm1 fm2))) - -(define (fldivide x y) - (if (y . unsafe-fl= . 0.0) 0.0 (unsafe-fl/ x y))) - -(define (flomap-divide-alpha fm) - (match-define (flomap _ c w h) fm) - (cond [(c . <= . 1) fm] - [else - (define alpha-fm (flomap-ref-component fm 0)) - (flomap-append-components alpha-fm ((flomap-lift2/unsafe 'flomap-divide-alpha fldivide) - (flomap-drop-components fm 1) alpha-fm))])) - -(define (flomap-multiply-alpha fm) - (match-define (flomap _ c w h) fm) - (cond [(c . > . 1) - (define alpha-fm (flomap-ref-component fm 0)) - (flomap-append-components alpha-fm (fm* (flomap-drop-components fm 1) alpha-fm))] - [else fm])) - -(define (bitmap->flomap bm) - (define w (send bm get-width)) - (define h (send bm get-height)) - (define bs (make-bytes (* 4 w h))) - ;; get bytes without premultiplying alpha because doing it in flonums maintains precision - ;; (if RGB bytes are stored without premultiplying alpha) - (send bm get-argb-pixels 0 0 w h bs #t) - (send bm get-argb-pixels 0 0 w h bs #f) - - (define argb-fm (make-flomap 4 w h)) - (define argb-vs (flomap-values argb-fm)) - (for ([i0 (in-range 0 (* 4 w h) 4)]) - (define i1 (unsafe-fx+ i0 1)) - (define i2 (unsafe-fx+ i0 2)) - (define i3 (unsafe-fx+ i0 3)) - (define a (unsafe-bytes-ref bs i0)) - (define r (unsafe-bytes-ref bs i1)) - (define g (unsafe-bytes-ref bs i2)) - (define b (unsafe-bytes-ref bs i3)) - (unsafe-flvector-set! argb-vs i0 (unsafe-fl/ (unsafe-fx->fl a) 255.0)) - (unsafe-flvector-set! argb-vs i1 (unsafe-fl/ (unsafe-fx->fl r) 255.0)) - (unsafe-flvector-set! argb-vs i2 (unsafe-fl/ (unsafe-fx->fl g) 255.0)) - (unsafe-flvector-set! argb-vs i3 (unsafe-fl/ (unsafe-fx->fl b) 255.0))) - (flomap-multiply-alpha argb-fm)) - -(define (flomap->bitmap fm) - (match-define (flomap vs c w h) fm) - (let* ([fm (case c - [(1) (flomap-append-components (make-flomap 1 w h 1.0) fm fm fm)] - [(2) (define alpha-fm (flomap-ref-component fm 0)) - (define value-fm (flomap-drop-components fm 1)) - (flomap-append-components alpha-fm value-fm value-fm value-fm)] - [(3) (flomap-append-components (make-flomap 1 w h 1.0) fm)] - [(4) fm] - [else (raise-type-error 'flomap->bitmap "flomap with 1, 2, 3 or 4 components" fm)])] - ;; inset if zero (bitmaps can't have zero size) - [fm (flomap-inset fm 0 0 (if (= w 0) 1 0) (if (= h 0) 1 0))] - ;; divide alphas before converting - [fm (flomap-divide-alpha fm)]) - ;; guaranteed an ARGB flomap now - (match-define (flomap vs 4 w h) fm) - (define bs (make-bytes (* 4 w h))) - (for ([i0 (in-range 0 (* 4 w h) 4)]) - (define i1 (unsafe-fx+ i0 1)) - (define i2 (unsafe-fx+ i0 2)) - (define i3 (unsafe-fx+ i0 3)) - (define a (unsafe-flvector-ref vs i0)) - (define r (unsafe-flvector-ref vs i1)) - (define g (unsafe-flvector-ref vs i2)) - (define b (unsafe-flvector-ref vs i3)) - (unsafe-bytes-set! bs i0 (unsafe-fl->byte (unsafe-fl* 255.0 a))) - (unsafe-bytes-set! bs i1 (unsafe-fl->byte (unsafe-fl* 255.0 r))) - (unsafe-bytes-set! bs i2 (unsafe-fl->byte (unsafe-fl* 255.0 g))) - (unsafe-bytes-set! bs i3 (unsafe-fl->byte (unsafe-fl* 255.0 b)))) - - (define bm (make-bitmap w h)) - (send bm set-argb-pixels 0 0 w h bs #t) - (send bm set-argb-pixels 0 0 w h bs #f) - bm)) - -(define (draw-flomap w h draw-proc) - (define bm (make-bitmap (max w 1) (max h 1))) - (define dc (make-object bitmap-dc% bm)) - (send dc set-smoothing 'smoothed) - (draw-proc dc) - (flomap-inset (bitmap->flomap bm) 0 0 (if (= w 0) -1 0) (if (= h 0) -1 0))) - -;; =================================================================================================== -;; Unary pointwise operations - -(define-syntax-rule (flomap-lift/unsafe f) - (λ (fm) - (match-define (flomap vs c w h) fm) - (define n (* c w h)) - (define res-vs (make-flvector n)) - (flomap (let loop ([i 0]) - (cond [(i . unsafe-fx< . n) - (unsafe-flvector-set! res-vs i (f (unsafe-flvector-ref vs i))) - (loop (unsafe-fx+ i 1))] - [else res-vs])) - c w h))) - -(define (flomap-lift op) - (flomap-lift/unsafe (λ (x) (exact->inexact (op x))))) - -(define fmneg (flomap-lift/unsafe unsafe-flneg)) -(define fmabs (flomap-lift/unsafe unsafe-flabs)) -(define fmsqr (flomap-lift/unsafe (λ (x) (unsafe-fl* x x)))) -(define fmsin (flomap-lift/unsafe unsafe-flsin)) -(define fmcos (flomap-lift/unsafe unsafe-flcos)) -(define fmtan (flomap-lift/unsafe unsafe-fltan)) -(define fmlog (flomap-lift/unsafe unsafe-fllog)) -(define fmexp (flomap-lift/unsafe unsafe-flexp)) -(define fmsqrt (flomap-lift/unsafe unsafe-flsqrt)) -(define fmasin (flomap-lift/unsafe unsafe-flasin)) -(define fmacos (flomap-lift/unsafe unsafe-flacos)) -(define fmatan (flomap-lift/unsafe unsafe-flatan)) -(define fmround (flomap-lift/unsafe unsafe-flround)) -(define fmfloor (flomap-lift/unsafe unsafe-flfloor)) -(define fmceiling (flomap-lift/unsafe unsafe-flceiling)) -(define fmtruncate (flomap-lift/unsafe unsafe-fltruncate)) - -;; =================================================================================================== -;; Binary pointwise operations - -(define-syntax-rule (flomap-lift2/unsafe name unsafe-op) - (λ (fm1 fm2) - (cond - [(and (real? fm1) (real? fm2)) - (error name "expected at least one flomap argument; given ~e and ~e" fm1 fm2)] - [(real? fm1) (let ([fm1 (exact->inexact fm1)]) - ((flomap-lift/unsafe (λ (v) (unsafe-op fm1 v))) fm2))] - [(real? fm2) (let ([fm2 (exact->inexact fm2)]) - ((flomap-lift/unsafe (λ (v) (unsafe-op v fm2))) fm1))] - [else - (match-define (flomap vs1 c1 w h) fm1) - (match-define (flomap vs2 c2 w2 h2) fm2) - (cond - [(not (and (= w w2) (= h h2))) - (error name "expected flomaps of equal size; given sizes ~e×~e and ~e×~e" w h w2 h2)] - [(= c1 c2) - (define n (* c1 w h)) - (define res-vs (make-flvector n)) - (flomap (let loop ([i 0]) - (cond [(i . unsafe-fx< . n) - (unsafe-flvector-set! res-vs i (unsafe-op (unsafe-flvector-ref vs1 i) - (unsafe-flvector-ref vs2 i))) - (loop (unsafe-fx+ i 1))] - [else res-vs])) - c1 w h)] - [(= c1 1) - (unsafe-build-flomap - c2 w h - (λ (k x y) - (unsafe-op (unsafe-flvector-ref vs1 (unsafe-coords->index 1 w 0 x y)) - (unsafe-flvector-ref vs2 (unsafe-coords->index c2 w k x y)))))] - [(= c2 1) - (unsafe-build-flomap - c1 w h - (λ (k x y) - (unsafe-op (unsafe-flvector-ref vs1 (unsafe-coords->index c1 w k x y)) - (unsafe-flvector-ref vs2 (unsafe-coords->index 1 w 0 x y)))))] - [else - (error name (string-append "expected flomaps with the same number of components, " - "or a flomap with 1 component and a flomap with n components; " - "given flomaps with ~e and ~e components") - c1 c2)])]))) - -(define (flomap-lift2 name op) - (flomap-lift2/unsafe name (λ (x y) (exact->inexact (op x y))))) - -(define fm+ (flomap-lift2/unsafe 'fm+ unsafe-fl+)) -(define fm- (flomap-lift2/unsafe 'fm- unsafe-fl-)) -(define fm* (flomap-lift2/unsafe 'fm* unsafe-fl*)) -(define fm/ (flomap-lift2/unsafe 'fm/ unsafe-fl/)) -(define fmmin (flomap-lift2/unsafe 'fmmin unsafe-flmin)) -(define fmmax (flomap-lift2/unsafe 'fmmax unsafe-flmax)) - -(define (flomap-normalize fm) - (match-define (flomap _ _c w h) fm) - (define-values (v-min v-max) (flomap-extreme-values fm)) - (define v-size (- v-max v-min)) - (let* ([fm (fm- fm v-min)] - [fm (if (zero? v-size) fm (fm/ fm (- v-max v-min)))]) - fm)) - -;; =================================================================================================== -;; Gaussian blur - -(define (flomap-gaussian-blur fm xσ [yσ xσ] [x-stddevs 3.0] [y-stddevs 3.0]) - (flomap-gaussian-blur-y - (flomap-gaussian-blur-x fm (abs (exact->inexact xσ)) (abs (exact->inexact x-stddevs))) - (abs (exact->inexact yσ)) (abs (exact->inexact y-stddevs)))) - -(define (flomap-gaussian-blur-x fm σ stddevs) - (let ([σ (abs (exact->inexact σ))] - [stddevs (abs (exact->inexact stddevs))]) - (cond - [(or (σ . = . 0.0) (stddevs . = . 0.0)) fm] - [else - (define dx-min (inexact->exact (floor (* (- stddevs) σ)))) - (define dx-max (+ 1 (inexact->exact (ceiling (* stddevs σ))))) - (define ss (gaussian-kernel-1d dx-min dx-max σ)) - - (match-define (flomap vs c w h) fm) - (unsafe-build-flomap - c w h - (λ (k x y) - (define dx-start (unsafe-fx- (unsafe-fxmax (unsafe-fx+ x dx-min) 0) x)) - (define dx-end (unsafe-fx- (unsafe-fxmin (unsafe-fx+ x dx-max) w) x)) - (define i (unsafe-fx+ k (unsafe-fx* c (unsafe-fx+ x (unsafe-fx* w y))))) - (define j (unsafe-fx+ i (unsafe-fx* c dx-start))) - ;; this inner loop has to be *tight*, so no `for'; seems to speed it up by about 50% - (let src-loop ([sum 0.0] [dx dx-start] [j j]) - (cond [(dx . unsafe-fx< . dx-end) - (define s (unsafe-flvector-ref ss (unsafe-fx- dx dx-min))) - (src-loop (unsafe-fl+ sum (unsafe-fl* s (unsafe-flvector-ref vs j))) - (unsafe-fx+ dx 1) - (unsafe-fx+ j c))] - [else sum]))))]))) - -(define (flomap-gaussian-blur-y fm σ stddevs) - (let ([σ (abs (exact->inexact σ))] - [stddevs (abs (exact->inexact stddevs))]) - (cond - [(or (σ . = . 0.0) (stddevs . = . 0.0)) fm] - [else - (define dy-min (inexact->exact (floor (* (- stddevs) σ)))) - (define dy-max (+ 1 (inexact->exact (ceiling (* stddevs σ))))) - (define ss (gaussian-kernel-1d dy-min dy-max σ)) - - (match-define (flomap vs c w h) fm) - (define cw (* c w)) - (unsafe-build-flomap - c w h - (λ (k x y) - (define dy-start (unsafe-fx- (unsafe-fxmax (unsafe-fx+ y dy-min) 0) y)) - (define dy-end (unsafe-fx- (unsafe-fxmin (unsafe-fx+ y dy-max) h) y)) - (define i (unsafe-fx+ k (unsafe-fx* c (unsafe-fx+ x (unsafe-fx* w y))))) - (define j (unsafe-fx+ i (unsafe-fx* cw dy-start))) - ;; this inner loop has to be *tight*, so no `for'; seems to speed it up by about 50% - (let src-loop ([sum 0.0] [dy dy-start] [j j]) - (cond [(dy . unsafe-fx< . dy-end) - (define s (unsafe-flvector-ref ss (unsafe-fx- dy dy-min))) - (src-loop (unsafe-fl+ sum (unsafe-fl* s (unsafe-flvector-ref vs j))) - (unsafe-fx+ dy 1) - (unsafe-fx+ j cw))] - [else sum]))))]))) - -(define (gaussian-kernel-1d mn mx σ) - (define n (- mx mn)) - (define ys - (for/flvector #:length n ([x (in-range mn mx)]) - (unsafe-flgaussian (unsafe-fx->fl x) σ))) - (define s (unsafe-flvector-sum ys)) - (for/flvector #:length n ([y (in-flvector ys)]) - (unsafe-fl/ y s))) - -;; =================================================================================================== -;; Integral images - -(define (flomap-integral fm) - (match-define (flomap vs c w h) fm) - (define w+1 (+ w 1)) - (define c*w+1 (* c w+1)) - (define h+1 (+ h 1)) - (define new-vs (make-flvector (* c w+1 h+1))) - (for* ([y (in-range h)] [x (in-range w)] [k (in-range c)]) - (define i (unsafe-coords->index c w k x y)) - (define j00 (unsafe-coords->index c w+1 k x y)) - (define j01 (unsafe-fx+ j00 c*w+1)) - (unsafe-flvector-set! new-vs (unsafe-fx+ j01 c) - (unsafe-fl- (unsafe-flsum (unsafe-flvector-ref vs i) - (unsafe-flvector-ref new-vs j01) - (unsafe-flvector-ref new-vs (unsafe-fx+ j00 c))) - (unsafe-flvector-ref new-vs j00)))) - (flomap new-vs c w+1 h+1)) - -(define (unsafe-flomap-integral-sum vs c w h k x-start y-start x-end y-end) - (define w-1 (unsafe-fx- w 1)) - (define h-1 (unsafe-fx- h 1)) - (define x1 (unsafe-fxmax 0 (unsafe-fxmin x-start w-1))) - (define x2 (unsafe-fxmax 0 (unsafe-fxmin x-end w-1))) - (define y1 (unsafe-fxmax 0 (unsafe-fxmin y-start h-1))) - (define y2 (unsafe-fxmax 0 (unsafe-fxmin y-end h-1))) - (unsafe-fl- (unsafe-fl+ (unsafe-flvector-ref vs (unsafe-coords->index c w k x1 y1)) - (unsafe-flvector-ref vs (unsafe-coords->index c w k x2 y2))) - (unsafe-fl+ (unsafe-flvector-ref vs (unsafe-coords->index c w k x1 y2)) - (unsafe-flvector-ref vs (unsafe-coords->index c w k x2 y1))))) - -(define (flomap-integral-x fm) - (match-define (flomap vs c w h) fm) - (define w+1 (+ w 1)) - (define new-vs (make-flvector (* c w+1 h))) - (for* ([y (in-range h)] [x (in-range w)] [k (in-range c)]) - (define i (unsafe-coords->index c w k x y)) - (define j0 (unsafe-coords->index c w+1 k x y)) - (define j1 (unsafe-fx+ j0 c)) - (unsafe-flvector-set! new-vs j1 - (unsafe-fl+ (unsafe-flvector-ref vs i) - (unsafe-flvector-ref new-vs j0)))) - (flomap new-vs c w+1 h)) - -(define (flomap-integral-y fm) - (match-define (flomap vs c w h) fm) - (define h+1 (+ h 1)) - (define cw (* c w)) - (define new-vs (make-flvector (* c w h+1))) - (for* ([y (in-range h)] [x (in-range w)] [k (in-range c)]) - (define j0 (unsafe-coords->index c w k x y)) - (define j1 (unsafe-fx+ j0 cw)) - (unsafe-flvector-set! new-vs j1 - (unsafe-fl+ (unsafe-flvector-ref vs j0) - (unsafe-flvector-ref new-vs j0)))) - (flomap new-vs c w h+1)) - -(define (unsafe-flomap-integral-x-sum vs c w k x-start x-end y) - (define w-1 (unsafe-fx- w 1)) - (define x1 (unsafe-fxmax 0 (unsafe-fxmin x-start w-1))) - (define x2 (unsafe-fxmax 0 (unsafe-fxmin x-end w-1))) - (unsafe-fl- (unsafe-flvector-ref vs (unsafe-coords->index c w k x2 y)) - (unsafe-flvector-ref vs (unsafe-coords->index c w k x1 y)))) - -(define (unsafe-flomap-integral-y-sum vs c w h k x y-start y-end) - (define h-1 (unsafe-fx- h 1)) - (define y1 (unsafe-fxmax 0 (unsafe-fxmin y-start h-1))) - (define y2 (unsafe-fxmax 0 (unsafe-fxmin y-end h-1))) - (unsafe-fl- (unsafe-flvector-ref vs (unsafe-coords->index c w k x y2)) - (unsafe-flvector-ref vs (unsafe-coords->index c w k x y1)))) - -;; =================================================================================================== -;; Box blur - -(define (flomap-box-blur fm xr [yr xr]) - (let ([xr (abs xr)] [yr (abs yr)]) - (cond [(and (integer? xr) (integer? yr)) - (flomap-box-blur/int fm (inexact->exact xr) (inexact->exact yr))] - [else - (flomap-box-blur-y (flomap-box-blur-x fm xr) yr)]))) - -(define (flomap-box-blur-x fm r) - (cond - [(integer? r) (flomap-box-blur-x/int fm (inexact->exact r))] - [else - (define r1 (inexact->exact (floor r))) - (define r2 (+ r1 1)) - (define s (+ 1 (* 2 r))) - (define s1 (+ 1 (* 2 r1))) - (define s2 (+ 1 (* 2 r2))) - (define α (exact->inexact (/ (- (sqr s2) (sqr s)) (- (sqr s2) (sqr s1))))) - (define norm1 (/ α s1)) - (define norm2 (/ (- 1 α) s2)) - (define r1+1 (+ r1 1)) - (define r2+1 (+ r2 1)) - (match-define (flomap _ c w h) fm) - (match-define (flomap int-vs int-c int-w int-h) (flomap-integral-x fm)) - (unsafe-build-flomap - c w h - (λ (k x y) - (unsafe-fl+ - (unsafe-fl* norm1 (unsafe-flomap-integral-x-sum - int-vs int-c int-w k - (unsafe-fx- x r1) (unsafe-fx+ x r1+1) y)) - (unsafe-fl* norm2 (unsafe-flomap-integral-x-sum - int-vs int-c int-w k - (unsafe-fx- x r2) (unsafe-fx+ x r2+1) y)))))])) - -(define (flomap-box-blur-y fm r) - (cond - [(integer? r) (flomap-box-blur-y/int fm (inexact->exact r))] - [else - (define r1 (inexact->exact (floor r))) - (define r2 (+ r1 1)) - (define s (+ 1 (* 2 r))) - (define s1 (+ 1 (* 2 r1))) - (define s2 (+ 1 (* 2 r2))) - (define α (exact->inexact (/ (- (sqr s2) (sqr s)) (- (sqr s2) (sqr s1))))) - (define norm1 (/ α s1)) - (define norm2 (/ (- 1 α) s2)) - (define r1+1 (+ r1 1)) - (define r2+1 (+ r2 1)) - (match-define (flomap _ c w h) fm) - (match-define (flomap int-vs int-c int-w int-h) (flomap-integral-y fm)) - (unsafe-build-flomap - c w h - (λ (k x y) - (unsafe-fl+ - (unsafe-fl* norm1 (unsafe-flomap-integral-y-sum - int-vs int-c int-w int-h k x - (unsafe-fx- y r1) (unsafe-fx+ y r1+1))) - (unsafe-fl* norm2 (unsafe-flomap-integral-y-sum - int-vs int-c int-w int-h k x - (unsafe-fx- y r2) (unsafe-fx+ y r2+1))))))])) - -(define (flomap-box-blur/int fm xr yr) - (define norm (/ 1.0 (* (+ 1 (* 2 xr)) (+ 1 (* 2 yr))))) - (define xr+1 (+ xr 1)) - (define yr+1 (+ yr 1)) - (match-define (flomap _ c w h) fm) - (match-define (flomap int-vs int-c int-w int-h) (flomap-integral fm)) - (unsafe-build-flomap - c w h - (λ (k x y) - (unsafe-fl* norm (unsafe-flomap-integral-sum - int-vs int-c int-w int-h k - (unsafe-fx- x xr) (unsafe-fx- y yr) - (unsafe-fx+ x xr+1) (unsafe-fx+ y yr+1)))))) - -(define (flomap-box-blur-x/int fm r) - (define norm (/ 1.0 (+ 1 (* 2 r)))) - (define r+1 (+ r 1)) - (match-define (flomap _ c w h) fm) - (match-define (flomap int-vs int-c int-w int-h) (flomap-integral-x fm)) - (unsafe-build-flomap - c w h - (λ (k x y) - (unsafe-fl* norm (unsafe-flomap-integral-x-sum - int-vs int-c int-w k - (unsafe-fx- x r) (unsafe-fx+ x r+1) y))))) - -(define (flomap-box-blur-y/int fm r) - (define norm (/ 1.0 (+ 1 (* 2 r)))) - (define r+1 (+ r 1)) - (match-define (flomap _ c w h) fm) - (match-define (flomap int-vs int-c int-w int-h) (flomap-integral-y fm)) - (unsafe-build-flomap - c w h - (λ (k x y) - (unsafe-fl* norm (unsafe-flomap-integral-y-sum - int-vs int-c int-w int-h k x - (unsafe-fx- y r) (unsafe-fx+ y r+1)))))) - -;; =================================================================================================== -;; Default blur - -(define (flomap-blur fm xσ [yσ xσ]) - (let ([xσ (abs xσ)] [yσ (abs yσ)]) - (cond - [(and (xσ . >= . 1.5) (yσ . >= . 1.5)) - (define xσ^2 (sqr xσ)) - (define yσ^2 (sqr yσ)) - (define xr (floor (variance->box-radius (* 1/3 xσ^2)))) - (define yr (floor (variance->box-radius (* 1/3 yσ^2)))) - (flomap-box-blur (flomap-box-blur (flomap-box-blur fm xr yr) xr yr) - (variance->box-radius (- xσ^2 (* 2 (box-radius->variance xr)))) - (variance->box-radius (- yσ^2 (* 2 (box-radius->variance yr)))))] - [else - (flomap-blur-x (flomap-blur-y fm yσ) xσ)]))) - -(define (box-radius->variance r) - (* 1/12 (sqr (+ 1 (* 2 r))))) - -(define (variance->box-radius σ^2) - (* 1/2 (- (sqrt (* 12 σ^2)) 1))) - -(define ((make-flomap-blur-dimension gaussian-blur box-blur) fm σ) - (cond - [(σ . = . 0.0) fm] - [(σ . < . 1.5) (gaussian-blur fm σ 3.0)] - [else - (define σ^2 (sqr σ)) - (define r (floor (variance->box-radius (* 1/3 σ^2)))) - (box-blur (box-blur (box-blur fm r) r) - (variance->box-radius (- σ^2 (* 2 (box-radius->variance r)))))])) - -(define flomap-blur-x (make-flomap-blur-dimension flomap-gaussian-blur-x flomap-box-blur-x)) -(define flomap-blur-y (make-flomap-blur-dimension flomap-gaussian-blur-y flomap-box-blur-y)) - -;; =================================================================================================== -;; Derivatives (Schurr operator) - -(define (flomap-gradient-x fm) - (match-define (flomap vs c w h) fm) - (define cw (* c w)) - (define d00 (+ (- cw) -1)) - (define d20 (+ (- cw) 1)) - (define d02 (+ cw -1)) - (define d22 (+ cw 1)) - (define w-1 (- w 1)) - (define h-1 (- h 1)) - (unsafe-build-flomap - c w h - (λ (k x y) - (cond [(and (x . unsafe-fx> . 0) (x . unsafe-fx< . w-1) - (y . unsafe-fx> . 0) (y . unsafe-fx< . h-1)) - (define i (unsafe-fx+ k (unsafe-fx* c (unsafe-fx+ x (unsafe-fx* w y))))) - (unsafe-flsum - (unsafe-fl- (unsafe-fl* 0.1875 (unsafe-flvector-ref vs (unsafe-fx+ i d20))) - (unsafe-fl* 0.1875 (unsafe-flvector-ref vs (unsafe-fx+ i d00)))) - (unsafe-fl- (unsafe-fl* 0.6250 (unsafe-flvector-ref vs (unsafe-fx+ i 1))) - (unsafe-fl* 0.6250 (unsafe-flvector-ref vs (unsafe-fx- i 1)))) - (unsafe-fl- (unsafe-fl* 0.1875 (unsafe-flvector-ref vs (unsafe-fx+ i d22))) - (unsafe-fl* 0.1875 (unsafe-flvector-ref vs (unsafe-fx+ i d02)))))] - [else 0.0])))) - -(define (flomap-gradient-y fm) - (match-define (flomap vs c w h) fm) - (define cw (* c w)) - (define d00 (+ (- cw) -1)) - (define d02 (+ cw -1)) - (define d20 (+ (- cw) 1)) - (define d22 (+ cw 1)) - (define w-1 (- w 1)) - (define h-1 (- h 1)) - (unsafe-build-flomap - c w h - (λ (k x y) - (cond [(and (x . unsafe-fx> . 0) (x . unsafe-fx< . w-1) - (y . unsafe-fx> . 0) (y . unsafe-fx< . h-1)) - (define i (unsafe-fx+ k (unsafe-fx* c (unsafe-fx+ x (unsafe-fx* w y))))) - (unsafe-flsum - (unsafe-fl- (unsafe-fl* 0.1875 (unsafe-flvector-ref vs (unsafe-fx+ i d02))) - (unsafe-fl* 0.1875 (unsafe-flvector-ref vs (unsafe-fx+ i d00)))) - (unsafe-fl- (unsafe-fl* 0.6250 (unsafe-flvector-ref vs (unsafe-fx+ i cw))) - (unsafe-fl* 0.6250 (unsafe-flvector-ref vs (unsafe-fx- i cw)))) - (unsafe-fl- (unsafe-fl* 0.1875 (unsafe-flvector-ref vs (unsafe-fx+ i d22))) - (unsafe-fl* 0.1875 (unsafe-flvector-ref vs (unsafe-fx+ i d20)))))] - [else 0.0])))) - -(define (flomap-gradient fm) - (values (flomap-gradient-x fm) (flomap-gradient-y fm))) - -(define (flomap-gradient-normal z-fm) - (define-values (dx-bm dy-bm) (flomap-gradient z-fm)) - (match-define (flomap dxs 1 w h) dx-bm) - (match-define (flomap dys 1 _w _h) dy-bm) - (define normal-vs (make-flvector (* 3 w h))) - (for ([i (in-range (* w h))]) - (define j (unsafe-fx* 3 i)) - (define dx (unsafe-flvector-ref dxs i)) - (define dy (unsafe-flvector-ref dys i)) - (define-values (nx ny nz) (unsafe-fl3normalize (unsafe-flneg dx) (unsafe-flneg dy) 2.0)) - (unsafe-flvector-3set! normal-vs j nx ny nz)) - (flomap normal-vs 3 w h)) - -;; =================================================================================================== -;; Statistics - -(define (flomap-min-value fm) - (define vs (flomap-values fm)) - (for/fold ([v-min 0.0]) ([v (in-flvector vs)]) - (unsafe-flmin v-min v))) - -(define (flomap-max-value fm) - (define vs (flomap-values fm)) - (for/fold ([v-max 0.0]) ([v (in-flvector vs)]) - (unsafe-flmax v-max v))) - -(define (flomap-extreme-values fm) - (define vs (flomap-values fm)) - (for/fold ([v-min 0.0] [v-max 0.0]) ([v (in-flvector vs)]) - (values (unsafe-flmin v-min v) - (unsafe-flmax v-max v)))) - -(define (flomap-nonzero-rect fm) - (match-define (flomap vs c w h) fm) - (for*/fold ([k-min c] [x-min w] [y-min h] [k-max 0] [x-max 0] [y-max 0] - ) ([y (in-range h)] [x (in-range w)] [k (in-range c)]) - (define i (unsafe-fx+ k (unsafe-fx* c (unsafe-fx+ x (unsafe-fx* y w))))) - (define v (unsafe-flvector-ref vs i)) - (cond [(not (v . unsafe-fl= . 0.0)) - (values (unsafe-fxmin k-min k) - (unsafe-fxmin x-min x) - (unsafe-fxmin y-min y) - (unsafe-fxmax k-max (unsafe-fx+ 1 k)) - (unsafe-fxmax x-max (unsafe-fx+ 1 x)) - (unsafe-fxmax y-max (unsafe-fx+ 1 y)))] - [else (values k-min x-min y-min k-max x-max y-max)]))) - -;; =================================================================================================== -;; Sizing - -(define flomap-inset - (case-lambda - [(fm amt) - (flomap-inset fm amt amt amt amt)] - [(fm h-amt v-amt) - (flomap-inset fm h-amt v-amt h-amt v-amt)] - [(fm l-amt t-amt r-amt b-amt) - (cond [(and (= l-amt 0) (= t-amt 0) (= r-amt 0) (= b-amt 0)) fm] - [else - (match-define (flomap vs c w h) fm) - (define new-w (+ w l-amt r-amt)) - (define new-h (+ h t-amt b-amt)) - (define new-vs (make-flvector (* c new-w new-h))) - (for ([new-y (in-range new-h)]) - (define y (- new-y t-amt)) - (when (and (y . >= . 0) (y . < . h)) - (for ([new-x (in-range new-w)]) - (define x (- new-x l-amt)) - (when (and (x . >= . 0) (x . < . w)) - (for ([k (in-range c)]) - (define i (unsafe-coords->index c w k x y)) - (define new-i (unsafe-coords->index c new-w k new-x new-y)) - (unsafe-flvector-set! new-vs new-i (unsafe-flvector-ref vs i))))))) - (flomap new-vs c new-w new-h)])])) - -(define (flomap-trim fm) - (match-define (flomap _ c w h) fm) - (unless (c . > . 0) - (raise-type-error 'flomap-shadow "flomap with at least 1 component" fm)) - (define-values (_k-min x-min y-min _k-max x-max y-max) - (flomap-nonzero-rect (flomap-ref-component fm 0))) - (flomap-inset fm (- x-min) (- y-min) (- x-max w) (- y-max h))) - -(define (flomap-crop fm width height x-frac y-frac) - (match-define (flomap _ c w h) fm) - (define l-amt (round (* x-frac (- width w)))) - (define r-amt (- (- width w) l-amt)) - (define t-amt (round (* y-frac (- height h)))) - (define b-amt (- (- height h) t-amt)) - (flomap-inset fm l-amt t-amt r-amt b-amt)) - -(define (flomap-lt-crop fm w h) (flomap-crop fm w h 0 0)) -(define (flomap-lc-crop fm w h) (flomap-crop fm w h 0 1/2)) -(define (flomap-lb-crop fm w h) (flomap-crop fm w h 0 1)) -(define (flomap-ct-crop fm w h) (flomap-crop fm w h 1/2 0)) -(define (flomap-cc-crop fm w h) (flomap-crop fm w h 1/2 1/2)) -(define (flomap-cb-crop fm w h) (flomap-crop fm w h 1/2 1)) -(define (flomap-rt-crop fm w h) (flomap-crop fm w h 1 0)) -(define (flomap-rc-crop fm w h) (flomap-crop fm w h 1 1/2)) -(define (flomap-rb-crop fm w h) (flomap-crop fm w h 1 1)) - -(define flomap-scale - (case-lambda - [(fm scale) (flomap-scale fm scale scale)] - [(fm x-scale y-scale) (flomap-scale-x (flomap-scale-y fm (exact->inexact y-scale)) - (exact->inexact x-scale))])) - -(define (flomap-resize fm width height) - (cond [(and width height) (flomap-resize-x (flomap-resize-y fm height) width)] - [width (define s (exact->inexact (/ width (flomap-width fm)))) - (flomap-resize-x (flomap-scale-y fm s) width)] - [height (define s (exact->inexact (/ height (flomap-height fm)))) - (flomap-scale-x (flomap-resize-y fm height) s)])) - -(define (flomap-scale-x fm scale) - (cond [(= 0 scale) (match-define (flomap _ c w h) fm) - (make-flomap c 0 h)] - [else (flomap-scale*-x fm scale (inexact->exact (ceiling (* (flomap-width fm) scale))))])) - -(define (flomap-scale-y fm scale) - (cond [(= 0 scale) (match-define (flomap _ c w h) fm) - (make-flomap c w 0)] - [else (flomap-scale*-y fm scale (inexact->exact (ceiling (* (flomap-height fm) scale))))])) - -(define (flomap-resize-x fm width) - (cond [(= 0 width) (match-define (flomap _ c w h) fm) - (make-flomap c 0 h)] - [else (flomap-scale*-x fm (exact->inexact (/ width (flomap-width fm))) width)])) - -(define (flomap-resize-y fm height) - (cond [(= 0 height) (match-define (flomap _ c w h) fm) - (make-flomap c w 0)] - [else (flomap-scale*-y fm (exact->inexact (/ height (flomap-height fm))) height)])) - -;; standard deviation of an unscaled box filter (i.e. f([-1/2,1/2]) = {1}, zero elsewhere) -(define box-filter-variance 1/12) -;; standard deviation of an unscaled triangle filter (simualtes effect of linear interpolation) -(define triangle-filter-variance 1/24) - -;; calculates the standard deviation of downscaling blur, assuming linear interpolation will be -;; carried out on the blurred image -(define (stddev-for-scale scale) - (define var (- (/ box-filter-variance (sqr scale)) - triangle-filter-variance)) - (sqrt (max 0 var))) - -(define (flomap-scale*-x fm scale width) - (cond [(scale . = . 1.0) fm] - [(scale . > . 1.0) (flomap-scale*-x/linear fm scale width)] - [else (define low-res-fm - (flomap-gaussian-blur-x fm (stddev-for-scale scale) 2.0)) - (flomap-scale*-x/linear low-res-fm scale width)])) - -(define (flomap-scale*-y fm scale height) - (cond [(scale . = . 1.0) fm] - [(scale . > . 1.0) (flomap-scale*-y/linear fm scale height)] - [else (define low-res-fm - (flomap-gaussian-blur-y fm (stddev-for-scale scale) 2.0)) - (flomap-scale*-y/linear low-res-fm scale height)])) - -(define (flomap-scale*-x/linear fm s new-w) - (match-define (flomap vs c w h) fm) - (define w-1 (unsafe-fx- w 1)) - (unsafe-build-flomap - c new-w h - (λ (k new-x y) - (define scaled-x (unsafe-fl- (unsafe-fl/ (unsafe-fl+ (unsafe-fx->fl new-x) 0.5) s) 0.5)) - (define floor-scaled-x (unsafe-flfloor scaled-x)) - (define x0 (unsafe-fl->fx floor-scaled-x)) - (cond [(or (x0 . unsafe-fx< . 0) (x0 . unsafe-fx>= . w)) 0.0] - [else - (define i0 (unsafe-coords->index c w k x0 y)) - (define v0 (unsafe-flvector-ref vs i0)) - (define v1 (cond [(x0 . unsafe-fx= . w-1) 0.0] - [else (unsafe-flvector-ref vs (unsafe-fx+ i0 c))])) - (unsafe-fl-convex-combination v0 v1 (unsafe-fl- scaled-x floor-scaled-x))])))) - -(define (flomap-scale*-y/linear fm s new-h) - (match-define (flomap vs c w h) fm) - (define h-1 (unsafe-fx- h 1)) - (define cw (* c w)) - (unsafe-build-flomap - c w new-h - (λ (k x new-y) - (define orig-y (unsafe-fl+ (unsafe-fx->fl new-y) 0.5)) - (define scaled-y (unsafe-fl/ orig-y s)) - (define half-floor-y (unsafe-fl- (unsafe-flfloor (unsafe-fl+ scaled-y 0.5)) 0.5)) - (define y0 (unsafe-fl->fx (unsafe-flfloor half-floor-y))) - (cond [(or (y0 . unsafe-fx< . 0) (y0 . unsafe-fx>= . h)) 0.0] - [else - (define i0 (unsafe-coords->index c w k x y0)) - (define v0 (unsafe-flvector-ref vs i0)) - (define v1 (cond [(y0 . unsafe-fx= . h-1) 0.0] - [else (unsafe-flvector-ref vs (unsafe-fx+ i0 cw))])) - (unsafe-fl-convex-combination v0 v1 (unsafe-fl- scaled-y half-floor-y))])))) - -;; =================================================================================================== -;; Pinning and standard pin-derived combiners - -(define (flomap-pin fm1 x1 y1 fm2 x2 y2) - (cond - [(not (and (zero? x2) (zero? y2))) - (flomap-pin fm1 (- x1 x2) (- y1 y2) fm2 0 0)] - [else - (match-define (flomap argb1-vs 4 w1 h1) fm1) - (match-define (flomap argb2-vs 4 w2 h2) fm2) - - ;; fm1 and fm2 offsets, in final image coordinates - (define dx1 (inexact->exact (round (max 0 (- x1))))) - (define dy1 (inexact->exact (round (max 0 (- y1))))) - (define dx2 (inexact->exact (round (max 0 x1)))) - (define dy2 (inexact->exact (round (max 0 y1)))) - - ;; final image size - (define w (max (+ dx1 w1) (+ dx2 w2))) - (define h (max (+ dy1 h1) (+ dy2 h2))) - - (define-syntax-rule (get-argb-pixel argb-vs dx dy w h x y) - (let ([x (unsafe-fx- x dx)] - [y (unsafe-fx- y dy)]) - (cond [(and (x . unsafe-fx>= . 0) (x . unsafe-fx< . w) - (y . unsafe-fx>= . 0) (y . unsafe-fx< . h)) - (unsafe-flvector-4ref argb-vs (unsafe-coords->index 4 w 0 x y))] - [else - (values 0.0 0.0 0.0 0.0)]))) - - (define argb-vs (make-flvector (* 4 w h))) - (for* ([y (in-range h)] [x (in-range w)]) - (define-values (a1 r1 g1 b1) (get-argb-pixel argb1-vs dx1 dy1 w1 h1 x y)) - (define-values (a2 r2 g2 b2) (get-argb-pixel argb2-vs dx2 dy2 w2 h2 x y)) - (unsafe-flvector-4set! argb-vs (unsafe-coords->index 4 w 0 x y) - (unsafe-fl-alpha-blend a1 a2 a2) - (unsafe-fl-alpha-blend r1 r2 a2) - (unsafe-fl-alpha-blend g1 g2 a2) - (unsafe-fl-alpha-blend b1 b2 a2))) - - (flomap argb-vs 4 w h)])) - -(define (flomap-pin* x1-frac y1-frac x2-frac y2-frac fm . fms) - (for/fold ([fm1 fm]) ([fm2 (in-list fms)]) - (define-values (w1 h1) (flomap-size fm1)) - (define-values (w2 h2) (flomap-size fm2)) - (flomap-pin fm1 (* x1-frac w1) (* y1-frac h1) - fm2 (* x2-frac w2) (* y2-frac h2)))) - -(define (flomap-lt-superimpose fm . fms) - (apply flomap-pin* 0 0 0 0 fm fms)) - -(define (flomap-lc-superimpose fm . fms) - (apply flomap-pin* 0 1/2 0 1/2 fm fms)) - -(define (flomap-lb-superimpose fm . fms) - (apply flomap-pin* 0 1 0 1 fm fms)) - -(define (flomap-ct-superimpose fm . fms) - (apply flomap-pin* 1/2 0 1/2 0 fm fms)) - -(define (flomap-cc-superimpose fm . fms) - (apply flomap-pin* 1/2 1/2 1/2 1/2 fm fms)) - -(define (flomap-cb-superimpose fm . fms) - (apply flomap-pin* 1/2 1 1/2 1 fm fms)) - -(define (flomap-rt-superimpose fm . fms) - (apply flomap-pin* 1 0 1 0 fm fms)) - -(define (flomap-rc-superimpose fm . fms) - (apply flomap-pin* 1 1/2 1 1/2 fm fms)) - -(define (flomap-rb-superimpose fm . fms) - (apply flomap-pin* 1 1 1 1 fm fms)) - -(define (flomap-vl-append fm . fms) - (apply flomap-pin* 0 1 0 0 fm fms)) - -(define (flomap-vc-append fm . fms) - (apply flomap-pin* 1/2 1 1/2 0 fm fms)) - -(define (flomap-vr-append fm . fms) - (apply flomap-pin* 1 1 1 0 fm fms)) - -(define (flomap-ht-append fm . fms) - (apply flomap-pin* 1 0 0 0 fm fms)) - -(define (flomap-hc-append fm . fms) - (apply flomap-pin* 1 1/2 0 1/2 fm fms)) - -(define (flomap-hb-append fm . fms) - (apply flomap-pin* 1 1 0 1 fm fms)) - -;; =================================================================================================== -;; Transforms - -(define (flomap-flip-horizontal fm) - (match-define (flomap vs c w h) fm) - (define w-1 (- w 1)) - (unsafe-build-flomap - c w h - (λ (k x y) - (unsafe-flvector-ref vs (unsafe-coords->index c w k (unsafe-fx- w-1 x) y))))) - -(define (flomap-flip-vertical fm) - (match-define (flomap vs c w h) fm) - (define h-1 (- h 1)) - (unsafe-build-flomap - c w h - (λ (k x y) - (unsafe-flvector-ref vs (unsafe-coords->index c w k x (unsafe-fx- h-1 y)))))) - -(define (flomap-transpose fm) - (match-define (flomap vs c w h) fm) - (unsafe-build-flomap - c h w - (λ (k x y) - (unsafe-flvector-ref vs (unsafe-coords->index c w k y x))))) - -(define (flomap-cw-rotate fm) - (match-define (flomap vs c w h) fm) - (define h-1 (- h 1)) - (unsafe-build-flomap - c h w - (λ (k x y) - (unsafe-flvector-ref vs (unsafe-coords->index c w k (unsafe-fx- h-1 y) x))))) - -(define (flomap-ccw-rotate fm) - (match-define (flomap vs c w h) fm) - (define w-1 (- w 1)) - (unsafe-build-flomap - c h w - (λ (k x y) - (unsafe-flvector-ref vs (unsafe-coords->index c w k y (unsafe-fx- w-1 x)))))) - - -;; =================================================================================================== -;; Effects - -(define (colorize-alpha fm color) - (match-define (flomap _ 1 w h) fm) - (flomap-append-components fm (fm* fm (make-flomap/components w h color)))) - -(define (flomap-outline fm amt #:color [color #f]) - (match-define (flomap _ c w h) fm) - (define σ (* 0.5 (max 1.0 amt))) - (define ceiling-amt (inexact->exact (ceiling amt))) - (define test-size (* 2 (+ 1 ceiling-amt))) - (define test-mid (quotient test-size 2)) - (define test-fm (build-flomap 1 test-size test-size - (λ (k x y) (if (x . >= . test-mid) 1.0 0.0)))) - (define blur-fm (flomap-blur test-fm σ)) - (define v-max (flomap-bilinear-ref blur-fm 0 (+ 0.5 (- test-mid amt)) test-mid)) - (define v-min (flomap-bilinear-ref blur-fm 0 (+ 0.5 (- test-mid amt 1)) test-mid)) - (define alpha-fm (flomap-ref-component fm 0)) - (define new-alpha-fm (fmmax 0.0 (fmmin 1.0 (fm/ (fm- (flomap-blur alpha-fm σ) v-min) - (- v-max v-min))))) - (define color-vs (if (list? color) color (make-list (- c 1) 0.0))) - (colorize-alpha new-alpha-fm color-vs)) - -(define (flomap-outlined fm amt #:color [color #f]) - (flomap-cc-superimpose (flomap-outline fm amt #:color color) fm)) - -(define (flomap-shadow fm σ #:color [color #f]) - (match-define (flomap _ c w h) fm) - (cond [(c . = . 0) fm] - [else (define alpha-fm (flomap-ref-component fm 0)) - (define color-vs (if (list? color) color (make-list (- c 1) 0.0))) - (colorize-alpha (flomap-blur alpha-fm σ) color-vs)])) - -(define (flomap-shadowed fm σ #:color [color #f]) - (flomap-cc-superimpose (flomap-shadow fm σ #:color color) fm)) +#lang typed/racket/base + +(require "flomap-struct.rkt" + "flomap-stats.rkt" + "flomap-pointwise.rkt" + "flomap-transform.rkt" + "flomap-gradient.rkt" + "flomap-effects.rkt" + "flomap-blur.rkt" + "flomap-composite.rkt" + "flomap-resize.rkt") + +(require/typed + "draw-predicates.rkt" + [opaque Bitmap bitmap?] + [opaque DC dc?]) + +(require/typed + "flomap-convert.rkt" + [bitmap->flomap (Bitmap -> flomap)] + [flomap->bitmap (flomap -> Bitmap)] + [draw-flomap (Integer Integer (DC -> Any) -> flomap)]) + +(provide (all-from-out "flomap-struct.rkt" + "flomap-stats.rkt" + "flomap-pointwise.rkt" + "flomap-transform.rkt" + "flomap-gradient.rkt" + "flomap-effects.rkt" + "flomap-blur.rkt" + "flomap-composite.rkt" + "flomap-resize.rkt") + Bitmap DC + bitmap->flomap flomap->bitmap draw-flomap) diff --git a/collects/images/private/flonum.rkt b/collects/images/private/flonum.rkt new file mode 100644 index 0000000000..7396fcf080 --- /dev/null +++ b/collects/images/private/flonum.rkt @@ -0,0 +1,102 @@ +#lang typed/racket/base + +(require (for-syntax typed/racket/base) + racket/flonum + (except-in racket/fixnum fl->fx fx->fl) + racket/math + (except-in racket/unsafe/ops unsafe-flvector-ref unsafe-flvector-set!) + (prefix-in old- (only-in racket/unsafe/ops unsafe-flvector-ref unsafe-flvector-set!)) + ) + +(provide (all-defined-out)) + +(define-predicate nonnegative-fixnum? Nonnegative-Fixnum) + +(: unsafe-flvector-ref (FlVector Integer -> Flonum)) +(define unsafe-flvector-ref flvector-ref) + +(: unsafe-flvector-set! (FlVector Integer Flonum -> Void)) +(define unsafe-flvector-set! flvector-set!) + +(define-syntax-rule (fl->fx x) + (let ([i (fl->exact-integer x)]) + (with-asserts ([i fixnum?]) + i))) + +(define-syntax-rule (fx->fl i) + (->fl i)) + +(define-syntax-rule (flrational? x) + (let: ([x* : Flonum x]) + ;; if x = +nan.0, both tests return #f + (and (x . > . -inf.0) (x . < . +inf.0)))) + +(define-syntax-rule (fl-convex-combination dv sv sa) + (let: ([sa* : Flonum sa]) + (+ (fl* sv sa*) (fl* dv (- 1.0 sa*))))) + +(define-syntax-rule (fl-alpha-blend dca sca sa) + (+ sca (* dca (- 1.0 sa)))) + +(define-syntax-rule (flgaussian x s) + (let: ([x/s : Flonum (fl/ x s)]) + (/ (exp (* -0.5 (* x/s x/s))) + (fl* (sqrt (* 2.0 pi)) s)))) + +(define-syntax-rule (flsigmoid x) + (/ 1.0 (+ 1.0 (exp (fl- 0.0 x))))) + +(define-syntax-rule (inline-build-flvector size f) + (let: ([n : Integer size]) + (with-asserts ([n nonnegative-fixnum?]) + (let: ([vs : FlVector (make-flvector n)]) + (let: loop : FlVector ([i : Nonnegative-Fixnum 0]) + (cond [(i . fx< . n) (old-unsafe-flvector-set! vs i (f i)) + (loop (unsafe-fx+ i 1))] + [else vs])))))) + +;; =================================================================================================== +;; 3-vectors + +(define-syntax-rule (fl3dot x1 y1 z1 x2 y2 z2) + (+ (fl* x1 x2) (fl* y1 y2) (fl* z1 z2))) + +(define-syntax (fl3* stx) + (syntax-case stx () + [(_ x y z c) + (syntax/loc stx + (let: ([c* : Flonum c]) + (values (fl* x c*) (fl* y c*) (fl* z c*))))] + [(_ x1 y1 z1 x2 y2 z2) + (syntax/loc stx + (values (fl* x1 x2) (fl* y1 y2) (fl* z1 z2)))])) + +(define-syntax-rule (fl3+ x1 y1 z1 x2 y2 z2) + (values (fl+ x1 x2) (fl+ y1 y2) (fl+ z1 z2))) + +(define-syntax (fl3- stx) + (syntax-case stx () + [(_ x y z) + (syntax/loc stx + (values (fl- 0.0 x) (fl- 0.0 y) (fl- 0.0 z)))] + [(_ x1 y1 z1 x2 y2 z2) + (syntax/loc stx + (values (fl- x1 x2) (fl- y1 y2) (fl- z1 z2)))])) + +(define-syntax-rule (fl3mag^2 x y z) + (let: ([x* : Flonum x] [y* : Flonum y] [z* : Flonum z]) + (+ (* x* x*) (* y* y*) (* z* z*)))) + +(define-syntax-rule (fl3mag x y z) + (flsqrt (fl3mag^2 x y z))) + +(define-syntax-rule (fl3dist x1 y1 z1 x2 y2 z2) + (fl3mag (fl- x1 x2) (fl- y1 y2) (fl- z1 z2))) + +(define-syntax-rule (fl3normalize x y z) + (let: ([x* : Flonum x] [y* : Flonum y] [z* : Flonum z]) + (let: ([d : Flonum (fl3mag x* y* z*)]) + (values (/ x* d) (/ y* d) (/ z* d))))) + +(define-syntax-rule (fl3-half-norm x1 y1 z1 x2 y2 z2) + (fl3normalize (fl+ x1 x2) (fl+ y1 y2) (fl+ z1 z2))) diff --git a/collects/images/private/renderfx.rkt b/collects/images/private/renderfx.rkt deleted file mode 100644 index 3980695d8b..0000000000 --- a/collects/images/private/renderfx.rkt +++ /dev/null @@ -1,640 +0,0 @@ -#lang racket/base - -(require racket/match racket/math racket/provide unstable/parameter-group racket/flonum - "unsafe.rkt" - "flomap.rkt" - "deep-flomap.rkt") - -(provide - ;; lighting parameters - light-direction - light-intensity - ambient-intensity - reflected-intensity - deep-flomap-lighting - (struct-out deep-flomap-lighting-value) - ;; material parameters - refractive-indexes - ->refractive-index - refractive-index - ideal-reflectance - ideal-transmission - transmission-density - specular-reflectance - specular-roughness - specular-purity - diffuse-reflectance - ambient-reflectance - ambient-transmission - shadow-blur - deep-flomap-material - (struct-out deep-flomap-material-value) - (matching-identifiers-out #rx".*-material" (all-defined-out)) - ;; ray tracing functions - deep-flomap-render - ) - -;; =================================================================================================== -;; Rendering parameters - -;; Hacks -(define specular-blur 1/2) -(define diffuse-blur 1/2) -(define ideal-transmission-blur 1) -(define ambient-transmission-blur-fraction 1/32) - -(define refractive-indexes - #hash((diamond . 2.42) - (cubic-zirconia . 2.15) - (ruby . 1.76) - (enamel . 1.63) - (glass . 1.54) - (wax . 1.43) - (water . 1.33) - (vacuum . 1.0))) - -(define (->refractive-index idx) - (cond [(symbol? idx) - (hash-ref refractive-indexes idx - (λ () (error 'refractive-index - "`refractive-indexes' does not have a refractive index for ~e" - idx)))] - [(rational? idx) (exact->inexact idx)])) - -(define (list-exact->inexact vs) - (map exact->inexact vs)) - -;; light parameters -(define light-direction (make-parameter '(0.0 -1.0 1.0) list-exact->inexact)) -(define light-intensity (make-parameter '(1.0 1.0 1.0) list-exact->inexact)) -(define ambient-intensity (make-parameter '(1.0 1.0 1.0) list-exact->inexact)) -(define reflected-intensity (make-parameter '(1.0 1.0 1.0) list-exact->inexact)) - -(define-parameter-group deep-flomap-lighting - (light-direction light-intensity ambient-intensity reflected-intensity)) - -;; material parameters -(define refractive-index (make-parameter (->refractive-index 'glass) ->refractive-index)) -(define ideal-reflectance (make-parameter 1.0 exact->inexact)) -(define ideal-transmission (make-parameter 1.0 exact->inexact)) -(define transmission-density (make-parameter 0.65 exact->inexact)) -(define specular-reflectance (make-parameter 0.15 exact->inexact)) -(define specular-roughness (make-parameter 0.15 exact->inexact)) -(define specular-purity (make-parameter 1.0 exact->inexact)) -(define diffuse-reflectance (make-parameter 0.25 exact->inexact)) -(define ambient-reflectance (make-parameter 0.1 exact->inexact)) -(define ambient-transmission (make-parameter 0.7 exact->inexact)) -(define shadow-blur (make-parameter 0.02 exact->inexact)) - -(define-parameter-group deep-flomap-material - (refractive-index ideal-reflectance ideal-transmission transmission-density - specular-reflectance specular-roughness specular-purity - diffuse-reflectance ambient-reflectance ambient-transmission - shadow-blur)) - -(define matte-material - (deep-flomap-material-value - 'vacuum 0.0 0.0 1.0 - 0.0 1.0 1.0 - 1.0 0.25 0.0 - 0.0)) - -(define dull-plastic-material - (deep-flomap-material-value - 'glass 0.0 0.0 1.0 - 1.0 0.25 1.0 - 1.0 0.25 0.0 - 0.0)) - -(define wax-material - (deep-flomap-material-value - 'wax 1.0 0.5 1.25 - 0.5 0.5 0.5 - 0.5 0.5 0.5 - 0.04)) - -(define plastic-material - (deep-flomap-material-value - 'glass 0.375 1.0 2.0 - 0.25 0.15 1.0 - 0.6 0.5 0.1 - 0.03)) - -(define metal-material - (deep-flomap-material-value - 3.0 0.3 0.0 1.0 - 0.8 0.1 0.2 - 0.2 0.8 0.0 - 0.0)) - -(define porcelain-material - (deep-flomap-material-value - 'enamel 0.9 0.5 1.5 - 0.4 0.2 1.0 - 0.5 0.5 0.5 - 0.04)) - -(define frosted-glass-material - (deep-flomap-material-value - 'glass 0.9 1.0 0.8 - 0.4 0.2 1.0 - 0.5 0.1 0.5 - 0.04)) - -(define glass-material - (deep-flomap-material-value - 'glass 1.0 1.0 0.65 - 0.15 0.15 1.0 - 0.25 0.1 0.7 - 0.02)) - -(define diamond-material - (deep-flomap-material-value - 'diamond 1.0 1.0 0.5 - 0.15 0.15 1.0 - 0.15 0.1 0.7 - 0.02)) - -;; =================================================================================================== -;; Ray tracing ops - -;; assumes direction to viewer is 0.0 0.0 1.0 (i.e. viewer above at infinity) -(define (unsafe-reflect-view-ray nx ny nz) - (values (unsafe-fl* 2.0 (unsafe-fl* nz nx)) - (unsafe-fl* 2.0 (unsafe-fl* nz ny)) - (unsafe-fl- (unsafe-fl* 2.0 (unsafe-fl* nz nz)) 1.0))) - -(define (unsafe-transmission-intensity cos-i η1 η2) - ;; Fresnel's equation - (define n1/n2 (unsafe-fl/ η1 η2)) - (define cos^2-i (unsafe-fl* cos-i cos-i)) - (define sin^2-t (unsafe-fl* (unsafe-fl* n1/n2 n1/n2) (unsafe-fl- 1.0 cos^2-i))) - (define cos-t (unsafe-flsqrt (unsafe-fl- 1.0 sin^2-t))) - (define n1-cos-i (unsafe-fl* η1 cos-i)) - (define n2-cos-t (unsafe-fl* η2 cos-t)) - (define n1-cos-t (unsafe-fl* η1 cos-t)) - (define n2-cos-i (unsafe-fl* η2 cos-i)) - (define perp (unsafe-fl/ (unsafe-fl- n1-cos-i n2-cos-t) - (unsafe-fl+ n1-cos-i n2-cos-t))) - (define parl (unsafe-fl/ (unsafe-fl- n2-cos-i n1-cos-t) - (unsafe-fl+ n2-cos-i n1-cos-t))) - (unsafe-fl- 1.0 (unsafe-fl* 0.5 (unsafe-fl+ (unsafe-fl* perp perp) (unsafe-fl* parl parl))))) - -(define (unsafe-transmitted-vector nx ny nz ix iy iz η1 η2) - (define η1/η2 (unsafe-fl/ η1 η2)) - (define cos-i (unsafe-flneg (unsafe-fl3dot nx ny nz ix iy iz))) - (define cos^2-i (unsafe-fl* cos-i cos-i)) - (define sin^2-t (unsafe-fl* (unsafe-fl* η1/η2 η1/η2) (unsafe-fl- 1.0 cos^2-i))) - (define c (unsafe-fl- (unsafe-fl* η1/η2 cos-i) (unsafe-flsqrt (unsafe-fl- 1.0 sin^2-t)))) - (define-values (tx1 ty1 tz1) (unsafe-fl3* ix iy iz η1/η2)) - (define-values (tx2 ty2 tz2) (unsafe-fl3* nx ny nz c)) - (unsafe-fl3+ tx1 ty1 tz1 tx2 ty2 tz2)) - -(define-syntax-rule (unsafe-transmit opacity dist) - (let* ([o (unsafe-fl+ (unsafe-fl* opacity 0.99) 0.005)]) - (cond [(unsafe-fl= 0.0 o) 0.0] - [else (unsafe-flexp (unsafe-flproduct (unsafe-fllog o) dist))]))) - -(define-syntax-rule (unsafe-beckmann-distribution n-dot-h surface-roughness) - (let ([cos-θ n-dot-h] - [m surface-roughness]) - (define x (unsafe-fl/ (unsafe-fltan (unsafe-flacos cos-θ)) m)) - (define m*cos^2-θ (unsafe-flproduct m cos-θ cos-θ)) - (unsafe-fl/ (unsafe-flexp (unsafe-flneg (unsafe-fl* x x))) - (unsafe-flproduct pi m*cos^2-θ m*cos^2-θ)))) - -;; =================================================================================================== -;; Pass 1: tracing from a directional light source - -(define (trace-directional-light alpha-fm rgb-fm z-fm normal-fm) - (match-define (flomap alpha-vs 1 w h) alpha-fm) - (match-define (list rgb-vs z-vs normal-vs) (map flomap-values (list rgb-fm z-fm normal-fm))) - - (define z-max (flomap-max-value z-fm)) - (define opacity-z (/ z-max (transmission-density))) - ;; max coordinates of the shadow image - (define sx-max (- w 1.0)) - (define sy-max (- h 1.0)) - ;; vector pointing toward light source, incident vector, and light color - (define-values (lx ly lz) (match-let ([(list lx ly lz) (light-direction)]) - (unsafe-fl3normalize lx ly lz))) - (define-values (ix iy iz) (unsafe-fl3neg lx ly lz)) - (match-define (list lr lg lb) (light-intensity)) - ;; view and "half" directions - (define-values (hx hy hz) (unsafe-fl3-half-norm lx ly lz 0.0 0.0 1.0)) - ;; material properties - (define η2 (exact->inexact (refractive-index))) - (define η1/η2 (/ 1.0 η2)) - ;; proportion of diffracted reflection - (define 0.5*v-dot-h (* 0.5 hz)) - (define Ra (ambient-reflectance)) - (define Ta (ambient-transmission)) - (define Rd (diffuse-reflectance)) - (define Rs (specular-reflectance)) - (define Ti (ideal-transmission)) - (define roughness (specular-roughness)) - (define purity (specular-purity)) - - (match-define (list ar ag ab) (ambient-intensity)) - (define-values (Tar Tag Tab) (unsafe-fl3* ar ag ab Ta)) - (define-values (Rar Rag Rab) (unsafe-fl3* ar ag ab Ra)) - - (define intensity-fm (make-flomap 3 w h)) - (define intensity-vs (flomap-values intensity-fm)) - (define specular-fm (make-flomap 1 w h)) - (define specular-vs (flomap-values specular-fm)) - (define diffuse-fm (make-flomap 3 w h lz)) - (define diffuse-vs (flomap-values diffuse-fm)) - - (define sx-vs (make-flvector (* w h) +nan.0)) - (define sy-vs (make-flvector (* w h) +nan.0)) - (define Irgb-vs (make-flvector (* 3 w h))) - - (for* ([int-y (in-range h)] [int-x (in-range w)]) - (define i (unsafe-fx+ int-x (unsafe-fx* int-y w))) - (define a (unsafe-flvector-ref alpha-vs i)) - (when (a . unsafe-fl> . 0.0) - (define j (unsafe-fx* 3 i)) - ;; altitude and surface normal - (define z (unsafe-flvector-ref z-vs i)) - (define-values (nx ny nz) (unsafe-flvector-3ref normal-vs j)) - ;; cosine of angle between light and surface normal - (define n-dot-l (unsafe-fl3dot nx ny nz lx ly lz)) - ;; intensity of incident light (Lambert's cosine law) - (define-values (Ilr Ilg Ilb) (unsafe-fl3* lr lg lb n-dot-l)) - (unsafe-flvector-3set! intensity-vs j Ilr Ilg Ilb) - ;; diffraction intensity due to specular, diffuse and ambient reflection - (cond - [(n-dot-l . unsafe-fl> . 0.0) ; does the microfacet face the light? - (define Is - (cond - #;; just Beckmann's distribution - [(Rs . unsafe-fl> . 0.0) - (define n-dot-h (unsafe-fl3dot nx ny nz hx hy hz)) - (unsafe-fl* Rs (unsafe-beckmann-distribution n-dot-h roughness))] - ;; Cook-Torrance specular reflection intensity - [(Rs . unsafe-fl> . 0.0) - (define n-dot-h (unsafe-fl3dot nx ny nz hx hy hz)) - (define n-dot-v nz) - ;; geometrical attenuation factor (has something to do with local reflections) - (define G (unsafe-flmin - 1.0 (unsafe-flmin (unsafe-fl/ (unsafe-fl* n-dot-h n-dot-v) 0.5*v-dot-h) - (unsafe-fl/ (unsafe-fl* n-dot-h n-dot-l) 0.5*v-dot-h)))) - ;; scatter distribution - (define D (unsafe-beckmann-distribution n-dot-h roughness)) - ;; Fresnel term - (define F (unsafe-fl- 1.0 (unsafe-transmission-intensity n-dot-l 1.0 η2))) - (unsafe-flproduct Rs F (unsafe-fl/ D n-dot-l) (unsafe-fl/ G n-dot-v))] - [else 0.0])) - (unsafe-flvector-set! specular-vs i Is) - - (let*-values ([(Idr Idg Idb) (unsafe-fl3* Ilr Ilg Ilb Rd)] - [(Idr Idg Idb) (unsafe-fl3+ Idr Idg Idb Rar Rag Rab)]) - (unsafe-flvector-3set! diffuse-vs j Idr Idg Idb))] - [else - (unsafe-flvector-3set! diffuse-vs j Rar Rag Rab)]) - - (when (and (Ti . unsafe-fl> . 0.0) (n-dot-l . unsafe-fl> . 0.0)) - ;; ideal transmission vector - (define-values (tx ty tz) (unsafe-transmitted-vector nx ny nz ix iy iz 1.0 η2)) - ;; sz = z + dist * tz, so dist = (sz - z) / tz - (define dist (unsafe-fl/ (unsafe-fl- 0.0 z) tz)) - (when (and (dist . unsafe-fl>= . 0.0) (dist . unsafe-fl< . +inf.0)) - ;; transmitted ray intersects with shadow plane at sx sy 0.0 - (define sx (unsafe-flsum 0.5 (unsafe-fx->fl int-x) (unsafe-fl* dist tx))) - (define sy (unsafe-flsum 0.5 (unsafe-fx->fl int-y) (unsafe-fl* dist ty))) - ;; actual transmission proportion (Fresnel's law) - (define T (unsafe-fl* Ti (unsafe-transmission-intensity n-dot-l 1.0 η2))) - ;; intensity of incident light (Lambert's cosine law) - (define-values (Ilr Ilg Ilb) (unsafe-fl3* lr lg lb n-dot-l)) - ;; normalized distance to the surface - (define norm-dist (unsafe-fl/ dist opacity-z)) - ;; intensity of the light that strikes the surface - (define-values (r g b) (unsafe-flvector-3ref rgb-vs j)) - (define-values (Ir Ig Ib) - ;; unsafe-transmit calculates intensity using color as absorption rate - (values (unsafe-flproduct T Ilr (unsafe-transmit r norm-dist)) - (unsafe-flproduct T Ilg (unsafe-transmit g norm-dist)) - (unsafe-flproduct T Ilb (unsafe-transmit b norm-dist)))) - (unsafe-flvector-set! sx-vs i sx) - (unsafe-flvector-set! sy-vs i sy) - (unsafe-flvector-3set! Irgb-vs j Ir Ig Ib))))) - - (define diffracted-fm (fm+ (fm* rgb-fm (flomap-blur diffuse-fm diffuse-blur)) - (fm* (flomap-blur specular-fm specular-blur) - (fm+ (fm* (- 1.0 purity) rgb-fm) - (fm* purity intensity-fm))))) - - ;; approximate ambient transmission by casting light downward with no refraction, then blurring - (define ambient-shadow-fm (make-flomap 3 w h)) - (define ambient-shadow-vs (flomap-values ambient-shadow-fm)) - (when (Ta . unsafe-fl> . 0.0) - (for* ([int-y (in-range h)] [int-x (in-range w)]) - (define i (unsafe-fx+ int-x (unsafe-fx* int-y w))) - (define a (unsafe-flvector-ref alpha-vs i)) - (when (a . unsafe-fl> . 0.0) - (define z (unsafe-flvector-ref z-vs i)) - (define j (unsafe-fx* 3 i)) - (define-values (r g b) (unsafe-flvector-3ref rgb-vs j)) - (define norm-dist (unsafe-fl/ z opacity-z)) - (define-values (Ir Ig Ib) - ;; note: unsafe-transmit converts colors to absorption rates - (values (unsafe-fl* Tar (unsafe-transmit r norm-dist)) - (unsafe-fl* Tag (unsafe-transmit g norm-dist)) - (unsafe-fl* Tab (unsafe-transmit b norm-dist)))) - (unsafe-flvector-3set! ambient-shadow-vs j Ir Ig Ib)))) - - ;; cast approximate shadow volumes - (define shadow-fm (flomap-blur ambient-shadow-fm (* ambient-transmission-blur-fraction (min w h)))) - (define shadow-vs (flomap-values shadow-fm)) - (when (Ti . unsafe-fl> . 0.0) - ;; Gaussian kernels - make as wide as possible to keep from having to reallocate - (define kxs (make-flvector w)) - (define kys (make-flvector h)) - (for* ([int-y (in-range (- h 1))] [int-x (in-range (- w 1))]) - (define i00 (unsafe-fx+ int-x (unsafe-fx* int-y w))) - (define i01 (unsafe-fx+ i00 1)) - (define i10 (unsafe-fx+ i00 w)) - (define i11 (unsafe-fx+ i10 1)) - (define sx00 (unsafe-flvector-ref sx-vs i00)) - (define sx01 (unsafe-flvector-ref sx-vs i01)) - (define sx10 (unsafe-flvector-ref sx-vs i10)) - (define sx11 (unsafe-flvector-ref sx-vs i11)) - (when (and (unsafe-flrational? sx00) (unsafe-flrational? sx01) - (unsafe-flrational? sx10) (unsafe-flrational? sx11)) - (define sy00 (unsafe-flvector-ref sy-vs i00)) - (define sy01 (unsafe-flvector-ref sy-vs i01)) - (define sy10 (unsafe-flvector-ref sy-vs i10)) - (define sy11 (unsafe-flvector-ref sy-vs i11)) - (define sx-min (unsafe-flmin* sx00 sx01 sx10 sx11)) - (define sy-min (unsafe-flmin* sy00 sy01 sy10 sy11)) - (define sx-max (unsafe-flmax* sx00 sx01 sx10 sx11)) - (define sy-max (unsafe-flmax* sy00 sy01 sy10 sy11)) - - (define sx-mid (unsafe-fl* 0.25 (unsafe-flsum sx00 sx01 sx10 sx11))) - (define sy-mid (unsafe-fl* 0.25 (unsafe-flsum sy00 sy01 sy10 sy11))) - (define sx-mid^2 (unsafe-fl* 0.25 (unsafe-flsum (unsafe-flsqr sx00) (unsafe-flsqr sx01) - (unsafe-flsqr sx10) (unsafe-flsqr sx11)))) - (define sy-mid^2 (unsafe-fl* 0.25 (unsafe-flsum (unsafe-flsqr sy00) (unsafe-flsqr sy01) - (unsafe-flsqr sy10) (unsafe-flsqr sy11)))) - (define sx-stddev (unsafe-flsqrt (unsafe-fl- sx-mid^2 (unsafe-flsqr sx-mid)))) - (define sy-stddev (unsafe-flsqrt (unsafe-fl- sy-mid^2 (unsafe-flsqr sy-mid)))) - (define x-min (unsafe-fxmax 0 (unsafe-fl->fx (unsafe-flfloor sx-min)))) - (define x-max (unsafe-fxmin w (unsafe-fx+ 1 (unsafe-fl->fx (unsafe-flfloor sx-max))))) - (define y-min (unsafe-fxmax 0 (unsafe-fl->fx (unsafe-flfloor sy-min)))) - (define y-max (unsafe-fxmin h (unsafe-fx+ 1 (unsafe-fl->fx (unsafe-flfloor sy-max))))) - (define x-size (unsafe-fx- x-max x-min)) - (define y-size (unsafe-fx- y-max y-min)) - (when (and (x-size . unsafe-fx> . 0) (y-size . unsafe-fx> . 0)) - ;; average the color - (define-values (r00 g00 b00) (unsafe-flvector-3ref Irgb-vs (unsafe-fx* 3 i00))) - (define-values (r01 g01 b01) (unsafe-flvector-3ref Irgb-vs (unsafe-fx* 3 i01))) - (define-values (r10 g10 b10) (unsafe-flvector-3ref Irgb-vs (unsafe-fx* 3 i10))) - (define-values (r11 g11 b11) (unsafe-flvector-3ref Irgb-vs (unsafe-fx* 3 i11))) - (define r (unsafe-fl* 0.25 (unsafe-flsum r00 r01 r10 r11))) - (define g (unsafe-fl* 0.25 (unsafe-flsum g00 g01 g10 g11))) - (define b (unsafe-fl* 0.25 (unsafe-flsum b00 b01 b10 b11))) - ;; precalculate the Gaussian kernel for the x direction - (for ([dx (in-range x-size)]) - (define x (unsafe-fx+ dx x-min)) - (define d (unsafe-fl/ (unsafe-fl- (unsafe-fl+ 0.5 (unsafe-fx->fl x)) sx-mid) sx-stddev)) - (define kx (unsafe-flexp (unsafe-fl* -0.5 (unsafe-fl* d d)))) - (unsafe-flvector-set! kxs dx kx)) - ;; precalculate the Gaussian kernel for the y direction - ;; this shouldn't help because it's used only once per y iteration, but it reduces allocs - ;; within the loop (unsafe-flexp has no bytecode op yet, so its args and return are boxed) - (for ([dy (in-range y-size)]) - (define y (unsafe-fx+ dy y-min)) - (define d (unsafe-fl/ (unsafe-fl- (unsafe-fl+ 0.5 (unsafe-fx->fl y)) sy-mid) sy-stddev)) - (define ky (unsafe-flexp (unsafe-fl* -0.5 (unsafe-fl* d d)))) - (unsafe-flvector-set! kys dy ky)) - ;; normalization constant for a 2D Gaussian kernel - (define c (unsafe-flproduct 2.0 pi sx-stddev sy-stddev)) - ;; cast the approximate shadow volume - ;; this loop doesn't use the nice unsafe-fl3 macros or define-values, which (currently) - ;; makes it about 2x faster - (let y-loop ([dy 0]) - (when (dy . unsafe-fx< . y-size) - (define ky (unsafe-flvector-ref kys dy)) - (cond [(ky . unsafe-fl> . 0.1) - (define a (unsafe-fl/ ky c)) - (define Ir (unsafe-fl* r a)) - (define Ig (unsafe-fl* g a)) - (define Ib (unsafe-fl* b a)) - (define i (unsafe-fx* 3 (unsafe-fx+ x-min (unsafe-fx* (unsafe-fx+ dy y-min) w)))) - (let x-loop ([dx 0] [i i]) - (cond [(dx . unsafe-fx< . x-size) - (define kx (unsafe-flvector-ref kxs dx)) - (when (kx . unsafe-fl> . 0.1) - (unsafe-flvector-set! - shadow-vs i (unsafe-fl+ (unsafe-fl* Ir kx) - (unsafe-flvector-ref shadow-vs i))) - (define i1 (unsafe-fx+ i 1)) - (unsafe-flvector-set! - shadow-vs i1 (unsafe-fl+ (unsafe-fl* Ig kx) - (unsafe-flvector-ref shadow-vs i1))) - (define i2 (unsafe-fx+ i 2)) - (unsafe-flvector-set! - shadow-vs i2 (unsafe-fl+ (unsafe-fl* Ib kx) - (unsafe-flvector-ref shadow-vs i2)))) - (x-loop (unsafe-fx+ 1 dx) (unsafe-fx+ 3 i))] - [else - (y-loop (unsafe-fx+ 1 dy))]))] - [else - (y-loop (unsafe-fx+ 1 dy))])))) - ))) - - ;; blur the shadow a bit to make up for approximating it with Gaussians - (values diffracted-fm (flomap-box-blur shadow-fm 1))) - -;; =================================================================================================== -;; Pass 2: tracing from a directional viewer - -(define (trace-directional-view alpha-fm rgb-fm z-fm normal-fm shadow-fm) - (match-define (flomap alpha-vs 1 w h) alpha-fm) - (match-define (list rgb-vs z-vs normal-vs shadow-vs) - (map flomap-values (list rgb-fm z-fm normal-fm shadow-fm))) - - (define w-1 (unsafe-fx- w 1)) - (define h-1 (unsafe-fx- h 1)) - (define x-size (exact->inexact w)) - (define y-size (exact->inexact h)) - (define z-size (flomap-max-value z-fm)) - (define x-mid (* 0.5 x-size)) - (define y-mid (* 0.5 y-size)) - (define opacity-z (/ z-size (transmission-density))) - - ;; reflected wall is tilted a bit toward the viewer - (define wall-tilt-θ (* 1/8 pi)) - (define cos-wall-tilt-θ (cos wall-tilt-θ)) - (define sin-wall-tilt-θ (sin wall-tilt-θ)) - (match-define (list Irr Irg Irb) (reflected-intensity)) - - ;; max coords of the shadow image - ;; subtract epsilon to ensure that sx < (w - 1) so that (flfloor sx) < (w - 1) (similarly for sy) - (define sx-max (- w 1.00001)) - (define sy-max (- h 1.00001)) - ;; material properties - (define η2 (exact->inexact (refractive-index))) - (define η1/η2 (/ 1.0 η2)) - (define Ri (ideal-reflectance)) - (define Ti (ideal-transmission)) - - (define reflected-fm (make-flomap 3 w h)) - (define reflected-vs (flomap-values reflected-fm)) - (define transmitted-fm (make-flomap 3 w h)) - (define transmitted-vs (flomap-values transmitted-fm)) - - (when (or (Ri . unsafe-fl> . 0.0) (Ti . unsafe-fl> . 0.0)) - (for* ([int-y (in-range h)] [int-x (in-range w)]) - (define i (unsafe-fx+ int-x (unsafe-fx* int-y w))) - (define a (unsafe-flvector-ref alpha-vs i)) - (when (a . unsafe-fl> . 0.0) - (define j (unsafe-fx* 3 i)) - ;; surface normal - (define-values (nx ny nz) (unsafe-flvector-3ref normal-vs j)) - ;; cosine of angle between viewer and surface normal - ;; with gradient inferred from z flomap, this is always > 0.0 - (define cos-i nz) - ;; transmitted intensity - (define orig-T (unsafe-transmission-intensity cos-i 1.0 η2)) - (define T (unsafe-fl* Ti orig-T)) - (define R (unsafe-fl* Ri (unsafe-fl- 1.0 orig-T))) - ;; surface coordinates - (define x (unsafe-fl+ 0.5 (unsafe-fx->fl int-x))) - (define y (unsafe-fl+ 0.5 (unsafe-fx->fl int-y))) - (define z (unsafe-flvector-ref z-vs i)) - - ;; reflection - (when (and (Ri . unsafe-fl> . 0.0) - (int-x . unsafe-fx> . 0) (int-x . unsafe-fx< . w-1) - (int-y . unsafe-fx> . 0) (int-y . unsafe-fx< . h-1)) - (define-values (rx ry rz) (unsafe-reflect-view-ray nx ny nz)) - ;; tilt the wall a little so flat surfaces reflect something - (define ry* (- (* ry cos-wall-tilt-θ) (* rz sin-wall-tilt-θ))) - ;(define rz* (+ (* ry sin-wall-tilt-θ) (* rz cos-wall-tilt-θ))) - ;; distance to the wall - (define rdist (unsafe-fl/ (unsafe-fl- (- z-size) y) ry*)) - (define sx (unsafe-fl+ x (unsafe-fl* rx rdist))) - (define sy (unsafe-fl+ y (unsafe-fl* ry rdist))) - (define sz (unsafe-fl+ z (unsafe-fl* rz rdist))) - (when (rdist . unsafe-fl>= . 0.0) - (define cdist (unsafe-fl3dist sx sy sz x-mid y-mid 0.0)) - (define v (unsafe-flsigmoid (unsafe-fl* 0.25 (unsafe-fl- (* 4.5 z-size) cdist)))) - (let-values ([(r g b) (unsafe-fl3* Irr Irg Irb (* R v))]) - (unsafe-flvector-3set! reflected-vs j r g b)))) - - ;; transmission (refraction) - (when (Ti . unsafe-fl> . 0.0) - (define-values (tx ty tz) (unsafe-transmitted-vector nx ny nz 0.0 0.0 -1.0 1.0 η2)) - ;; sz = z + dist * tz, so dist = (sz - z) / tz - (define dist (unsafe-fl/ (unsafe-fl- 0.0 z) tz)) - (when (and (dist . unsafe-fl>= . 0.0) (dist . unsafe-fl< . +inf.0)) - ;; Find the color of the point on the shadow that the ray struck - (define sx (unsafe-flmax 0.0 (unsafe-flmin sx-max (unsafe-fl+ x (unsafe-fl* dist tx))))) - (define sy (unsafe-flmax 0.0 (unsafe-flmin sy-max (unsafe-fl+ y (unsafe-fl* dist ty))))) - (define floor-sx (unsafe-flfloor sx)) - (define floor-sy (unsafe-flfloor sy)) - (define bx (unsafe-fl->fx floor-sx)) - (define by (unsafe-fl->fx floor-sy)) - ;; Bilinearly interpolate the four colors nearest the point on the shadow - (define 1-αx (unsafe-fl- sx floor-sx)) - (define 1-αy (unsafe-fl- sy floor-sy)) - (define αx (unsafe-fl- 1.0 1-αx)) - (define αy (unsafe-fl- 1.0 1-αy)) - ;; upper-left weighted values - (define j1 (unsafe-fx* 3 (unsafe-fx+ bx (unsafe-fx* by w)))) - (define-values (r1 g1 b1) (unsafe-flvector-3ref shadow-vs j1)) - (define-values (sr1 sg1 sb1) (unsafe-fl3* r1 g1 b1 (unsafe-fl* αx αy))) - ;; upper-right weighted values - (define j2 (unsafe-fx+ j1 3)) - (define-values (r2 g2 b2) (unsafe-flvector-3ref shadow-vs j2)) - (define-values (sr2 sg2 sb2) (unsafe-fl3* r2 g2 b2 (unsafe-fl* 1-αx αy))) - ;; lower-left weighted values - (define j3 (unsafe-fx+ j1 (unsafe-fx* 3 w))) - (define-values (r3 g3 b3) (unsafe-flvector-3ref shadow-vs j3)) - (define-values (sr3 sg3 sb3) (unsafe-fl3* r3 g3 b3 (unsafe-fl* αx 1-αy))) - ;; lower-right weighted values - (define j4 (unsafe-fx+ j3 3)) - (define-values (r4 g4 b4) (unsafe-flvector-3ref shadow-vs j4)) - (define-values (sr4 sg4 sb4) (unsafe-fl3* r4 g4 b4 (unsafe-fl* 1-αx 1-αy))) - ;; final interpolated shadow color - (define-values (sr sg sb) - (values (unsafe-flsum sr1 sr2 sr3 sr4) - (unsafe-flsum sg1 sg2 sg3 sg4) - (unsafe-flsum sb1 sb2 sb3 sb4))) - ;; normalized distance to the surface - (define norm-dist (unsafe-fl/ dist opacity-z)) - ;; intensities of each r g b by the time the light emerges from the surface - (define-values (r g b) - ;; colors represent absorption rates - (let-values ([(r g b) (unsafe-flvector-3ref rgb-vs j)]) - (values (unsafe-flproduct T sr (unsafe-transmit r norm-dist)) - (unsafe-flproduct T sg (unsafe-transmit g norm-dist)) - (unsafe-flproduct T sb (unsafe-transmit b norm-dist))))) - (unsafe-flvector-3set! transmitted-vs j r g b)))))) - - ;; blur to cut down on sparklies (poor man's supersampling) - (values reflected-fm - (flomap-blur transmitted-fm ideal-transmission-blur))) - -;; =================================================================================================== -;; Full rendering - -(define (prep-background fm w h) - (let loop ([fm (flomap-cc-crop fm w h)]) - (case (flomap-components fm) - [(0) #f] - [(1) (flomap-append-components fm fm fm)] - [(2) (define value-fm (flomap-ref-component fm 1)) - (loop (flomap-append-components fm value-fm value-fm))] - [(3) fm] - [(4) (flomap-drop-components (flomap-cc-superimpose (make-flomap 4 w h 1.0) fm) 1)] - [else (raise-type-error 'deep-flomap-render "flomap with 0, 1, 2, 3 or 4 components" fm)]))) - -(define (deep-flomap-render dfm [background-fm #f]) - (define-values (w h) (deep-flomap-size dfm)) - (define argb-fm (flomap-divide-alpha (deep-flomap-argb dfm))) - (define alpha-fm (flomap-ref-component argb-fm 0)) - (define rgb-fm (flomap-drop-components argb-fm 1)) - (define z-fm (fmmax 0.0 (deep-flomap-z dfm))) - (define normal-fm (flomap-gradient-normal z-fm)) - ;(printf "~v~n" (flomap->bitmap (fm* 0.5 (fm+ 1.0 normal-fm)))) - (define bg-fm (if background-fm (prep-background background-fm) #f)) - - ;; pass 1: trace from the light source - (define-values (diffracted-fm raw-shadow-fm) - (trace-directional-light alpha-fm rgb-fm z-fm normal-fm)) - #; - (printf "diffracted: ~v~nraw shadow: ~v~n" - (flomap->bitmap diffracted-fm #;(flomap-normalize diffracted-fm)) - (flomap->bitmap raw-shadow-fm #;(flomap-normalize raw-shadow-fm))) - - ;; blur the shadow to simulate internal scatter - (define σ (* (min w h) (shadow-blur))) - (define shadow-fm - (cond [bg-fm - ;; two Gaussian blurs by half-σ is equivalent to one Gaussian blur by σ - (define half-σ (* (/ 1 (sqrt 2)) σ)) - (let* ([fm (flomap-blur raw-shadow-fm half-σ)] - [fm (fm* fm bg-fm)] - [fm (flomap-blur fm half-σ)]) - fm)] - [else - (flomap-blur raw-shadow-fm σ)])) - ;(printf "~v~n" (flomap->bitmap (flomap-normalize scattered-shadow-fm))) - - ;; pass 2: trace from the viewer - (define-values (reflected-fm transmitted-fm) - (trace-directional-view alpha-fm rgb-fm z-fm normal-fm shadow-fm)) - #; - (printf "reflected: ~v~ntransmitted: ~v~n" - (flomap->bitmap (flomap-normalize reflected-fm)) - (flomap->bitmap (flomap-normalize transmitted-fm))) - - ;; add all the light together, convert to premultiplied-alpha flomap - (let* ([fm (fm+ (fm+ diffracted-fm transmitted-fm) reflected-fm)] - [fm (flomap-append-components alpha-fm fm)] - [fm (flomap-multiply-alpha fm)] - ) - fm)) diff --git a/collects/images/private/unsafe.rkt b/collects/images/private/unsafe.rkt deleted file mode 100644 index bf1350a216..0000000000 --- a/collects/images/private/unsafe.rkt +++ /dev/null @@ -1,243 +0,0 @@ -#lang racket - -(require racket/flonum - ;racket/unsafe/ops - (prefix-in unsafe- (combine-in racket/flonum racket/fixnum racket/base)) - ) - -(provide (all-defined-out) - ;(all-from-out racket/unsafe/ops) - (combine-out (all-from-out racket/flonum racket/fixnum) - unsafe-bytes-ref unsafe-bytes-set! unsafe-bytes-length - unsafe-flvector-ref unsafe-flvector-set! unsafe-flvector-length - unsafe-vector-ref unsafe-vector-set! unsafe-vector-length)) - -;; =================================================================================================== -;; flonum ops - -(define-syntax-rule (unsafe-flneg x) (unsafe-fl- 0.0 x)) -(define-syntax-rule (unsafe-flsqr x) (let ([y x]) (unsafe-fl* y y))) - -(define-syntax-rule (unsafe-flrational? x) - ;; if x = +nan.0, both tests return #f - (and (unsafe-fl> x -inf.0) (unsafe-fl< x +inf.0))) - -(define-syntax unsafe-flsum - (syntax-rules () - [(_) 0.0] - [(_ v1) v1] - [(_ v1 vs ...) (unsafe-fl+ v1 (unsafe-flsum vs ...))])) - -(define-syntax unsafe-flproduct - (syntax-rules () - [(_) 1.0] - [(_ v1) v1] - [(_ v1 vs ...) (unsafe-fl* v1 (unsafe-flproduct vs ...))])) - -(define-syntax unsafe-flmin* - (syntax-rules () - [(_) 1.0] - [(_ v1) v1] - [(_ v1 vs ...) (unsafe-flmin v1 (unsafe-flmin* vs ...))])) - -(define-syntax unsafe-flmax* - (syntax-rules () - [(_) 1.0] - [(_ v1) v1] - [(_ v1 vs ...) (unsafe-flmax v1 (unsafe-flmax* vs ...))])) - -(define-syntax-rule (unsafe-fl->byte x) - (unsafe-fl->fx* (unsafe-flround (unsafe-flmax (unsafe-flmin x 255.0) 0.0)))) - -(define-syntax-rule (unsafe-fl-convex-combination dv sv sa) - (let ([sa* sa]) - (unsafe-fl+ (unsafe-fl* sa* sv) (unsafe-fl* dv (unsafe-fl- 1.0 sa*))))) - -(define-syntax-rule (unsafe-fl-alpha-blend dca sca sa) - (unsafe-fl+ sca (unsafe-fl* dca (unsafe-fl- 1.0 sa)))) - -(define-syntax-rule (unsafe-flsigmoid x) - (unsafe-fl/ 1.0 (unsafe-fl+ 1.0 (unsafe-flexp (unsafe-fl- 0.0 x))))) - -(define-syntax-rule (unsafe-flgaussian x s) - (let* ([s* s] [x* (unsafe-fl/ x s*)]) - (unsafe-fl/ (unsafe-flexp (unsafe-fl* -0.5 (unsafe-fl* x* x*))) - (unsafe-fl* (sqrt (* 2.0 pi)) s*)))) - -;; =================================================================================================== -;; flvector ops - -(define-syntax-rule (unsafe-flvector-3ref vs i) - (let ([j i]) - (values (unsafe-flvector-ref vs j) - (unsafe-flvector-ref vs (unsafe-fx+ j 1)) - (unsafe-flvector-ref vs (unsafe-fx+ j 2))))) - -(define-syntax-rule (unsafe-flvector-3set! vs i x y z) - (let ([j i]) - (unsafe-flvector-set! vs j x) - (unsafe-flvector-set! vs (unsafe-fx+ j 1) y) - (unsafe-flvector-set! vs (unsafe-fx+ j 2) z))) - -(define-syntax-rule (unsafe-flvector-4ref vs i) - (let ([j i]) - (values (unsafe-flvector-ref vs j) - (unsafe-flvector-ref vs (unsafe-fx+ j 1)) - (unsafe-flvector-ref vs (unsafe-fx+ j 2)) - (unsafe-flvector-ref vs (unsafe-fx+ j 3))))) - -(define-syntax-rule (unsafe-flvector-4set! vs i a r g b) - (let ([j i]) - (unsafe-flvector-set! vs j a) - (unsafe-flvector-set! vs (unsafe-fx+ j 1) r) - (unsafe-flvector-set! vs (unsafe-fx+ j 2) g) - (unsafe-flvector-set! vs (unsafe-fx+ j 3) b))) - -(define-syntax-rule (unsafe-build-flvector len f) - (let ([n len]) - (define vs (make-flvector n)) - (let loop ([i 0]) - (cond [(i . unsafe-fx< . n) (unsafe-flvector-set! vs i (f i)) - (loop (unsafe-fx+ i 1))] - [else vs])))) - -(define-syntax-rule (unsafe-flvector-sum vs) - (let ([vs* vs]) - (let ([n (unsafe-flvector-length vs*)]) - (let loop ([i 0] [sum 0.0]) - (cond [(unsafe-fx= i n) sum] - [else (loop (unsafe-fx+ i 1) (unsafe-fl+ sum (unsafe-flvector-ref vs* i)))]))))) - -;; =================================================================================================== -;; fixnum ops - -(define (unsafe-fl->fx* x) (if (unsafe-flrational? x) (unsafe-fl->fx x) 0)) - -(define-syntax-rule (unsafe-fxneg x) (unsafe-fx- 0 x)) - -(define-syntax unsafe-fxsum - (syntax-rules () - [(_) 0] - [(_ v1) v1] - [(_ v1 vs ...) (unsafe-fx+ v1 (unsafe-fxsum vs ...))])) - -(define-syntax unsafe-fxproduct - (syntax-rules () - [(_) 1] - [(_ v1) v1] - [(_ v1 vs ...) (unsafe-fx* v1 (unsafe-fxproduct vs ...))])) - -(define-syntax-rule (unsafe-byte-blend x y α) - (unsafe-fxquotient (unsafe-fx+ (unsafe-fx* x α) (unsafe-fx* (unsafe-fx- 255 α) y)) 255)) - -(define-syntax-rule (unsafe-fx->byte x) - (unsafe-fxmax (unsafe-fxmin x 255) 0)) - -(define-syntax-rule (unsafe-fx-dst-over-alpha sa da) - (let ([sa* sa] [da* da]) - (unsafe-fxquotient (unsafe-fx+ 127 (unsafe-fx- (unsafe-fx* (unsafe-fx+ sa* da*) 255) - (unsafe-fx* sa* da*))) - 255))) - -(define-syntax-rule (unsafe-fx-dst-over-color sa sc da dc) - (let ([da* da]) - (unsafe-fxquotient (unsafe-fxsum 32512 - (unsafe-fxproduct da* dc 255) - (unsafe-fxproduct sa sc (unsafe-fx- 255 da*))) - 65025))) - -;; =================================================================================================== -;; bytes ops - -(define-syntax-rule (unsafe-bytes-3ref bs i) - (let ([j i]) - (values (unsafe-bytes-ref bs j) - (unsafe-bytes-ref bs (unsafe-fx+ j 1)) - (unsafe-bytes-ref bs (unsafe-fx+ j 2))))) - -(define-syntax-rule (unsafe-bytes-3set! bs i r g b) - (let ([j i]) - (unsafe-bytes-set! bs j r) - (unsafe-bytes-set! bs (unsafe-fx+ j 1) g) - (unsafe-bytes-set! bs (unsafe-fx+ j 2) b))) - -(define-syntax-rule (unsafe-bytes-4ref bs i) - (let ([j i]) - (values (unsafe-bytes-ref bs j) - (unsafe-bytes-ref bs (unsafe-fx+ j 1)) - (unsafe-bytes-ref bs (unsafe-fx+ j 2)) - (unsafe-bytes-ref bs (unsafe-fx+ j 3))))) - -(define-syntax-rule (unsafe-bytes-4set! bs i a r g b) - (let ([j i]) - (unsafe-bytes-set! bs j a) - (unsafe-bytes-set! bs (unsafe-fx+ j 1) r) - (unsafe-bytes-set! bs (unsafe-fx+ j 2) g) - (unsafe-bytes-set! bs (unsafe-fx+ j 3) b))) - -;; =================================================================================================== -;; 2-flonum-values ops - -(define-syntax-rule (unsafe-fl2dot x1 y1 x2 y2) - (unsafe-fl+ (unsafe-fl* x1 x2) (unsafe-fl* y1 y2))) - -;; =================================================================================================== -;; 3-flonum-values ops - -(define-syntax-rule (unsafe-fl3+ x1 y1 z1 x2 y2 z2) - (values (unsafe-fl+ x1 x2) (unsafe-fl+ y1 y2) (unsafe-fl+ z1 z2))) - -(define-syntax-rule (unsafe-fl3- x1 y1 z1 x2 y2 z2) - (values (unsafe-fl- x1 x2) (unsafe-fl- y1 y2) (unsafe-fl- z1 z2))) - -(define-syntax unsafe-fl3* - (syntax-rules () - [(_ x y z c) (values (unsafe-fl* x c) (unsafe-fl* y c) (unsafe-fl* z c))] - [(_ x1 y1 z1 x2 y2 z2) (values (unsafe-fl* x1 x2) (unsafe-fl* y1 y2) (unsafe-fl* z1 z2))])) - -(define-syntax unsafe-fl3/ - (syntax-rules () - [(_ x y z c) (values (unsafe-fl/ x c) (unsafe-fl/ y c) (unsafe-fl/ z c))] - [(_ x1 y1 z1 x2 y2 z2) (values (unsafe-fl/ x1 x2) (unsafe-fl/ y1 y2) (unsafe-fl/ z1 z2))])) - -(define-syntax unsafe-fl3ma - (syntax-rules () - [(_ x y z dx dy dz t) - (values (unsafe-fl+ x (unsafe-fl* dx t)) - (unsafe-fl+ y (unsafe-fl* dy t)) - (unsafe-fl+ z (unsafe-fl* dz t)))] - [(_ x y z dx dy dz tx ty tz) - (values (unsafe-fl+ x (unsafe-fl* dx tx)) - (unsafe-fl+ y (unsafe-fl* dy ty)) - (unsafe-fl+ z (unsafe-fl* dz tz)))])) - -(define-syntax-rule (unsafe-fl3neg x y z) - (values (unsafe-flneg x) (unsafe-flneg y) (unsafe-flneg z))) - -(define-syntax-rule (unsafe-fl3dot x1 y1 z1 x2 y2 z2) - (unsafe-fl+ (unsafe-fl+ (unsafe-fl* x1 x2) (unsafe-fl* y1 y2)) - (unsafe-fl* z1 z2))) - -(define-syntax-rule (unsafe-fl3mag^2 dx dy dz) - (unsafe-fl3dot dx dy dz dx dy dz)) - -(define-syntax-rule (unsafe-fl3mag dx dy dz) - (unsafe-flsqrt (unsafe-fl3mag^2 dx dy dz))) - -(define-syntax-rule (unsafe-fl3dist x1 y1 z1 x2 y2 z2) - (unsafe-fl3mag (unsafe-fl- x1 x2) (unsafe-fl- y1 y2) (unsafe-fl- z1 z2))) - -(define-syntax-rule (unsafe-fl3normalize x1 y1 z1) - (let ([i1 x1] [j1 y1] [k1 z1]) - (define d (unsafe-fl3mag i1 j1 k1)) - (values (unsafe-fl/ i1 d) (unsafe-fl/ j1 d) (unsafe-fl/ k1 d)))) - -(define-syntax-rule (unsafe-fl3-half-norm x1 y1 z1 x2 y2 z2) - (unsafe-fl3normalize (unsafe-fl+ x1 x2) (unsafe-fl+ y1 y2) (unsafe-fl+ z1 z2))) - -(define-syntax-rule (unsafe-fl3-convex-combination x1 y1 z1 x2 y2 z2 α) - (let* ([a α] - [1-a (unsafe-fl- 1.0 a)]) - (values (unsafe-fl+ (unsafe-fl* 1-a x1) (unsafe-fl* a x2)) - (unsafe-fl+ (unsafe-fl* 1-a y1) (unsafe-fl* a y2)) - (unsafe-fl+ (unsafe-fl* 1-a z1) (unsafe-fl* a z2))))) diff --git a/collects/images/private/utils.rkt b/collects/images/private/utils.rkt index 48794567ec..033313818e 100644 --- a/collects/images/private/utils.rkt +++ b/collects/images/private/utils.rkt @@ -6,37 +6,41 @@ (provide (all-defined-out)) +(define num-callbacks 0) +(define (get-num-callbacks) num-callbacks) + (define (register-gc-callback proc) - (define val (box 0)) - (register-finalizer val (λ (_) - (define again? (proc)) - (when again? (register-gc-callback proc))))) + (printf "registering~n") + (register-finalizer (malloc 4) (λ (val) + (set! num-callbacks (+ 1 num-callbacks)) + (printf "here~n") + (when (proc) (register-gc-callback proc))))) (define (weak-value-hash-clean! h) (define ks (for*/list ([(k bx) (in-hash h)] - [val (in-value (weak-box-value bx))] + [val (in-value (weak-box-value (car bx)))] #:when (not val)) k)) (for ([k (in-list ks)]) (hash-remove! h k))) -;(define total-time-saved 0) -;(define total-time-spent 0) +(define total-time-saved 0) +(define total-time-spent 0) ;; Can't simply wrap hash-ref! with weak-box-value and thnk with make-weak-box, because ;; 1. If weak-box-value returns #f, we need to regenerate the value ;; 2. We need to keep a handle to the generated value while it's being stored in the hash (define (weak-value-hash-ref! h k thnk) (define (cache-ref!) - ;(define start (current-milliseconds)) + (define start (current-milliseconds)) (define val (thnk)) - ;(define time (- (current-milliseconds) start)) - ;(set! total-time-spent (+ total-time-spent time)) + (define time (- (current-milliseconds) start)) + (set! total-time-spent (+ total-time-spent time)) ;(printf "total-time-spent = ~v~n" total-time-spent) - (hash-set! h k (cons (make-weak-box val) 0)) + (hash-set! h k (cons (make-weak-box val) time)) val) - (cond [(hash-has-key? h k) (define p (hash-ref h k)) - (define val (weak-box-value (car p))) - (cond [val ;(set! total-time-saved (+ total-time-saved (cdr p))) + (cond [(hash-has-key? h k) (define bx (hash-ref h k)) + (define val (weak-box-value (car bx))) + (cond [val (set! total-time-saved (+ total-time-saved (cdr bx))) ;(printf "total-time-saved = ~v~n" total-time-saved) val] [else (cache-ref!)])] @@ -45,13 +49,17 @@ (define flomap-cache (make-hash)) (define (clean-flomap-cache!) - (weak-value-hash-clean! flomap-cache)) + (weak-value-hash-clean! flomap-cache) + #t) (register-gc-callback clean-flomap-cache!) -(define (read-flomap-cache) +(define (get-flomap-cache) (for/list ([(k bx) (in-hash flomap-cache)]) - (cons k (weak-box-value bx)))) + (cons k (cons (weak-box-value (car bx)) (cdr bx))))) + +(define (get-total-time-saved) total-time-saved) +(define (get-total-time-spent) total-time-spent) (define (make-cached-flomap* name proc size . args) (define rendered-size diff --git a/collects/images/tests/icon-tests.rkt b/collects/images/tests/icon-tests.rkt index 01572d9bf2..cc751ff404 100644 --- a/collects/images/tests/icon-tests.rkt +++ b/collects/images/tests/icon-tests.rkt @@ -7,7 +7,8 @@ images/icons/misc images/icons/tool images/icons/style - images/private/renderfx) + images/private/deep-flomap-render + images/private/utils) (default-icon-height 16) ;(default-icon-material glass-icon-material) diff --git a/collects/images/tests/logo-tests.rkt b/collects/images/tests/logo-tests.rkt index fda2057ef8..08ceb56088 100644 --- a/collects/images/tests/logo-tests.rkt +++ b/collects/images/tests/logo-tests.rkt @@ -3,3 +3,4 @@ (require images/logos) (time (plt-logo 256)) +(time (planet-logo 256)) From 0cfbbb9bdff8780f0f10cdffdb6697864da091ff Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Tue, 10 Jan 2012 15:21:49 -0700 Subject: [PATCH 461/746] Better debugger icon bomb (cherry picked from commit 5736695baec21d1b9e14e93dc574e4f3ca5e2bdb) --- collects/drracket/private/unit.rkt | 5 ++--- collects/icons/bomb-32x32.png | Bin 2357 -> 2262 bytes collects/images/icons/misc.rkt | 20 ++++++++++-------- collects/images/icons/tool.rkt | 2 +- collects/images/private/utils.rkt | 32 ++++++++++++++++++++++++++++- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/collects/drracket/private/unit.rkt b/collects/drracket/private/unit.rkt index b18001286d..c6e7167d37 100644 --- a/collects/drracket/private/unit.rkt +++ b/collects/drracket/private/unit.rkt @@ -386,12 +386,11 @@ module browser threading seems wrong. frame program-filename)))]))) - (define disk-color (make-object color% 255 233 112)) (define execute-bitmap (icons:play-icon icons:run-icon-color (icons:toolbar-icon-height))) (define break-bitmap (icons:stop-icon icons:halt-icon-color (icons:toolbar-icon-height))) - (define small-save-bitmap (icons:small-save-icon icons:syntax-icon-color disk-color + (define small-save-bitmap (icons:small-save-icon icons:syntax-icon-color "gold" (icons:toolbar-icon-height))) - (define save-bitmap (icons:save-icon icons:syntax-icon-color disk-color + (define save-bitmap (icons:save-icon icons:syntax-icon-color "gold" (icons:toolbar-icon-height))) (define-values (get-program-editor-mixin add-to-program-editor-mixin) diff --git a/collects/icons/bomb-32x32.png b/collects/icons/bomb-32x32.png index fd0af43583b329377e72a11221a1dc369ad7072d..2b491a0d17adff3b500d9f6de4c5e5bd755e2689 100644 GIT binary patch delta 2232 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 indent-fm) (* -2 scale))] + [indent-dfm (deep-flomap-raise (flomap->deep-flomap indent-fm) (* -1 scale))] [fm (regular-polygon-flomap 8 (/ (* 2 pi) 16) color height)] [dfm (flomap->deep-flomap fm)] [dfm (deep-flomap-cc-superimpose 'add dfm indent-dfm)] @@ -218,16 +218,20 @@ (define scale (/ height 32)) (define fuse-fm (let* ([fm (draw-icon-flomap - 16 16 (λ (dc) - (send dc set-pen "black" 1/2 'solid) + 10 25 (λ (dc) + (send dc set-pen "darkred" 1 'solid) (send dc set-brush "gold" 'solid) (draw-path-commands dc 0 0 - '((m 0.5 5.5) - (c -1.5 -2 -0.5 -5 2 -5.5 - 3 0.5 5 2.5 6 5 - 0.5 2.5 -1.5 4.5 -4 4 - -1 -2 -1.5 -3.5 -4 -3.5)))) + '((m 3.5 0) + (c -5 0 -3.29080284 10.4205 -3 11.5 + 1.1137011 4.1343 2 6.5 0 8.5 + -0.5711131 2.0524 1.5 4 3.5 3.5 + 2.5711131 -2.5524 3.1327042 -5.5355 2 -9.5 + -2 -7 -2 -9 -1.5 -9 + 0 1 -0.5 2 1 3.5 + 2 0.5 4 -1.5 3.5 -3.5 + -2 -2 -2 -5 -5.5 -5)))) scale)] [dfm (flomap->deep-flomap fm)] [dfm (deep-flomap-icon-style dfm)] diff --git a/collects/images/icons/tool.rkt b/collects/images/icons/tool.rkt index 33ce9166b6..06ccc52b6b 100644 --- a/collects/images/icons/tool.rkt +++ b/collects/images/icons/tool.rkt @@ -10,7 +10,7 @@ (provide (all-defined-out)) -(define debugger-bomb-color (make-object color% 128 64 64)) +(define debugger-bomb-color (make-object color% 128 32 32)) (define macro-stepper-hash-color (make-object color% 30 96 30)) (define (check-syntax-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) diff --git a/collects/images/private/utils.rkt b/collects/images/private/utils.rkt index 033313818e..08b96724f5 100644 --- a/collects/images/private/utils.rkt +++ b/collects/images/private/utils.rkt @@ -10,7 +10,6 @@ (define (get-num-callbacks) num-callbacks) (define (register-gc-callback proc) - (printf "registering~n") (register-finalizer (malloc 4) (λ (val) (set! num-callbacks (+ 1 num-callbacks)) (printf "here~n") @@ -143,6 +142,37 @@ (scale-path-commands cmds sx sy))] [(list) (list)])) +(define (relativize-path-commands cmds) + (let loop ([x 0] [y 0] [cmds cmds]) + (cond + [(empty? cmds) empty] + [else + (define cmd (first cmds)) + (match cmd + ;; absolute commands + [`(M) (loop x y (rest cmds))] + [`(L) (loop x y (rest cmds))] + [`(C) (loop x y (rest cmds))] + [`(M ,ax ,ay ,as ...) (cons `(m ,(- ax x) ,(- ay y)) + (loop ax ay (cons `(M ,@as) (rest cmds))))] + [`(L ,ax ,ay ,as ...) (cons `(l ,(- ax x) ,(- ay y)) + (loop ax ay (cons '(L ,@as) (rest cmds))))] + [`(C ,ax1 ,ay1 ,ax2 ,ay2 ,ax ,ay ,as ...) + (cons `(c ,(- ax1 x) ,(- ay1 y) ,(- ax2 x) ,(- ay2 y) ,(- ax x) ,(- ay y)) + (loop ax ay (cons `(C ,@as) (rest cmds))))] + ;; relative commands + [`(m) (loop x y (rest cmds))] + [`(l) (loop x y (rest cmds))] + [`(c) (loop x y (rest cmds))] + [`(m ,dx ,dy ,ds ...) (cons `(m ,dx ,dy) (loop (+ x dx) (+ y dy) + (cons `(m ,@ds) (rest cmds))))] + [`(l ,dx ,dy ,ds ...) (cons `(l ,dx ,dy) (loop (+ x dx) (+ y dy) + (cons `(l ,@ds) (rest cmds))))] + [`(c ,dx1 ,dy1 ,dx2 ,dy2 ,dx ,dy ,ds ...) + (cons `(c ,dx1 ,dy1 ,dx2 ,dy2 ,dx ,dy) + (loop (+ x dx) (+ y dy) (cons `(c ,@ds) (rest cmds))))] + [_ (error 'apply-path-commands "unknown path command ~e" cmd)])]))) + (define (get-text-size str font) (define bm (make-bitmap 1 1)) (define dc (make-object bitmap-dc% bm)) From b7b273895a5a2bbbf893817726952a3274796f2d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 11 Jan 2012 04:58:29 -0700 Subject: [PATCH 462/746] fix bytecode optimizer bugs Certain unsafe operations were allowed to propagate across a `lambda' boundary (where space safety is known not to be an issue), which could lead to duplicate uses of a "once used" variable if the relevant `lambda' is inlined. Furthermore, `lambda' boundary crossing wasn't detected in the case that the operation to propagate was propagated through an intermediate variable without a `lambda' crossing. Merge to 5.2.1 (cherry picked from commit 7850a26dfe2b6165fd0bf39f377314e431157be9) --- .../images/private/deep-flomap-render.rkt | 6 +-- collects/tests/racket/optimize.rktl | 31 ++++++++++++++ src/racket/src/optimize.c | 42 ++++++++++++++----- 3 files changed, 64 insertions(+), 15 deletions(-) diff --git a/collects/images/private/deep-flomap-render.rkt b/collects/images/private/deep-flomap-render.rkt index 6d46cfb856..219740d138 100644 --- a/collects/images/private/deep-flomap-render.rkt +++ b/collects/images/private/deep-flomap-render.rkt @@ -400,11 +400,7 @@ (when (rdist . >= . 0.0) (define cdist (fl3dist sx sy sz x-mid y-mid 0.0)) (define v (flsigmoid (* 0.25 (- (* 4.5 z-size) cdist)))) - (define trash 0.0) - (set! trash Irr) - (set! trash Irg) - (set! trash Irb) - (let-values ([(r g b) (fl3* Irr Irg Irb (* R v))]) + (let-values ([(r g b) (fl3* Irr Irg Irb (* R v))]) (unsafe-flvector-set! reflected-vs j r) (unsafe-flvector-set! reflected-vs (fx+ j 1) g) (unsafe-flvector-set! reflected-vs (fx+ j 2) b)))) diff --git a/collects/tests/racket/optimize.rktl b/collects/tests/racket/optimize.rktl index e619d1e642..51297553a7 100644 --- a/collects/tests/racket/optimize.rktl +++ b/collects/tests/racket/optimize.rktl @@ -1393,6 +1393,37 @@ (f) (list x))) +;; don't duplicate formerly once-used variable due to inlining +(test-comp '(lambda (y) + (let ([q (unsafe-fl* y y)]) ; => q is known flonum + (let ([x (unsafe-fl* q q)]) ; can delay (but don't duplicate) + (define (f z) (unsafe-fl+ z x)) + (if y + (f 10) + f)))) + '(lambda (y) + (let ([q (unsafe-fl* y y)]) + (let ([x (unsafe-fl* q q)]) + (define (f z) (unsafe-fl+ z x)) + (if y + (unsafe-fl+ 10 x) + f))))) +;; double-check that previous test doesn't succeed due to copying +(test-comp '(lambda (y) + (let ([q (unsafe-fl* y y)]) + (let ([x (unsafe-fl* q q)]) + (define (f z) (unsafe-fl+ z x)) + (if y + (unsafe-fl+ 10 x) + f)))) + '(lambda (y) + (let ([q (unsafe-fl* y y)]) + (define (f z) (unsafe-fl+ z (unsafe-fl* q q))) + (if y + (unsafe-fl+ 10 (unsafe-fl* q q)) + f))) + #f) + ;; simple cross-module inlining (test-comp `(module m racket/base (require racket/bool) diff --git a/src/racket/src/optimize.c b/src/racket/src/optimize.c index 0c2aaaebec..d7d1d57e21 100644 --- a/src/racket/src/optimize.c +++ b/src/racket/src/optimize.c @@ -93,7 +93,7 @@ static void optimize_info_used_top(Optimize_Info *info); static void optimize_mutated(Optimize_Info *info, int pos); static void optimize_produces_flonum(Optimize_Info *info, int pos); -static Scheme_Object *optimize_reverse(Optimize_Info *info, int pos, int unless_mutated); +static Scheme_Object *optimize_reverse(Optimize_Info *info, int pos, int unless_mutated, int disrupt_single_use); static int optimize_is_used(Optimize_Info *info, int pos); static int optimize_any_uses(Optimize_Info *info, int start_pos, int end_pos); static int optimize_is_mutated(Optimize_Info *info, int pos); @@ -534,8 +534,9 @@ static int is_movable_prim(Scheme_Object *rator, int n, int cross_lambda) if (rator && SCHEME_PRIMP(rator)) { if (((Scheme_Prim_Proc_Header *)rator)->flags & SCHEME_PRIM_IS_UNSAFE_FUNCTIONAL) { /* Although it's semantically ok to return -1 even when cross_lambda, - doing so risks duplicating a computation of the relevant `lambda' + doing so risks duplicating a computation if the relevant `lambda' is later inlined. */ + if (cross_lambda) return 0; return -1; } } @@ -1126,7 +1127,7 @@ Scheme_Object *optimize_for_inline(Optimize_Info *info, Scheme_Object *le, int a sub_info = info; /* If scheme_optimize_clone succeeds, inlining succeeds. */ - le = scheme_optimize_clone(0, data->code, sub_info, + le = scheme_optimize_clone(single_use, data->code, sub_info, offset + (outside_nested ? nested_count : 0), data->num_params); @@ -1225,7 +1226,7 @@ static void register_flonum_argument_types(Scheme_App_Rec *app, Scheme_App2_Rec } if (SAME_TYPE(SCHEME_TYPE(rator), scheme_local_type)) { - rator = optimize_reverse(info, SCHEME_LOCAL_POS(rator), 1); + rator = optimize_reverse(info, SCHEME_LOCAL_POS(rator), 1, 0); if (rator) { int offset, single_use; le = optimize_info_lookup(info, SCHEME_LOCAL_POS(rator), &offset, &single_use, 0, 0, NULL, NULL); @@ -1997,7 +1998,7 @@ static Scheme_Object *lookup_constant_proc(Optimize_Info *info, Scheme_Object *r if (SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type)) { int offset; Scheme_Object *expr; - expr = optimize_reverse(info, SCHEME_LOCAL_POS(rand), 0); + expr = optimize_reverse(info, SCHEME_LOCAL_POS(rand), 0, 0); c = optimize_info_lookup(info, SCHEME_LOCAL_POS(expr), &offset, NULL, 0, 0, NULL, NULL); } if (SAME_TYPE(SCHEME_TYPE(rand), scheme_compiled_toplevel_type)) { @@ -2436,7 +2437,7 @@ Scheme_Object *scheme_optimize_apply_values(Scheme_Object *f, Scheme_Object *e, { Scheme_Object *rev; if (SAME_TYPE(SCHEME_TYPE(f), scheme_local_type)) { - rev = optimize_reverse(info, SCHEME_LOCAL_POS(f), 1); + rev = optimize_reverse(info, SCHEME_LOCAL_POS(f), 1, 0); } else rev = f; @@ -3978,7 +3979,7 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i Unless post_bind, this must be done with respect to body_info, not rhs_info, because we attach the value to body_info: */ - value = optimize_reverse(post_bind ? rhs_info : body_info, vpos, 1); + value = optimize_reverse(post_bind ? rhs_info : body_info, vpos, 1, 0); /* Double-check that the value is ready, because we might be nested in the RHS of a `letrec': */ @@ -5269,7 +5270,7 @@ Scheme_Object *scheme_optimize_clone(int dup_ok, Scheme_Object *expr, Optimize_I { int pos = SCHEME_LOCAL_POS(expr); if (pos >= closure_depth) { - expr = optimize_reverse(info, pos + delta - closure_depth, 0); + expr = optimize_reverse(info, pos + delta - closure_depth, 0, !dup_ok); if (closure_depth) expr = scheme_make_local(scheme_local_type, SCHEME_LOCAL_POS(expr) + closure_depth, 0); } @@ -5923,7 +5924,7 @@ static void optimize_produces_flonum(Optimize_Info *info, int pos) register_use(info, pos, 0x4); } -static Scheme_Object *optimize_reverse(Optimize_Info *info, int pos, int unless_mutated) +static Scheme_Object *optimize_reverse(Optimize_Info *info, int pos, int unless_mutated, int disrupt_single_use) /* pos is in new-frame counts, and we want to produce an old-frame reference if it's not mutated */ { @@ -5941,6 +5942,26 @@ static Scheme_Object *optimize_reverse(Optimize_Info *info, int pos, int unless_ if (info->use && (info->use[pos] & 0x1)) return NULL; + if (disrupt_single_use) { + Scheme_Object *p, *n; + p = info->consts; + while (p) { + n = SCHEME_VEC_ELS(p)[1]; + if (SCHEME_INT_VAL(n) == pos) { + if (SCHEME_TRUEP(SCHEME_VEC_ELS(p)[3])) { + SCHEME_VEC_ELS(p)[3] = scheme_false; /* disable "single use" mark */ + } + n = SCHEME_VEC_ELS(p)[2]; + if (SAME_TYPE(SCHEME_TYPE(n), scheme_once_used_type)) { + ((Scheme_Once_Used *)n)->expr = NULL; + ((Scheme_Once_Used *)n)->vclock = -1; + } + break; + } + p = SCHEME_VEC_ELS(p)[0]; + } + } + return scheme_make_local(scheme_local_type, pos + delta, 0); } @@ -6103,7 +6124,7 @@ static Scheme_Object *do_optimize_info_lookup(Optimize_Info *info, int pos, int o->cross_lambda = (j != orig_j); return (Scheme_Object *)o; } else if (SAME_TYPE(SCHEME_TYPE(n), scheme_local_type)) { - int pos; + int pos, cross_lambda = (j != orig_j); pos = SCHEME_LOCAL_POS(n); if (info->flags & SCHEME_LAMBDA_FRAME) @@ -6136,6 +6157,7 @@ static Scheme_Object *do_optimize_info_lookup(Optimize_Info *info, int pos, int /* Need to adjust delta: */ delta = optimize_info_get_shift(info, pos); ((Scheme_Once_Used *)n)->delta += delta; + if (cross_lambda) ((Scheme_Once_Used *)n)->cross_lambda = 1; } } return n; From e6285227f1fec8be6e4080eb6991dfe3ace6d6b4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 11 Jan 2012 11:29:27 -0600 Subject: [PATCH 463/746] Change 'bitmap' to use collection-file-path (with its new #:fail) argument, so that it picks up linked collections. closes 12424 merge to the release branch, please (cherry picked from commit d93818dd613942eda80244497fdc139fb1b2bbd3) --- collects/2htdp/private/image-more.rkt | 31 +++++++++++---------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/collects/2htdp/private/image-more.rkt b/collects/2htdp/private/image-more.rkt index 3941f60585..2ffd94835d 100644 --- a/collects/2htdp/private/image-more.rkt +++ b/collects/2htdp/private/image-more.rkt @@ -1271,25 +1271,18 @@ [(null? pieces) (raise-syntax-error 'bitmap "expected a path with a / in it" stx)] [else - (let loop ([cps (current-library-collection-paths)]) - (cond - [(null? cps) - (raise-syntax-error 'bitmap - (format "could not find the ~a collection" (car pieces)) - stx)] - [else - (if (and (directory-exists? (car cps)) - (member (build-path (car pieces)) - (directory-list (car cps)))) - (let ([candidate (apply build-path (car cps) pieces)]) - (if (file-exists? candidate) - candidate - (raise-syntax-error 'bitmap - (format "could not find ~a in the ~a collection" - (apply string-append (add-between (cdr pieces) "/")) - (car pieces)) - stx))) - (loop (cdr cps)))]))]))] + (define fn (last pieces)) + (define colls (reverse (cdr (reverse pieces)))) + (define candidate + (apply collection-file-path fn colls + #:fail + (λ (msg) (raise-syntax-error 'bitmap msg stx)))) + (unless (file-exists? candidate) + (raise-syntax-error 'bitmap + (format "could not find ~s, expected it to be in ~a" + arg candidate) + stx)) + candidate]))] [(string? arg) (path->complete-path arg From ca73b0569d039c0f1aef919d9309e1cc67e2ca85 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 11 Jan 2012 12:31:41 -0600 Subject: [PATCH 464/746] tweak the printing of syntax errors again so the "in:" part is in tt font merge to the release branch, please (cherry picked from commit 9aecc085795bd50ea3ff72da84980bb1f1329cf6) --- collects/drracket/private/debug.rkt | 46 ++++++++++++++++------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/collects/drracket/private/debug.rkt b/collects/drracket/private/debug.rkt index 4df3981356..b81bfd88e6 100644 --- a/collects/drracket/private/debug.rkt +++ b/collects/drracket/private/debug.rkt @@ -515,27 +515,31 @@ profile todo: (write-special snp (current-error-port))) (display msg (current-error-port))))]) (send error-text-style-delta set-delta-foreground (make-object color% 200 0 0)) - (let ([show-one - (λ (expr) - (display " " (current-error-port)) - (send-out (format "~s" (syntax->datum expr)) - (λ (snp) - (send snp set-style - (send (editor:get-standard-style-list) find-or-create-style - (send (editor:get-standard-style-list) find-named-style "Standard") - error-text-style-delta)))))] - [exprs (exn:fail:syntax-exprs exn)]) - (cond - [(null? exprs) (void)] - [(null? (cdr exprs)) - (send-out " in:" void) - (show-one (car exprs))] - [else - (send-out " in:" void) - (for-each (λ (expr) - (display "\n " (current-error-port)) - (show-one expr)) - exprs)])))) + (define (show-one expr) + (display " " (current-error-port)) + (send-out (format "~s" (syntax->datum expr)) + (λ (snp) + (send snp set-style + (send (editor:get-standard-style-list) find-or-create-style + (send (editor:get-standard-style-list) find-named-style "Standard") + error-text-style-delta))))) + (define exprs (exn:fail:syntax-exprs exn)) + (define (show-in) + (send-out " in:" + (λ (snp) + (send snp set-style + (send (editor:get-standard-style-list) find-named-style "Standard"))))) + (cond + [(null? exprs) (void)] + [(null? (cdr exprs)) + (show-in) + (show-one (car exprs))] + [else + (show-in) + (for-each (λ (expr) + (display "\n " (current-error-port)) + (show-one expr)) + exprs)]))) ;; insert/clickback : (instanceof text%) (union string (instanceof snip%)) (-> void) From 42698ef9c54f2b032f9d84d3869fe6d2984b6dc1 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 11 Jan 2012 12:43:30 -0600 Subject: [PATCH 465/746] relax the contract to match what the server actually needs closes PR 12476 merge to the release branch, please (cherry picked from commit 5e80753b48125eae686c6a2fae12a8a91f4d75da) --- collects/drracket/tool-lib.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/drracket/tool-lib.rkt b/collects/drracket/tool-lib.rkt index cf121a8966..7f5ffcfbf8 100644 --- a/collects/drracket/tool-lib.rkt +++ b/collects/drracket/tool-lib.rkt @@ -906,7 +906,7 @@ all of the names in the tools library, for use defining keybindings (parameter-doc drracket:rep:after-expression - (parameter/c (or/c #f (-> void?))) + (parameter/c (or/c #f (-> any))) top-level-expression @{This parameter is used by @method[drracket:rep:text% evaluate-from-port]. When it is a thunk, then DrRacket invokes the thunk on the user's thread From 09ad681027ea891adaf2da98b9f8b430733dbbe0 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 11 Jan 2012 13:01:03 -0600 Subject: [PATCH 466/746] fix call to message box to remove incorrect style flag merge to the release branch, please (cherry picked from commit e067a4415a03ec6572135ce584a17050690873ca) --- collects/framework/private/frame.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/framework/private/frame.rkt b/collects/framework/private/frame.rkt index 6a8d9dedff..0f0396f586 100644 --- a/collects/framework/private/frame.rkt +++ b/collects/framework/private/frame.rkt @@ -1459,7 +1459,7 @@ (format (string-constant welcome-to-something) (application:current-app-name)) #f - '(ok app)))) + '(ok)))) (define/override help-menu:about-string (λ () (application:current-app-name))) (define/override help-menu:create-about? (λ () #t)) From 132a46f6719f83538b206b159935d89af7aafd95 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 11 Jan 2012 14:41:33 -0700 Subject: [PATCH 467/746] add missing OS X thread-data synchronization Merge to 5.2.1 (cherry picked from commit af9d0e6976621eee931c80ac4a784885e5a4b5a7) --- src/racket/gc2/vm_osx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/racket/gc2/vm_osx.c b/src/racket/gc2/vm_osx.c index 73466e621e..8c63088f88 100644 --- a/src/racket/gc2/vm_osx.c +++ b/src/racket/gc2/vm_osx.c @@ -102,6 +102,7 @@ static void unregister_mach_thread() { int index = thread_self % OSX_THREAD_TABLE_SIZE; OSXThreadData * thread, *prev = NULL; + pthread_mutex_lock(&osxthreadsmutex); thread = osxthreads[index]; while (thread->thread_port_id != thread_self) { prev = thread; @@ -114,6 +115,7 @@ static void unregister_mach_thread() { osxthreads[index] = thread->next; free(thread); } + pthread_mutex_unlock(&osxthreadsmutex); } #endif From 110283109a1a5a6fa9de9123d533f5d3930bd560 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 12 Jan 2012 06:55:09 -0700 Subject: [PATCH 468/746] skip `libtool --finish' if DESTDIR is set Merge to 5.2.1 (cherry picked from commit 45d72785de1e6d7458a7305443a246dc1e4ed596) --- src/Makefile.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile.in b/src/Makefile.in index a49b16a388..c659147437 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -94,7 +94,9 @@ install-no: $(NOOP) lib-finish: - @LIBFINISH@ "$(libdir)" + if [ "$(DESTDIR)" = "" ]; then \ + @LIBFINISH@ "$(libdir)"; \ + fi no-run: $(NOOP) From d4ab93c5cad1db3e937052f570497d7c47658e83 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 12 Jan 2012 08:17:51 -0700 Subject: [PATCH 469/746] MysterX repairs Merge to 5.2.1 (cherry picked from commit 84d66ca8fe89a2a37251749d1bff18cc0230b0b8) --- src/mysterx/mysterx.cxx | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/mysterx/mysterx.cxx b/src/mysterx/mysterx.cxx index b81b57cab8..30c6e6ab45 100644 --- a/src/mysterx/mysterx.cxx +++ b/src/mysterx/mysterx.cxx @@ -72,7 +72,8 @@ static void GC_BOX_DONE(void *v) { static int is_member(Scheme_Object *a, Scheme_Object *l) { while (!SCHEME_NULLP(l)) { - if (SAME_OBJ(a, SCHEME_CAR(l))) return 1; + if (scheme_equal(a, SCHEME_CAR(l))) return 1; + l = SCHEME_CDR(l); } return 0; } @@ -981,12 +982,12 @@ Scheme_Object *mx_set_coclass(int argc, Scheme_Object **argv) XFORM_NONGCING static int get_wow_flag(int pass) { -#ifndef _WIN64 +#ifdef _WIN64 /* Try 64-bit first, but fall back to 32-bit keys */ -# define NUM_WOW_PASSES 1 +# define NUM_WOW_PASSES 2 return ((pass == 0) ? KEY_WOW64_64KEY : KEY_WOW64_32KEY); #else -# define NUM_WOW_PASSES 0 +# define NUM_WOW_PASSES 1 return 0; #endif } @@ -1017,8 +1018,10 @@ Scheme_Object *mx_coclass(int argc, Scheme_Object **argv) // use CLSID to rummage through Registry to find coclass for (pass = 0; pass < NUM_WOW_PASSES; pass++) { + int wow; + wow = get_wow_flag(pass); result = RegOpenKeyEx(HKEY_CLASSES_ROOT, "CLSID", (DWORD)0, - KEY_READ | get_wow_flag(pass), + KEY_READ | wow, &hkey); if (result != ERROR_SUCCESS) @@ -1051,7 +1054,7 @@ Scheme_Object *mx_coclass(int argc, Scheme_Object **argv) continue; // open subkey result = RegOpenKeyEx(hkey, clsIdBuffer, (DWORD)0, - KEY_READ | get_wow_flag(pass), + KEY_READ | wow, &hsubkey); if (result != ERROR_SUCCESS) scheme_signal_error("coclass: Error obtaining coclass value"); @@ -3729,7 +3732,8 @@ void unmarshalVariant(Scheme_Object *val, VARIANTARG *pVariantArg) break; case VT_VARIANT | VT_BYREF : - SCHEME_BOX_VAL(val) = variantToSchemeObject(pVariantArg->pvarVal); + v = variantToSchemeObject(pVariantArg->pvarVal); + SCHEME_BOX_VAL(val) = v; free(pVariantArg->pvarVal); break; @@ -4539,8 +4543,10 @@ Scheme_Object *mx_all_clsid(int argc, Scheme_Object **argv, char **attributes) retval = scheme_null; for (pass = 0; pass < NUM_WOW_PASSES; pass++) { + int wow; + wow = get_wow_flag(pass); result = RegOpenKeyEx(HKEY_CLASSES_ROOT, "CLSID", (DWORD)0, - KEY_READ | get_wow_flag(pass), + KEY_READ | wow, &hkey); if (result != ERROR_SUCCESS) return retval; @@ -4563,7 +4569,7 @@ Scheme_Object *mx_all_clsid(int argc, Scheme_Object **argv, char **attributes) // open subkey result = RegOpenKeyEx(hkey, clsidBuffer, (DWORD)0, - KEY_READ | get_wow_flag(pass), + KEY_READ | wow, &hsubkey); if (result != ERROR_SUCCESS) From 4603785afef54387a662f957a43f0c5f0bb483df Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Wed, 11 Jan 2012 16:45:23 -0700 Subject: [PATCH 470/746] Added standing and running stickman icons Optimize rendering by looping only over the smallest rectangle with nonzero alpha Please merge into release (cherry picked from commit 2313b528c4c0e8b7940e746481f58b1d6722cdf9) --- collects/images/icons/stickman.rkt | 332 ++++++++++++++++++ .../images/private/deep-flomap-render.rkt | 27 +- 2 files changed, 349 insertions(+), 10 deletions(-) create mode 100644 collects/images/icons/stickman.rkt diff --git a/collects/images/icons/stickman.rkt b/collects/images/icons/stickman.rkt new file mode 100644 index 0000000000..574825a91d --- /dev/null +++ b/collects/images/icons/stickman.rkt @@ -0,0 +1,332 @@ +#lang racket/gui + +(require racket/class racket/snip racket/vector + "../private/flomap.rkt" + "../private/deep-flomap.rkt" + "../private/utils.rkt" + "style.rkt") + +(provide standing-stickman-flomap standing-stickman-icon + running-stickman-flomap running-stickman-icon) + +(define (cons+ p1 p2) + (match-define (cons x1 y1) p1) + (match-define (cons x2 y2) p2) + (cons (+ x1 x2) (+ y1 y2))) + +(define (polar->cartesian angle mag) + (cons (* mag (cos (* (/ pi 180) angle))) + (* mag (sin (* (/ pi 180) angle))))) + +(define line-width 1) +(define body-width 4.5) +(define leg-width 4) +(define arm-width 3.5) + +(define neck-length 6) +(define torso-length 6) +(define upper-arm-length 5) +(define lower-arm-length 5.5) +(define thigh-length 6.5) +(define shin-length 6.5) +(define shoulder-breadth 7) + +(define standing-torso-angle -90) +(define standing-neck-angle 5) +(define standing-left-knee-angle 200) +(define standing-left-foot-angle 0) +(define standing-right-knee-angle 150) +(define standing-right-foot-angle 20) +(define standing-left-elbow-angle 230) +(define standing-left-hand-angle -90) +(define standing-right-elbow-angle 140) +(define standing-right-hand-angle 90) + +(define standing-hip-point (cons 14 (- 29 (+ thigh-length shin-length)))) + +(define standing-neck-point + (cons+ standing-hip-point + (polar->cartesian standing-torso-angle torso-length))) + +(define standing-head-point + (cons+ standing-neck-point + (polar->cartesian (+ standing-neck-angle standing-torso-angle) + neck-length))) + +(define standing-left-knee-point + (cons+ standing-hip-point + (polar->cartesian (+ standing-left-knee-angle standing-torso-angle) + thigh-length))) + +(define standing-left-foot-point + (cons+ standing-left-knee-point + (polar->cartesian (+ standing-left-knee-angle standing-torso-angle standing-left-foot-angle) + shin-length))) + +(define standing-left-shoulder-point + (cons+ standing-neck-point (cons (* -1/2 shoulder-breadth) 0))) + +(define standing-left-elbow-point + (cons+ standing-left-shoulder-point + (polar->cartesian (+ standing-left-elbow-angle standing-torso-angle) + upper-arm-length))) + +(define standing-left-hand-point + (cons+ standing-left-elbow-point + (polar->cartesian (+ standing-left-elbow-angle standing-torso-angle standing-left-hand-angle) + lower-arm-length))) + +(define standing-right-knee-point + (cons+ standing-hip-point + (polar->cartesian (+ standing-right-knee-angle standing-torso-angle) + thigh-length))) + +(define standing-right-foot-point + (cons+ standing-right-knee-point + (polar->cartesian (+ standing-right-knee-angle standing-torso-angle standing-right-foot-angle) + shin-length))) + +(define standing-right-shoulder-point + (cons+ standing-neck-point (cons (* 1/2 shoulder-breadth) 0))) + + +(define standing-right-elbow-point + (cons+ standing-right-shoulder-point + (polar->cartesian (+ standing-right-elbow-angle standing-torso-angle) + upper-arm-length))) + +(define standing-right-hand-point + (cons+ standing-right-elbow-point + (polar->cartesian (+ standing-right-elbow-angle standing-torso-angle standing-right-hand-angle) + lower-arm-length))) + +(define (draw-short-rendered-icon-flomap w h proc scale material) + (let* ([fm (draw-icon-flomap w h proc scale)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-raise dfm (* -18 (/ (flomap-height fm) 32)))]) + (deep-flomap-render-icon dfm material))) + +(define (standing-stickman-flomap color arm-color head-color + [height (default-icon-height)] + [material (default-icon-material)]) + (make-cached-flomap + [height color arm-color head-color material] + (flomap-lt-superimpose + (draw-short-rendered-icon-flomap + 26 32 (λ (dc) + (send dc set-pen "black" (+ arm-width (* 2 line-width)) 'solid) + (send dc draw-lines (list standing-right-shoulder-point + standing-right-elbow-point + standing-right-hand-point)) + (send dc set-pen arm-color arm-width 'solid) + (send dc draw-lines (list standing-right-shoulder-point + standing-right-elbow-point + standing-right-hand-point))) + (/ height 32) + material) + (draw-short-rendered-icon-flomap + 26 32 (λ (dc) + (send dc set-pen "black" (+ body-width (* 2 line-width)) 'solid) + (send dc draw-lines (list standing-neck-point standing-hip-point)) + (send dc set-pen "black" (+ leg-width (* 2 line-width)) 'solid) + (send dc draw-lines (list standing-hip-point + standing-left-knee-point + standing-left-foot-point)) + (send dc draw-lines (list standing-hip-point + standing-right-knee-point + standing-right-foot-point)) + (send dc set-pen color body-width 'solid) + (send dc draw-lines (list standing-neck-point standing-hip-point)) + (send dc set-pen color leg-width 'solid) + (send dc draw-lines (list standing-hip-point + standing-left-knee-point + standing-left-foot-point)) + (send dc draw-lines (list standing-hip-point + standing-right-knee-point + standing-right-foot-point))) + (/ height 32) + material) + (draw-short-rendered-icon-flomap + 26 32 (λ (dc) + (send dc set-pen "black" (+ arm-width (* 2 line-width)) 'solid) + (send dc draw-lines (list standing-left-shoulder-point + standing-left-elbow-point + standing-left-hand-point)) + (send dc set-pen arm-color arm-width 'solid) + (send dc draw-lines (list standing-left-shoulder-point + standing-left-elbow-point + standing-left-hand-point))) + (/ height 32) + material) + (draw-short-rendered-icon-flomap + 26 32 (λ (dc) + (send dc set-pen "black" line-width 'solid) + (send dc set-brush head-color 'solid) + (match-define (cons x y) standing-head-point) + (draw-ellipse/smoothed dc (- x 3.5) (- y 3.5) 8 8)) + (/ height 32) + material)))) + +(define running-neck-angle 20) +(define running-torso-angle -70) + +(define (squash* x scale) + (/ 1 (+ 1 (exp (- (* scale (- x 1/2))))))) + +(define (squash x scale) + (define y-min (squash* 0 scale)) + (define y-max (squash* 1 scale)) + (let* ([x (max 0.0 (min 1.0 x))] + [y (squash* x scale)] + [y (/ (- y y-min) (- y-max y-min))]) + (max 0.0 (min 1.0 y)))) + +(define (cycle t) + (* 0.5 (+ 1.0 (cos (* 2.0 pi (+ 0.5 t)))))) + +(define (scale-angle θ θ-min θ-max) + (+ θ-min (* θ (- θ-max θ-min)))) + +(define (running-foot-angle t) + (scale-angle (squash (cycle (+ -0.3333 t)) 3) 0 125)) + +(define (running-knee-angle t) + (scale-angle (squash (cycle t) 2) 90 210)) + +(define (running-hip-height t) + (+ (- 27 (+ thigh-length shin-length)) + (* 2 (squash (cycle (+ 0.125 (* 2 t))) 5)))) + +(define (running-elbow-angle t) + (scale-angle (squash (cycle (+ 0.5 t)) 4) 150 240)) + +(define (running-hand-angle t) + (scale-angle (squash (cycle (+ 0.6666 t)) 6) -115 -30)) + +(define (running-hip-point t) (cons 14 (running-hip-height t))) + +(define (running-shoulder-point t) + (cons+ (running-hip-point t) + (polar->cartesian running-torso-angle torso-length))) + +(define (running-head-point t) + (cons+ (running-shoulder-point t) + (polar->cartesian (+ running-neck-angle running-torso-angle) + neck-length))) + +(define (running-knee-point t) + (cons+ (running-hip-point t) + (polar->cartesian (+ (running-knee-angle t) running-torso-angle) + thigh-length))) + +(define (running-foot-point t) + (cons+ (running-knee-point t) + (polar->cartesian (+ (running-knee-angle t) running-torso-angle (running-foot-angle t)) + shin-length))) + +(define (running-elbow-point t) + (cons+ (running-shoulder-point t) + (polar->cartesian (+ (running-elbow-angle t) running-torso-angle) + upper-arm-length))) + +(define (running-hand-point t) + (cons+ (running-elbow-point t) + (polar->cartesian (+ (running-elbow-angle t) running-torso-angle (running-hand-angle t)) + lower-arm-length))) + +(define (draw-running-body dc t color width) + (send dc set-pen color width 'solid) + (send dc draw-lines (list (running-hip-point t) (running-shoulder-point t)))) + +(define (draw-running-leg dc t color width) + (send dc set-pen color width 'solid) + (send dc draw-lines + (list (running-hip-point t) (running-knee-point t) (running-foot-point t)))) + +(define (draw-running-arm dc t color width) + (send dc set-pen color width 'solid) + (send dc draw-lines + (list (running-shoulder-point t) (running-elbow-point t) (running-hand-point t)))) + +(define (running-head-flomap t color height material) + (make-cached-flomap + [height t color material] + (draw-short-rendered-icon-flomap + 26 32 (λ (dc) + (send dc set-pen "black" line-width 'solid) + (send dc set-brush color 'solid) + (match-define (cons x y) (running-head-point t)) + (draw-ellipse/smoothed dc (- x 3.5) (- y 3.5) 8 8)) + (/ height 32) + material))) + +(define (running-leg-flomap t body? color height material) + (make-cached-flomap + [height t body? color material] + (draw-short-rendered-icon-flomap + 26 32 (λ (dc) + (draw-running-leg dc t "black" (+ leg-width (* 2 line-width))) + (when body? + (draw-running-body dc t "black" (+ body-width (* 2 line-width))) + (draw-running-body dc t color body-width)) + (draw-running-leg dc t color leg-width)) + (/ height 32) + material))) + +(define (running-arm-flomap t color height material) + (make-cached-flomap + [height t color material] + (draw-short-rendered-icon-flomap + 26 32 (λ (dc) + (draw-running-arm dc t "black" (+ arm-width (* 2 line-width))) + (draw-running-arm dc t color arm-width)) + (/ height 32) + material))) + +(define (running-stickman-flomap t color arm-color head-color + [height (default-icon-height)] + [material (default-icon-material)]) + (make-cached-flomap + [height t color arm-color head-color material] + (flomap-lt-superimpose (running-arm-flomap (+ t 0.5) arm-color height material) + (running-leg-flomap (+ t 0.5) #f color height material) + (running-leg-flomap t #t color height material) + (running-head-flomap t head-color height material) + (running-arm-flomap t arm-color height material)))) + +(define standing-stickman-icon (compose flomap->bitmap standing-stickman-flomap)) +(define running-stickman-icon (compose flomap->bitmap running-stickman-flomap)) + +#; +(begin + (require (planet "animated-canvas.rkt" ("williams" "animated-canvas.plt" 2 4))) + + (define size 20) + + (standing-stickman-icon halt-icon-color "white" halt-icon-color size) + + (define framerate 12) + + (default-icon-material glass-icon-material) + (define frame-bitmaps + (for/vector ([t (in-range 0 1 (/ 1 framerate))]) + (time (running-stickman-icon t run-icon-color "white" run-icon-color size)))) + (printf "~v~n" frame-bitmaps) + + (define frame (make-object frame% "Canvas")) + (define canvas (new animated-canvas% + [parent frame] [style '(border)] + [min-width (+ size 4)] [min-height (+ size 4)])) + (send frame show #t) + + (define i 0) + (define timer (make-object timer% (λ () + (define bm (vector-ref frame-bitmaps i)) + (set! i (modulo (+ i 1) framerate)) + (define dc (send canvas get-dc)) + (send dc draw-bitmap bm 0 0) + (send canvas swap-bitmaps) + (yield)) + (round (* 1000 (/ 1 framerate))))) + ) diff --git a/collects/images/private/deep-flomap-render.rkt b/collects/images/private/deep-flomap-render.rkt index 219740d138..bc88565271 100644 --- a/collects/images/private/deep-flomap-render.rkt +++ b/collects/images/private/deep-flomap-render.rkt @@ -70,8 +70,9 @@ ;; =================================================================================================== ;; Pass 1: tracing from a directional light source -(: trace-directional-light (flomap flomap flomap flomap -> (values flomap flomap))) -(define (trace-directional-light alpha-fm rgb-fm z-fm normal-fm) +(: trace-directional-light (flomap flomap flomap flomap Integer Integer Integer Integer + -> (values flomap flomap))) +(define (trace-directional-light alpha-fm rgb-fm z-fm normal-fm x-min x-max y-min y-max) (match-define (flomap alpha-vs 1 w h) alpha-fm) (match-define (list rgb-vs z-vs normal-vs) (map flomap-values (list rgb-fm z-fm normal-fm))) @@ -115,7 +116,8 @@ (define sy-vs (make-flvector (* w h) +nan.0)) (define Irgb-vs (make-flvector (* 3 w h))) - (for*: ([int-y : Integer (in-range h)] [int-x : Integer (in-range w)]) + (for*: ([int-y : Integer (in-range y-min y-max)] + [int-x : Integer (in-range x-min x-max)]) (define i (fx+ int-x (fx* int-y w))) (define a (unsafe-flvector-ref alpha-vs i)) (when (a . > . 0.0) @@ -202,7 +204,8 @@ (define ambient-shadow-fm (make-flomap 3 w h)) (define ambient-shadow-vs (flomap-values ambient-shadow-fm)) (when (Ta . > . 0.0) - (for*: ([int-y : Integer (in-range h)] [int-x : Integer (in-range w)]) + (for*: ([int-y : Integer (in-range y-min y-max)] + [int-x : Integer (in-range x-min x-max)]) (define i (fx+ int-x (fx* int-y w))) (define a (unsafe-flvector-ref alpha-vs i)) (when (a . > . 0.0) @@ -227,7 +230,8 @@ ;; Gaussian kernels - make as wide as possible to keep from having to reallocate (define kxs (make-flvector w)) (define kys (make-flvector h)) - (for*: ([int-y : Integer (in-range (- h 1))] [int-x : Integer (in-range (- w 1))]) + (for*: ([int-y : Integer (in-range y-min (- y-max 1))] + [int-x : Integer (in-range x-min (- x-max 1))]) (define i00 (fx+ int-x (fx* int-y w))) (define i01 (fx+ i00 1)) (define i10 (fx+ i00 w)) @@ -327,8 +331,9 @@ ;; =================================================================================================== ;; Pass 2: tracing from a directional viewer -(: trace-directional-view (flomap flomap flomap flomap flomap -> (values flomap flomap))) -(define (trace-directional-view alpha-fm rgb-fm z-fm normal-fm shadow-fm) +(: trace-directional-view (flomap flomap flomap flomap flomap Integer Integer Integer Integer + -> (values flomap flomap))) +(define (trace-directional-view alpha-fm rgb-fm z-fm normal-fm shadow-fm x-min x-max y-min y-max) (define-values (w h) (flomap-size alpha-fm)) (match-define (list alpha-vs rgb-vs z-vs normal-vs shadow-vs) (map flomap-values (list alpha-fm rgb-fm z-fm normal-fm shadow-fm))) @@ -364,7 +369,8 @@ (define transmitted-vs (flomap-values transmitted-fm)) (when (or (Ri . > . 0.0) (Ti . > . 0.0)) - (for*: ([int-y : Integer (in-range h)] [int-x : Integer (in-range w)]) + (for*: ([int-y : Integer (in-range y-min y-max)] + [int-x : Integer (in-range x-min x-max)]) (define i (fx+ int-x (fx* int-y w))) (define a (unsafe-flvector-ref alpha-vs i)) (when (a . > . 0.0) @@ -497,10 +503,11 @@ (define z-fm (fmmax 0.0 (deep-flomap-z dfm))) (define normal-fm (flomap-gradient-normal z-fm)) (define bg-fm (if background-fm (prep-background background-fm w h) #f)) + (define-values (_1 x-min y-min _2 x-max y-max) (flomap-nonzero-rect alpha-fm)) ;; pass 1: trace from the light source (define-values (diffracted-fm raw-shadow-fm) - (trace-directional-light alpha-fm rgb-fm z-fm normal-fm)) + (trace-directional-light alpha-fm rgb-fm z-fm normal-fm x-min x-max y-min y-max)) ;; blur the shadow to simulate internal scatter (define σ (* (min w h) (shadow-blur))) @@ -517,7 +524,7 @@ ;; pass 2: trace from the viewer (define-values (reflected-fm transmitted-fm) - (trace-directional-view alpha-fm rgb-fm z-fm normal-fm shadow-fm)) + (trace-directional-view alpha-fm rgb-fm z-fm normal-fm shadow-fm x-min x-max y-min y-max)) ;; add all the light together, convert to premultiplied-alpha flomap (let* ([fm (fm+ (fm+ diffracted-fm transmitted-fm) reflected-fm)] From d637be4b710be2976712a94e4cfde6225dade9ee Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Wed, 11 Jan 2012 21:24:44 -0700 Subject: [PATCH 471/746] Use running stickman in lower-right "run" indicator Please merge into release (cherry picked from commit 436a1dcb7167d56e8c0f79da7954c53efbbaedb7) --- collects/drracket/private/unit.rkt | 86 +++++++++++++----------------- 1 file changed, 36 insertions(+), 50 deletions(-) diff --git a/collects/drracket/private/unit.rkt b/collects/drracket/private/unit.rkt index c6e7167d37..6179fab9d0 100644 --- a/collects/drracket/private/unit.rkt +++ b/collects/drracket/private/unit.rkt @@ -39,7 +39,7 @@ module browser threading seems wrong. "eval-helpers.rkt" (prefix-in drracket:arrow: "../arrow.rkt") (prefix-in icons: (combine-in images/icons/file images/icons/control images/icons/style - images/logos)) + images/icons/stickman images/logos)) mred (prefix-in mred: mred) @@ -4395,66 +4395,52 @@ module browser threading seems wrong. ; ; - - (define running-bitmap (include-bitmap (lib "icons/b-run.png"))) - (define waiting-bitmap (include-bitmap (lib "icons/b-wait.png"))) - (define waiting2-bitmap (include-bitmap (lib "icons/b-wait2.png"))) - (define running/waiting-bitmaps (list running-bitmap waiting-bitmap waiting2-bitmap)) (define running-canvas% (class canvas% (inherit get-dc refresh get-client-size) - (define/public (set-running r?) - (unless (eq? r? is-running?) - (set! is-running? r?) - (refresh))) - (define is-running? #f) - (define toggle? #t) - (define timer #f) - (define inside? #f) - (define/override (on-event evt) - (let-values ([(w h) (get-client-size)]) - (let ([new-inside? - (and (< 0 (send evt get-x) w) - (< 0 (send evt get-y) h))] - [old-inside? inside?]) - (set! inside? new-inside?) - (cond - [(and new-inside? (not old-inside?)) - (unless is-running? - (set! timer - (new timer% - [notify-callback - (λ () - (set! toggle? (not toggle?)) - (refresh))] - [interval 200])))] - [(and (not new-inside?) old-inside? timer) - (send timer stop) - (set! timer #f)])))) + (define stickman-height 18) + (define num-running-frames 12) + (define frame-delay 200) ; 5 FPS at the most (when the user program is blocked or waiting) + (define running-frames + (for/vector ([t (in-range 0 1 (/ 1 num-running-frames))]) + (icons:running-stickman-icon t icons:run-icon-color "white" icons:run-icon-color + stickman-height))) + (define standing-frame + (icons:standing-stickman-icon icons:run-icon-color "white" icons:run-icon-color + stickman-height)) + + (define all-running-frames + (cons standing-frame (vector->list running-frames))) + + (define is-running? #f) + (define frame 0) + (define timer (make-object timer% (λ () (refresh) (yield)) #f)) + + (define/public (set-running r?) + (cond [r? (unless is-running? (set! frame 4)) + (send timer start frame-delay #f)] + [else (send timer stop) + (refresh)]) + (set! is-running? r?)) (define/override (on-paint) - (let ([dc (get-dc)] - [bm - (if is-running? - running-bitmap - (if toggle? - waiting-bitmap - waiting2-bitmap))]) - (let-values ([(cw ch) (get-client-size)]) - (send dc draw-bitmap bm - (- (/ cw 2) (/ (send bm get-width) 2)) - (- (/ ch 2) (/ (send bm get-height) 2)) - 'solid - (send the-color-database find-color "black") - (send bm get-loaded-mask))))) + (define dc (get-dc)) + (define bm (cond [is-running? (define bm (vector-ref running-frames frame)) + (set! frame (modulo (+ frame 1) num-running-frames)) + bm] + [else standing-frame])) + (define-values (w h) (get-client-size)) + (send dc draw-bitmap bm + (- (/ w 2) (/ (send bm get-width) 2)) + (- (/ h 2) (/ (send bm get-height) 2)))) (super-new [stretchable-width #f] [stretchable-height #f] [style '(transparent no-focus)]) (inherit min-width min-height) - (min-width (apply max (map (λ (x) (send x get-width)) running/waiting-bitmaps))) - (min-height (apply max (map (λ (x) (send x get-height)) running/waiting-bitmaps))))) + (min-width (apply max (map (λ (x) (send x get-width)) all-running-frames))) + (min-height (apply max (map (λ (x) (send x get-height)) all-running-frames))))) ;; get-mbytes : top-level-window -> (union #f ;; cancel ;; integer[>=100] ;; a limit From 2f6193a7f89149576ca2b14b0905a77f41c2ce5a Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Wed, 11 Jan 2012 22:35:40 -0700 Subject: [PATCH 472/746] Text icon fix - works better when trimmed Recycle icon (text icon of string "\u267b") Removed debug output from plt-logo Slightly faster bitmap <-> flomap conversion (uses bitmap%'s premultiply-alpha) Please merge into release (cherry picked from commit 5dcfd76927d80c099ea1875eb5df887c0ef5848a) --- collects/images/icons/misc.rkt | 11 +++++++++-- collects/images/logos.rkt | 15 +++------------ collects/images/private/flomap-convert.rkt | 16 ++++++---------- collects/images/private/utils.rkt | 7 ++++++- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/collects/images/icons/misc.rkt b/collects/images/icons/misc.rkt index e334194906..493ed64fba 100644 --- a/collects/images/icons/misc.rkt +++ b/collects/images/icons/misc.rkt @@ -60,10 +60,13 @@ (define weight (send font get-weight)) (define underline? (send font get-underlined)) (define smoothing (send font get-smoothing)) + (define size + (let* ([size (inexact->exact (ceiling height))]) + (min 255 (if trim? (* 2 size) size)))) + (make-cached-flomap [height str family style weight underline? smoothing color trim? outline? material] - (let ([font (make-object font% (min 255 (inexact->exact (ceiling height))) - family style weight underline? smoothing #t)]) + (let ([font (make-object font% size family style weight underline? smoothing #t)]) (define-values (w h) (get-text-size str font)) (define outline-amt (if outline? (/ height 32) 0)) (define ceiling-amt (inexact->exact (ceiling outline-amt))) @@ -80,6 +83,9 @@ fm)) (flomap-render-icon fm material)))) +(define (recycle-flomap color [height (default-icon-height)] [material (default-icon-material)]) + (text-flomap "♻" (make-object font% 64 'default) color #t #t height material)) + (define (x-flomap color [height (default-icon-height)] [material (default-icon-material)]) (make-cached-flomap [height color material] @@ -287,6 +293,7 @@ ;; Bitmaps (icons) (define text-icon (compose flomap->bitmap text-flomap)) +(define recycle-icon (compose flomap->bitmap recycle-flomap)) (define regular-polygon-icon (compose flomap->bitmap regular-polygon-flomap)) (define octagon-icon (compose flomap->bitmap octagon-flomap)) (define x-icon (compose flomap->bitmap x-flomap)) diff --git a/collects/images/logos.rkt b/collects/images/logos.rkt index 56da35d64e..c397aa2012 100644 --- a/collects/images/logos.rkt +++ b/collects/images/logos.rkt @@ -127,16 +127,11 @@ (let* ([bulge-dfm (flomap->deep-flomap bulge-fm)] [bulge-dfm (deep-flomap-bulge-spheroid bulge-dfm (* 112 scale))] - ;[bulge-dfm (deep-flomap-raise bulge-dfm (* 8 scale))] - ;[bulge-dfm (deep-flomap-smooth-z bulge-dfm (* 1/2 scale))] - #;[bulge-dfm (deep-flomap (deep-flomap-argb bulge-dfm) - (flomap-rough (deep-flomap-z bulge-dfm) 0.5))] [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 112 scale))] [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] - [lambda-fm (time (printf "render lam:~n") - (deep-flomap-render-icon lambda-dfm metal-material))] - [fm (time (printf "render fm:~n") (deep-flomap-render-icon bulge-dfm glass-logo-material))] + [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] + [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] [fm (flomap-cc-superimpose fm (lambda-flomap lambda-outline-color 10) @@ -153,11 +148,6 @@ fm)]) fm))) -(define (plt-logo height) - (define fm (plt-flomap height)) - (time (printf "flomap->bitmap:~n") - (flomap->bitmap fm))) - (define continents-path-commands '((m 11.526653 18.937779) (c 0.05278 0.724075 1.940414 1.202607 0.678885 2.296248 @@ -293,4 +283,5 @@ earth-fm land-fm))) +(define plt-logo (compose flomap->bitmap plt-flomap)) (define planet-logo (compose flomap->bitmap planet-flomap)) diff --git a/collects/images/private/flomap-convert.rkt b/collects/images/private/flomap-convert.rkt index 47d359ce89..8343c5a44f 100644 --- a/collects/images/private/flomap-convert.rkt +++ b/collects/images/private/flomap-convert.rkt @@ -18,10 +18,8 @@ (define w (send bm get-width)) (define h (send bm get-height)) (define bs (make-bytes (* 4 w h))) - ;; get bytes without premultiplying alpha because doing it in flonums maintains precision - ;; (if RGB bytes are stored without premultiplying alpha) - (send bm get-argb-pixels 0 0 w h bs #t) - (send bm get-argb-pixels 0 0 w h bs #f) + (send bm get-argb-pixels 0 0 w h bs #t #t) + (send bm get-argb-pixels 0 0 w h bs #f #t) (define argb-fm (make-flomap 4 w h)) (define argb-vs (flomap-values argb-fm)) @@ -38,7 +36,7 @@ (unsafe-flvector-set! argb-vs i2 (unsafe-fl/ (unsafe-fx->fl g) 255.0)) (unsafe-flvector-set! argb-vs i3 (unsafe-fl/ (unsafe-fx->fl b) 255.0))) - (flomap-multiply-alpha argb-fm)) + argb-fm) (define (flomap->bitmap fm) (match-define (flomap vs c w h) fm) @@ -52,9 +50,7 @@ [(4) fm] [else (raise-type-error 'flomap->bitmap "flomap with 1, 2, 3 or 4 components" fm)])] ;; inset if zero (bitmaps can't have zero size) - [fm (flomap-inset fm 0 0 (if (= w 0) 1 0) (if (= h 0) 1 0))] - ;; divide alphas before converting - [fm (flomap-divide-alpha fm)]) + [fm (flomap-inset fm 0 0 (if (= w 0) 1 0) (if (= h 0) 1 0))]) ;; guaranteed an ARGB flomap now (match-define (flomap vs 4 w h) fm) (define bs (make-bytes (* 4 w h))) @@ -72,8 +68,8 @@ (unsafe-bytes-set! bs i3 (unsafe-fl->byte (unsafe-fl* 255.0 b)))) (define bm (make-bitmap w h)) - (send bm set-argb-pixels 0 0 w h bs #t) - (send bm set-argb-pixels 0 0 w h bs #f) + (send bm set-argb-pixels 0 0 w h bs #t #t) + (send bm set-argb-pixels 0 0 w h bs #f #t) bm)) (define (draw-flomap w h draw-proc) diff --git a/collects/images/private/utils.rkt b/collects/images/private/utils.rkt index 08b96724f5..19b60aaa0e 100644 --- a/collects/images/private/utils.rkt +++ b/collects/images/private/utils.rkt @@ -6,6 +6,9 @@ (provide (all-defined-out)) +;; =================================================================================================== +;; Caching flomaps with a hash table of weak box values + (define num-callbacks 0) (define (get-num-callbacks) num-callbacks) @@ -74,7 +77,9 @@ (with-syntax ([(name) (generate-temporaries #'(make-cached-flomap))]) (syntax/loc stx (make-cached-flomap* 'name (λ (size args ...) expr0 expr ...) size args ...)))])) - + +;; =================================================================================================== +;; Drawing (define (draw-ellipse/smoothed dc x y w h) (define pen (send dc get-pen)) From ed172a81fa0b151b4703baa5ad314a7b12115423 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Thu, 12 Jan 2012 21:48:41 -0700 Subject: [PATCH 473/746] Removed accidental dependence of images/icons/stickman on racket/gui Began scribble docs Added `compiled-bitmap' and `compiled-bitmap-list', which embed bitmaps computed at expansion time into compiled files (safe 3D values) Please merge into release (cherry picked from commit 4d1cedc913402858582796a33e9df384714f9072) --- collects/drracket/private/debug.rkt | 9 +- collects/drracket/private/unit.rkt | 74 ++-- .../drracket/syncheck-drracket-button.rkt | 9 +- collects/gui-debugger/debug-tool.rkt | 7 +- collects/images/compile-time.rkt | 29 ++ collects/images/icons/arrow.rkt | 119 ++++-- collects/images/icons/stickman.rkt | 15 +- collects/images/icons/style.rkt | 29 ++ collects/images/info.rkt | 6 + collects/images/private/utils.rkt | 7 + .../images/scribblings/compile-time.scrbl | 11 + collects/images/scribblings/icons.scrbl | 366 ++++++++++++++++++ collects/images/scribblings/images.scrbl | 14 + collects/images/scribblings/logos.scrbl | 11 + collects/images/tests/icon-tests.rkt | 19 +- collects/macro-debugger/tool.rkt | 9 +- 16 files changed, 638 insertions(+), 96 deletions(-) create mode 100644 collects/images/compile-time.rkt create mode 100644 collects/images/info.rkt create mode 100644 collects/images/scribblings/compile-time.scrbl create mode 100644 collects/images/scribblings/icons.scrbl create mode 100644 collects/images/scribblings/images.scrbl create mode 100644 collects/images/scribblings/logos.scrbl diff --git a/collects/drracket/private/debug.rkt b/collects/drracket/private/debug.rkt index b81bfd88e6..0ffa8f56fd 100644 --- a/collects/drracket/private/debug.rkt +++ b/collects/drracket/private/debug.rkt @@ -26,7 +26,8 @@ profile todo: net/url racket/match mrlib/include-bitmap - images/icons/misc images/icons/style images/icons/control images/logos + images/compile-time + (for-syntax images/icons/misc images/icons/style images/icons/control images/logos) (for-syntax racket/base)) (define orig (current-output-port)) @@ -187,11 +188,11 @@ profile todo: (super-make-object bitmap))]) note%))) - (define file-note% (make-note% "stop-22x22.png" (stop-sign-icon halt-icon-color))) - (define bug-note% (make-note% "stop-multi.png" (stop-signs-icon halt-icon-color))) + (define file-note% (make-note% "stop-22x22.png" (compiled-bitmap (stop-sign-icon halt-icon-color)))) + (define bug-note% (make-note% "stop-multi.png" (compiled-bitmap (stop-signs-icon halt-icon-color)))) (define mf-note% (make-note% "mf.gif" (include-bitmap (lib "icons/mf.gif") 'gif))) - (define small-planet-bitmap (planet-logo (default-icon-height))) + (define small-planet-bitmap (compiled-bitmap (planet-logo (default-icon-height)))) (define planet-note% (make-note% "small-planet.png" small-planet-bitmap)) ;; display-stats : (syntax -> syntax) diff --git a/collects/drracket/private/unit.rkt b/collects/drracket/private/unit.rkt index 6179fab9d0..ec058b7bc4 100644 --- a/collects/drracket/private/unit.rkt +++ b/collects/drracket/private/unit.rkt @@ -38,9 +38,7 @@ module browser threading seems wrong. "local-member-names.rkt" "eval-helpers.rkt" (prefix-in drracket:arrow: "../arrow.rkt") - (prefix-in icons: (combine-in images/icons/file images/icons/control images/icons/style - images/icons/stickman images/logos)) - + (prefix-in icons: images/compile-time) mred (prefix-in mred: mred) @@ -69,6 +67,46 @@ module browser threading seems wrong. (let ([fw (collection-path "framework")]) (directory-exists? (build-path fw 'up 'up ".git")))))) +;; =================================================================================================== +;; Compiled bitmaps + +(require (for-syntax + racket/base + (prefix-in icons: (combine-in images/icons/file images/icons/control images/icons/style + images/icons/stickman images/logos)))) + +(define execute-bitmap + (icons:compiled-bitmap (icons:play-icon icons:run-icon-color (icons:toolbar-icon-height)))) +(define break-bitmap + (icons:compiled-bitmap (icons:stop-icon icons:halt-icon-color (icons:toolbar-icon-height)))) +(define small-save-bitmap + (icons:compiled-bitmap (icons:small-save-icon icons:syntax-icon-color "gold" + (icons:toolbar-icon-height)))) +(define save-bitmap + (icons:compiled-bitmap (icons:save-icon icons:syntax-icon-color "gold" + (icons:toolbar-icon-height)))) + +(begin-for-syntax + (define stickman-height 18) + (define num-running-frames 12)) + +(define running-frame-list + (icons:compiled-bitmap-list + (for/list ([t (in-range 0 1 (/ 1 num-running-frames))]) + (icons:running-stickman-icon t icons:run-icon-color "white" icons:run-icon-color + stickman-height)))) +(define running-frames (list->vector running-frame-list)) + +(define standing-frame + (icons:compiled-bitmap + (icons:standing-stickman-icon icons:run-icon-color "white" icons:run-icon-color + stickman-height))) + +(define very-small-planet-bitmap + (icons:compiled-bitmap (icons:planet-logo (icons:toolbar-icon-height)))) + +;; =================================================================================================== + (define-unit unit@ (import [prefix help-desk: drracket:help-desk^] [prefix drracket:app: drracket:app^] @@ -386,13 +424,6 @@ module browser threading seems wrong. frame program-filename)))]))) - (define execute-bitmap (icons:play-icon icons:run-icon-color (icons:toolbar-icon-height))) - (define break-bitmap (icons:stop-icon icons:halt-icon-color (icons:toolbar-icon-height))) - (define small-save-bitmap (icons:small-save-icon icons:syntax-icon-color "gold" - (icons:toolbar-icon-height))) - (define save-bitmap (icons:save-icon icons:syntax-icon-color "gold" - (icons:toolbar-icon-height))) - (define-values (get-program-editor-mixin add-to-program-editor-mixin) (let* ([program-editor-mixin (mixin (editor:basic<%> (class->interface text%)) () @@ -4399,27 +4430,15 @@ module browser threading seems wrong. (class canvas% (inherit get-dc refresh get-client-size) - (define stickman-height 18) - (define num-running-frames 12) - (define frame-delay 200) ; 5 FPS at the most (when the user program is blocked or waiting) - (define running-frames - (for/vector ([t (in-range 0 1 (/ 1 num-running-frames))]) - (icons:running-stickman-icon t icons:run-icon-color "white" icons:run-icon-color - stickman-height))) - (define standing-frame - (icons:standing-stickman-icon icons:run-icon-color "white" icons:run-icon-color - stickman-height)) - - (define all-running-frames - (cons standing-frame (vector->list running-frames))) - + (define running-frame-delay 200) ; 5 FPS at the most (if user program is blocked or waiting) + (define num-running-frames (vector-length running-frames)) (define is-running? #f) (define frame 0) (define timer (make-object timer% (λ () (refresh) (yield)) #f)) (define/public (set-running r?) (cond [r? (unless is-running? (set! frame 4)) - (send timer start frame-delay #f)] + (send timer start running-frame-delay #f)] [else (send timer stop) (refresh)]) (set! is-running? r?)) @@ -4438,7 +4457,10 @@ module browser threading seems wrong. (super-new [stretchable-width #f] [stretchable-height #f] [style '(transparent no-focus)]) + (inherit min-width min-height) + + (define all-running-frames (cons standing-frame running-frame-list)) (min-width (apply max (map (λ (x) (send x get-width)) all-running-frames))) (min-height (apply max (map (λ (x) (send x get-height)) all-running-frames))))) @@ -4683,8 +4705,6 @@ module browser threading seems wrong. [(null? l) '()] [else (cons (car l) (loop (cdr l) (- n 1)))]))) - (define very-small-planet-bitmap (icons:planet-logo (icons:toolbar-icon-height))) - (define saved-bug-reports-window #f) (define saved-bug-reports-panel #f) (define (init-saved-bug-reports-window) diff --git a/collects/drracket/syncheck-drracket-button.rkt b/collects/drracket/syncheck-drracket-button.rkt index 56f4d19dae..e732a3e37f 100644 --- a/collects/drracket/syncheck-drracket-button.rkt +++ b/collects/drracket/syncheck-drracket-button.rkt @@ -2,7 +2,8 @@ (require racket/class racket/gui/base string-constants/string-constant - images/icons/tool images/icons/style) + images/compile-time + (for-syntax racket/base images/icons/tool images/icons/style)) (provide syncheck-drracket-button syncheck-bitmap syncheck-small-bitmap @@ -10,8 +11,10 @@ (define-local-member-name syncheck:button-callback) -(define syncheck-bitmap (check-syntax-icon (toolbar-icon-height))) -(define syncheck-small-bitmap (small-check-syntax-icon (toolbar-icon-height))) +(define syncheck-bitmap + (compiled-bitmap (check-syntax-icon (toolbar-icon-height)))) +(define syncheck-small-bitmap + (compiled-bitmap (small-check-syntax-icon (toolbar-icon-height)))) (define syncheck-drracket-button (list diff --git a/collects/gui-debugger/debug-tool.rkt b/collects/gui-debugger/debug-tool.rkt index eb6c04ae64..2622888a72 100644 --- a/collects/gui-debugger/debug-tool.rkt +++ b/collects/gui-debugger/debug-tool.rkt @@ -15,7 +15,8 @@ framework string-constants lang/debugger-language-interface - images/icons/tool) + images/compile-time + (for-syntax images/icons/tool)) (provide tool@) @@ -1082,8 +1083,8 @@ (super-new))) - (define debug-bitmap (debugger-icon)) - (define small-debug-bitmap (small-debugger-icon)) + (define debug-bitmap (compiled-bitmap (debugger-icon))) + (define small-debug-bitmap (compiled-bitmap (small-debugger-icon))) (define make-pause-label (bitmap-label-maker diff --git a/collects/images/compile-time.rkt b/collects/images/compile-time.rkt new file mode 100644 index 0000000000..819f480ce7 --- /dev/null +++ b/collects/images/compile-time.rkt @@ -0,0 +1,29 @@ +#lang racket/base + +(require (for-syntax racket/base racket/class racket/draw) + racket/class racket/draw) + +(provide compiled-bitmap compiled-bitmap-list) + +(define-for-syntax (make-3d-bitmap ctxt bm) + (define p (open-output-bytes)) + (send bm save-file p 'png) + (with-syntax ([bs (datum->syntax ctxt (get-output-bytes p))]) + (syntax/loc ctxt + (make-object bitmap% (open-input-bytes bs) 'png/alpha)))) + +(define-syntax (compiled-bitmap stx) + (syntax-case stx () + [(_ expr) (syntax/loc stx + (let-syntax ([maker (λ (inner-stx) (make-3d-bitmap inner-stx expr))]) + (maker)))])) + +(define-syntax (compiled-bitmap-list stx) + (syntax-case stx () + [(_ expr) + (syntax/loc stx + (let-syntax ([maker (λ (inner-stx) + (with-syntax ([(bm (... ...)) + (map (λ (e) (make-3d-bitmap inner-stx e)) expr)]) + #'(list bm (... ...))))]) + (maker)))])) diff --git a/collects/images/icons/arrow.rkt b/collects/images/icons/arrow.rkt index 861cb50954..e15626e6b1 100644 --- a/collects/images/icons/arrow.rkt +++ b/collects/images/icons/arrow.rkt @@ -1,23 +1,39 @@ #lang racket/base -(require racket/class +(require racket/class racket/draw + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" "style.rkt") -(provide (all-defined-out)) +(provide + (activate-contract-out + flat-right-arrow-flomap + flat-right-over-arrow-flomap + right-arrow-flomap left-arrow-flomap up-arrow-flomap down-arrow-flomap + right-over-arrow-flomap left-over-arrow-flomap + right-under-arrow-flomap left-under-arrow-flomap + right-arrow-icon left-arrow-icon up-arrow-icon down-arrow-icon + right-over-arrow-icon left-over-arrow-icon + right-under-arrow-icon left-under-arrow-icon) + (only-doc-out (all-defined-out))) -(define (flat-right-arrow-flomap color height) - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-brush color 'solid) - (send dc draw-polygon (list '(0 . 9) '(15 . 9) '(14 . 0) - '(31 . 15.5) - '(14 . 31) '(15 . 22) '(0 . 22)))) - (/ height 32))) +(defproc (flat-right-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0))] + ) flomap? + (let ([color (->color% color)]) + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-brush color 'solid) + (send dc draw-polygon (list '(0 . 9) '(15 . 9) '(14 . 0) + '(31 . 15.5) + '(14 . 31) '(15 . 22) '(0 . 22)))) + (/ height 32)))) -(define (flat-right-over-arrow-flomap color height) +(defproc (flat-right-over-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0))] + ) flomap? (draw-icon-flomap 32 32 (λ (dc) (send dc set-brush color 'solid) @@ -29,55 +45,72 @@ (l -4 -4)))) (/ height 32))) -(define (flomap-render-short-icon fm material) - (define scale (/ (flomap-height fm) 32)) - (define dfm - (let* ([dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* -12 scale))]) - dfm)) - (deep-flomap-render-icon dfm material)) - -(define (right-arrow-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (right-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] - (flomap-render-short-icon (flat-right-arrow-flomap color height) material))) + (flomap-render-thin-icon (flat-right-arrow-flomap color height) material))) -(define (up-arrow-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (up-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (flomap-render-icon (flomap-cw-rotate (flat-right-arrow-flomap color height)) material))) -(define (down-arrow-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (down-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (flomap-render-icon (flomap-ccw-rotate (flat-right-arrow-flomap color height)) material))) -(define (right-over-arrow-flomap color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (right-over-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] - (flomap-render-short-icon (flat-right-over-arrow-flomap color height) material))) + (flomap-render-thin-icon (flat-right-over-arrow-flomap color height) material))) -(define (right-under-arrow-flomap color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (right-under-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] - (flomap-render-short-icon + (flomap-render-thin-icon (flomap-flip-vertical (flat-right-over-arrow-flomap color height)) material))) -(define left-arrow-flomap (compose flomap-flip-horizontal right-arrow-flomap)) -(define left-over-arrow-flomap (compose flomap-flip-horizontal right-over-arrow-flomap)) -(define left-under-arrow-flomap (compose flomap-flip-horizontal right-under-arrow-flomap)) +(defproc (left-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (right-arrow-flomap color height material))) -(define right-arrow-icon (compose flomap->bitmap right-arrow-flomap)) -(define left-arrow-icon (compose flomap->bitmap left-arrow-flomap)) -(define up-arrow-icon (compose flomap->bitmap up-arrow-flomap)) -(define down-arrow-icon (compose flomap->bitmap down-arrow-flomap)) -(define right-over-arrow-icon (compose flomap->bitmap right-over-arrow-flomap)) -(define left-over-arrow-icon (compose flomap->bitmap left-over-arrow-flomap)) -(define right-under-arrow-icon (compose flomap->bitmap right-under-arrow-flomap)) -(define left-under-arrow-icon (compose flomap->bitmap left-under-arrow-flomap)) +(defproc (left-over-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (right-over-arrow-flomap color height material))) + +(defproc (left-under-arrow-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (right-under-arrow-flomap color height material))) + +(define-simple-icon-wrapper left-arrow-icon left-arrow-flomap) +(define-simple-icon-wrapper right-arrow-icon right-arrow-flomap) +(define-simple-icon-wrapper up-arrow-icon up-arrow-flomap) +(define-simple-icon-wrapper down-arrow-icon down-arrow-flomap) + +(define-simple-icon-wrapper right-over-arrow-icon right-over-arrow-flomap) +(define-simple-icon-wrapper left-over-arrow-icon left-over-arrow-flomap) +(define-simple-icon-wrapper right-under-arrow-icon right-under-arrow-flomap) +(define-simple-icon-wrapper left-under-arrow-icon left-under-arrow-flomap) diff --git a/collects/images/icons/stickman.rkt b/collects/images/icons/stickman.rkt index 574825a91d..cd6cf8124f 100644 --- a/collects/images/icons/stickman.rkt +++ b/collects/images/icons/stickman.rkt @@ -1,6 +1,6 @@ -#lang racket/gui +#lang racket/base -(require racket/class racket/snip racket/vector +(require racket/class racket/vector racket/match racket/math "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" @@ -100,13 +100,6 @@ (polar->cartesian (+ standing-right-elbow-angle standing-torso-angle standing-right-hand-angle) lower-arm-length))) -(define (draw-short-rendered-icon-flomap w h proc scale material) - (let* ([fm (draw-icon-flomap w h proc scale)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* -18 (/ (flomap-height fm) 32)))]) - (deep-flomap-render-icon dfm material))) - (define (standing-stickman-flomap color arm-color head-color [height (default-icon-height)] [material (default-icon-material)]) @@ -298,9 +291,9 @@ (define standing-stickman-icon (compose flomap->bitmap standing-stickman-flomap)) (define running-stickman-icon (compose flomap->bitmap running-stickman-flomap)) -#; +#;; FOR TESTING ONLY: Do not let this find its way into the repo uncommented! (begin - (require (planet "animated-canvas.rkt" ("williams" "animated-canvas.plt" 2 4))) + (require racket/gui (planet "animated-canvas.rkt" ("williams" "animated-canvas.plt" 2 4))) (define size 20) diff --git a/collects/images/icons/style.rkt b/collects/images/icons/style.rkt index ae3c8184b3..f40a5454cd 100644 --- a/collects/images/icons/style.rkt +++ b/collects/images/icons/style.rkt @@ -1,6 +1,7 @@ #lang racket (require racket/draw unstable/parameter-group + racket/contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt") @@ -70,3 +71,31 @@ (let* ([fm (draw-icon-flomap w h draw-proc scale)] [fm (flomap-render-icon fm material)]) fm)) + +;; TODO: make one of the following functions unnecessary + +(define (flomap-render-thin-icon fm material) + (define scale (/ (flomap-height fm) 32)) + (define dfm + (let* ([dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-raise dfm (* -12 scale))]) + dfm)) + (deep-flomap-render-icon dfm material)) + +(define (draw-short-rendered-icon-flomap w h proc scale material) + (let* ([fm (draw-icon-flomap w h proc scale)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-raise dfm (* -12 (/ (flomap-height fm) 32)))]) + (deep-flomap-render-icon dfm material))) + +;; =================================================================================================== +;; Syntax for writing icon functions + +(define-syntax-rule (define-simple-icon-wrapper icon-fun flomap-fun) + (defproc (icon-fun [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (flomap-fun color height material)))) diff --git a/collects/images/info.rkt b/collects/images/info.rkt new file mode 100644 index 0000000000..c5d1c4cbdb --- /dev/null +++ b/collects/images/info.rkt @@ -0,0 +1,6 @@ +#lang setup/infotab + +(define scribblings '(["scribblings/images.scrbl" (multi-page) (gui-library)])) + +(define compile-omit-paths '("tests")) + diff --git a/collects/images/private/utils.rkt b/collects/images/private/utils.rkt index 19b60aaa0e..e9256a570a 100644 --- a/collects/images/private/utils.rkt +++ b/collects/images/private/utils.rkt @@ -81,6 +81,13 @@ ;; =================================================================================================== ;; Drawing +(define (->color% c) + (match c + [(list r g b) (make-object color% r g b)] + [(? (is-a?/c color%)) c] + [(? string?) (send the-color-database find-color c)] + [else (raise-type-error '->color% "list, color% or string" c)])) + (define (draw-ellipse/smoothed dc x y w h) (define pen (send dc get-pen)) (define brush (send dc get-brush)) diff --git a/collects/images/scribblings/compile-time.scrbl b/collects/images/scribblings/compile-time.scrbl new file mode 100644 index 0000000000..b23069dada --- /dev/null +++ b/collects/images/scribblings/compile-time.scrbl @@ -0,0 +1,11 @@ +#lang scribble/manual + +@(require scribble/eval + (for-label images/compile-time + racket) + images/compile-time) + +@(define (author-email) "neil.toronto@gmail.com") + +@title{Embedding Computed Bitmaps in Source Files} +@author{@(author+email "Neil Toronto" (author-email))} diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl new file mode 100644 index 0000000000..58a193f50d --- /dev/null +++ b/collects/images/scribblings/icons.scrbl @@ -0,0 +1,366 @@ +#lang scribble/manual + +@(require scribble/eval + unstable/latent-contract/defthing + (for-label images/icons/arrow + mrlib/switchable-button + racket + racket/draw) + images/icons/arrow) + +@(define (author-email) "neil.toronto@gmail.com") + +@title{Icons} +@author{@(author+email "Neil Toronto" (author-email))} + + +@(define icons-eval (make-base-eval)) +@interaction-eval[#:eval icons-eval (require racket/math racket/list images/icons/style)] + +@;{ +@section{Introduction (What is an icon, really?)} +@margin-note*{This introduction describes an ideal, not necessarily the current state of things.} + +As a first approximation, an icon is just a small bitmap with an alpha channel. +But the icons in this collection are not simply loaded from disk. +They are generated programmatically by drawing on a @racket[dc<%>], +Icons can also be rendered , resized, generated programmatically by drawing on a , or composed using @racket[pict] functions. + +The @racketmodname[icons] module is intended to make it possible to do all of these things, and to make it easy to get common icons in different colors, heights and styles. + +An icon communicates. Its shape and color are a visual metaphor for an action or a message. Icons should be easily recognizable, distinguishable, visually consistent, and metaphorically appropriate for the actions and messages they are used with. This is difficult to do well, but good examples, good abstractions, and an existing icon library help considerably. + +@(define (hash-quote) (hash-quote-flomap (solid-icon-color '(41 128 38)) 16)) +@(define (step) (step-flomap (solid-icon-color "blue") 16 'diffuse)) +@(define (macro-stepper) (ht-append (hash-quote) (step))) + +Example: The Macro Stepper tool composes a new icon @(hash-quote) and an existing icon @(step), resulting in @(macro-stepper) for its toolbar icon. +The @(hash-quote) icon connotes syntax, and is the color of a syntax-quote as rendered by DrRacket by default. +The @(step) icon is colored like DrRacket colors identifier syntax by default, and is shaped using metaphors used in debugger toolbars, TV remotes, and music players around the world. +It is composed of @(go-icon (solid-icon-color "blue") 16 'diffuse) to connote starting and @(bar-icon (solid-icon-color "blue") 16 'diffuse) to connote immediately stopping---a ``step.'' + +The author of this collection is available to adapt or create SVG icons for DrRacket tools, and charges no more than your immortal soul. + +@section{Icon Parameters} + +@doc-apply[toolbar-icon-height]{ +The height of DrRacket toolbar icons. + +Use @racket[(toolbar-icon-height)] as the @racket[height] argument when loading common icons that will be used in DrRacket toolbars and buttons, or in the toolbars and buttons of DrRacket tools. + +(When making an icon for DrRacket's main toolbar, try to keep it nearly square so that it will not take up too much horizontal space when the toolbar is docked vertically. +If you cannot, as with the Macro Stepper, send a thinner icon as the @racket[alternate-bitmap] argument to a @racket[switchable-button%].) +} + +@doc-apply[default-icon-height]{ +The height of standard (e.g. not toolbar) DrRacket icons, used as a default argument through the @racketmodname[icons] module. +} + +@doc-apply[default-icon-style]{ +The style of DrRacket icons, used as a default argument throughout the @racketmodname[icons] module. +} +} + +@section[#:tag "arrows"]{Arrow Icons} + +@defmodule[images/icons/arrow] + +@interaction-eval[#:eval icons-eval (require images/icons/arrow)] + +@doc-apply[right-arrow-icon] +@doc-apply[left-arrow-icon] +@doc-apply[up-arrow-icon] +@doc-apply[down-arrow-icon]{ +Cardinal direction arrows. + +@interaction[#:eval icons-eval + (list (right-arrow-icon syntax-icon-color (toolbar-icon-height)) + (left-arrow-icon run-icon-color) + (up-arrow-icon halt-icon-color 37) + (down-arrow-icon "lightblue" 44 glass-icon-material))] +} + +@doc-apply[right-over-arrow-icon] +@doc-apply[left-over-arrow-icon] +@doc-apply[right-under-arrow-icon] +@doc-apply[left-under-arrow-icon]{ +@interaction[#:eval icons-eval + (list (right-over-arrow-icon metal-icon-color (toolbar-icon-height)) + (left-over-arrow-icon dark-metal-icon-color) + (right-under-arrow-icon run-icon-color 37) + (left-under-arrow-icon "lightgreen" 44 glass-icon-material))] +} + +@section[#:tag "control"]{Control Icons} + +@section[#:tag "file"]{File Icons} + +@section[#:tag "tool"]{Tool Icons} + +@section[#:tag "stickman"]{Stickman Icons} + +@section[#:tag "misc"]{Miscellaneous Icons} + +@;{ +@subsection{Control Icons} + +@doc-apply[go-icon] +@doc-apply[bar-icon] +@doc-apply[back-icon] +@doc-apply[stop-icon] +@doc-apply[record-icon] +@doc-apply[step-icon] +@doc-apply[step-back-icon] +@doc-apply[continue-icon] +@doc-apply[continue-back-icon] +@doc-apply[fast-forward-icon] +@doc-apply[rewind-icon] +@doc-apply[pause-icon]{ +These return typical ``playback'' icons. + +@interaction[#:eval icons-eval + (for/list ([make-icon (list rewind-icon continue-back-icon + step-back-icon back-icon + pause-icon stop-icon + go-icon step-icon + continue-icon fast-forward-icon + record-icon)] + [style (in-cycle icon-styles)]) + (make-icon (solid-icon-color "darkseagreen") 32 style))] + +The remaining icon @(bar-icon #f 16), returned by @racket[bar-icon], is used to build the others. +} + +@subsection{Arrow Icons} + +@doc-apply[up-arrow-icon] +@doc-apply[down-arrow-icon] +@doc-apply[left-arrow-icon] +@doc-apply[right-arrow-icon]{ +@examples[#:eval icons-eval + (for/list ([make-icon (list up-arrow-icon down-arrow-icon + left-arrow-icon right-arrow-icon)]) + (for/list ([style (in-list icon-styles)]) + (make-icon (solid-icon-color "brown") (default-icon-height) style)))] +} + +@subsection{Sign Icons} + +@doc-apply[stop-sign-icon]{ +@examples[#:eval icons-eval (list (stop-sign-icon (default-icon-height) 'diffuse) + (stop-sign-icon (default-icon-height) 'shiny))] +} + +@subsection{Check Icons} + +@doc-apply[check-icon]{ +@examples[#:eval icons-eval + (list (check-icon (solid-icon-color "green") 29 'diffuse) + (check-icon (solid-icon-color "green") 29 'shiny))] +} + +@doc-apply[x-icon]{ +@examples[#:eval icons-eval + (for/list ([color icon-colors] + [style (in-cycle icon-styles)]) + (x-icon color 29 style))] +} + +@subsection{Miscellaneous Icons} + +@doc-apply[magnifying-glass-icon]{ +@examples[#:eval icons-eval (list (magnifying-glass-icon 31 'diffuse) + (magnifying-glass-icon 31 'shiny))] +Note that the uncolorized magnifying glass has a brown handle. +} + +@doc-apply[magnifying-glass-left-icon]{ +@examples[#:eval icons-eval (list (magnifying-glass-left-icon 31 'diffuse) + (magnifying-glass-left-icon 31 'shiny))] +} + +@doc-apply[disk-icon]{ +@examples[#:eval icons-eval + (for/list ([color icon-colors] + [style (in-cycle icon-styles)]) + (disk-icon color 33 style))] +} + +@doc-apply[earth-icon]{ +@examples[#:eval icons-eval (list (earth-icon 48 'diffuse) + (earth-icon 48 'shiny))] +} + +@doc-apply[moon-icon]{ +@examples[#:eval icons-eval (list (moon-icon 48 'diffuse) + (moon-icon 48 'shiny))] +} + +@subsection{Symbols} + +@doc-apply[hash-quote-icon]{ +@examples[#:eval icons-eval (list (hash-quote-icon (toolbar-icon-height) 'diffuse) + (hash-quote-icon (toolbar-icon-height) 'shiny))] +} + +@doc-apply[plus-icon]{ +@examples[#:eval icons-eval + (for/list ([color icon-colors] + [style (in-cycle icon-styles)]) + (plus-icon color 24 style))] +} + +@doc-apply[times-icon]{ +@examples[#:eval icons-eval + (for/list ([color icon-colors] + [style (in-cycle icon-styles)]) + (times-icon color 24 style))] +} + +@subsection{Logos} + +@doc-apply[plt-logo]{ +@examples[#:eval icons-eval + (list (plt-logo 128 'diffuse) (plt-logo 128 'shiny))] +} + +@doc-apply[planet-logo]{ +@examples[#:eval icons-eval (list (planet-logo 128 'diffuse) + (planet-logo 128 'shiny))] +} + + +@section{Icon Constants and Contracts} + +@;{ +@doc-apply[icon-colors]{ +A list containing the names of allowed icon colors. + +When an SVG icon source file is rendered, it is rendered once directly. Then, for each color corresponding to a symbol in @racket[icon-colors], it is colorized by replacing gradients, and then rendered. + +When loading an icon, a @racket[#f] color name loads an uncolorized rendering. +Every icon can be loaded with a @racket[#f] color name. +An icon can be loaded using any name in @racket[icon-colors] only if its SVG source has gradients that can be colorized. +See @secref["new-icons"] for details. + +The actual hues associated with the color names are the hues of the first seven @racketmodname[plot] color numbers. +The following example illustrates the correspondence: +@interaction[#:eval icons-eval + (require plot) + (for/list ([color (rest icon-colors)]) + (stop-flomap color 48)) + (parameterize ([plot-width 48] + [plot-height 48] + [plot-decorations? #f] + [plot-background-alpha 0]) + (for/list ([n (in-range 7)]) + (plot3d-pict (surface3d (λ (x y) (- (sqr x) (sqr y))) -1 1 -1 1 + #:color n #:line-color n + #:samples 11 #:line-width 1))))] +This example also shows how to use @racketmodname[plot] to create icon @racket[pict]s from mathematical functions. +}} + +@doc-apply[icon-color/c]{ +A contract that identifies color names. +} + +@doc-apply[icon-styles]{ +Typical icon styles. + +It is not necessary to have a version of each icon in each style. +But if an icon has different styles, it should have these. +} + +@doc-apply[icon-style/c]{ +A contract that identifies icon styles. +} + + +@section{Icon @racket[pict]s} + +@interaction-eval[#:eval icons-eval (require slideshow/pict)] + +It is more flexible, but a little more complicated, to load icons as @racket[pict]s. +As picts, icons can easily be appended, inset, superimposed, blurred, and more. +For example, it is easy to make modern-looking media player controls using @racket[cc-superimpose] and the @racket['shiny] style: +@interaction[#:eval icons-eval + (define media-icon-background (record-flomap 'blue 64 'shiny)) + (list (cc-superimpose media-icon-background + (step-back-flomap 'white 32 'shiny)) + (cc-superimpose media-icon-background + (pause-flomap 'white 32 'shiny)) + (cc-superimpose media-icon-background + (step-flomap 'white 32 'shiny)))] + +Almost all of the functions in preceeding sections are defined in terms of the @racket[pict]-producing functions documented in this section. + +To use these functions effectively, you should require @racketmodname[icons] and @racketmodname[slideshow/pict] together. +Use @racket[bitmap] to convert a @racket[bitmap%] (e.g. an icon) to a @racket[pict], and @racket[pict->bitmap] to convert back. + +Converting from @racket[pict]s to bitmaps can be lossy. For example, converting text can look especially horrible: +@interaction[#:eval icons-eval + (scale (text "Hello" null 10) 5) + (scale (bitmap (pict->bitmap (text "Hello" null 10))) 5)] + +Therefore, when composing icons from parts, try to work only with @racket[pict]s, and convert to an icon using @racket[pict->bitmap] as the last step. + +When composing icons from parts, it is fine to use @racket[pict]s converted from @racket[bitmap%]s. +Without scaling or rotating, the conversion is lossless: +@interaction[#:eval icons-eval + (define not-blurry (magnifying-glass-icon 64 'shiny)) + not-blurry + (for/fold ([icon not-blurry]) ([i (in-range 30)]) + (pict->bitmap (bitmap icon)))] + +Avoid converting between @racket[pict]s and @racket[bitmap%]s more than once if bitmap-backed @racket[pict]s are scaled, rotated by angles that are not multiples of 90 degrees, or superimposed or appended at non-integer coordinates. +Avoid scaling up in general. + +@doc-apply[load-flomap]{ +Corresponds to @racket[load-icon]. In fact, @racket[load-icon] uses @racket[load-flomap] to load the icon as a @racket[pict], and passes it to @racket[pict->bitmap]. +} + +@doc-apply[go-flomap] +@doc-apply[bar-flomap] +@doc-apply[back-flomap] +@doc-apply[stop-flomap] +@doc-apply[record-flomap] +@doc-apply[step-flomap] +@doc-apply[step-back-flomap] +@doc-apply[continue-flomap] +@doc-apply[continue-back-flomap] +@doc-apply[fast-forward-flomap] +@doc-apply[rewind-flomap] +@doc-apply[pause-flomap]{ +These return typical ``playback'' icons, as @racket[pict]s. + +@interaction[#:eval icons-eval + (for/fold ([icon (blank)]) + ([make-flomap (list rewind-flomap continue-back-flomap + step-back-flomap back-flomap + pause-flomap stop-flomap + go-flomap step-flomap + continue-flomap fast-forward-flomap + record-flomap)]) + (hc-append icon (make-flomap 'black 32 'shiny) (blank 12)))] +} + +@doc-apply[up-arrow-flomap]{ Corresponds to @racket[up-arrow-icon]. } +@doc-apply[down-arrow-flomap]{ Corresponds to @racket[down-arrow-icon]. } +@doc-apply[left-arrow-flomap]{ Corresponds to @racket[left-arrow-icon]. } +@doc-apply[right-arrow-flomap]{ Corresponds to @racket[right-arrow-icon]. } + +@doc-apply[stop-sign-flomap]{ Corresponds to @racket[stop-sign-icon]. } +@doc-apply[check-flomap]{ Corresponds to @racket[check-icon]. } +@doc-apply[x-flomap]{ Corresponds to @racket[x-icon]. } +@doc-apply[magnifying-glass-flomap]{ Corresponds to @racket[magnifying-glass-icon]. } +@doc-apply[magnifying-glass-left-flomap]{ Corresponds to @racket[magnifying-glass-left-icon]. } +@doc-apply[disk-flomap]{ Corresponds to @racket[disk-icon]. } +@doc-apply[earth-flomap]{ Corresponds to @racket[earth-icon]. } +@doc-apply[moon-flomap]{ Corresponds to @racket[moon-icon]. } +@doc-apply[hash-quote-flomap]{ Corresponds to @racket[hash-quote-icon]. } +@doc-apply[plus-flomap]{ Corresponds to @racket[plus-icon]. } +@doc-apply[times-flomap]{ Corresponds to @racket[times-icon]. } +@doc-apply[plt-logo-pict]{ Corresponds to @racket[plt-logo]. } +@doc-apply[planet-logo-pict]{ Corresponds to @racket[planet-logo]. } + +} \ No newline at end of file diff --git a/collects/images/scribblings/images.scrbl b/collects/images/scribblings/images.scrbl new file mode 100644 index 0000000000..ec8dfd4cb9 --- /dev/null +++ b/collects/images/scribblings/images.scrbl @@ -0,0 +1,14 @@ +#lang scribble/manual + +@(define (author-email) "neil.toronto@gmail.com") + +@title{Images} +@author{@(author+email "Neil Toronto" (author-email))} + +@table-of-contents[] + +@include-section["icons.scrbl"] + +@include-section["logos.scrbl"] + +@include-section["compile-time.scrbl"] diff --git a/collects/images/scribblings/logos.scrbl b/collects/images/scribblings/logos.scrbl new file mode 100644 index 0000000000..a2fdaa610f --- /dev/null +++ b/collects/images/scribblings/logos.scrbl @@ -0,0 +1,11 @@ +#lang scribble/manual + +@(require scribble/eval + (for-label images/logos + racket) + images/logos) + +@(define (author-email) "neil.toronto@gmail.com") + +@title{Logos} +@author{@(author+email "Neil Toronto" (author-email))} diff --git a/collects/images/tests/icon-tests.rkt b/collects/images/tests/icon-tests.rkt index cc751ff404..fc6817a7f1 100644 --- a/collects/images/tests/icon-tests.rkt +++ b/collects/images/tests/icon-tests.rkt @@ -8,7 +8,10 @@ images/icons/tool images/icons/style images/private/deep-flomap-render - images/private/utils) + images/private/utils + images/compile-time + (for-syntax images/icons/stickman + images/icons/style)) (default-icon-height 16) ;(default-icon-material glass-icon-material) @@ -19,6 +22,20 @@ 0.0)) ;(default-icon-material diamond-material) +;; =================================================================================================== +;; Compiled stickman test + +(begin-for-syntax + (define stickman-height 32) + (define num-running-frames 12)) + +(compiled-bitmap-list + (for/list ([t (in-range 0 1 (/ 1 num-running-frames))]) + (running-stickman-icon t run-icon-color "white" run-icon-color stickman-height))) + +;; =================================================================================================== +;; Other icons, various colors + (define icon-procss (list (list reverse-icon continue-back-icon step-back-icon back-icon pause-icon stop-icon record-icon play-icon step-icon continue-icon fast-forward-icon) diff --git a/collects/macro-debugger/tool.rkt b/collects/macro-debugger/tool.rkt index 8b59fd6893..1d392adf3c 100644 --- a/collects/macro-debugger/tool.rkt +++ b/collects/macro-debugger/tool.rkt @@ -10,7 +10,8 @@ (only-in "view/view.rkt" macro-stepper-director%) "view/stepper.rkt" "view/prefs.rkt" - images/icons/tool + images/compile-time + (for-syntax racket/base images/icons/tool) ;; FIXME: drracket/private/syncheck/local-member-names) @@ -83,6 +84,9 @@ (define macro-stepper-button-label "Macro Stepper") +(define macro-debugger-bitmap (compiled-bitmap (macro-stepper-icon))) +(define small-macro-debugger-bitmap (compiled-bitmap (small-macro-stepper-icon))) + (define tool@ (unit (import drracket:tool^) @@ -109,9 +113,6 @@ (define-local-member-name check-language) - (define macro-debugger-bitmap (macro-stepper-icon)) - (define small-macro-debugger-bitmap (small-macro-stepper-icon)) - (define (macro-debugger-unit-frame-mixin %) (class* % (frame/supports-macro-stepper<%>) (super-new) From 259913ee835afda0f1277a5df424560cdbaed234 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 13 Jan 2012 07:15:15 -0700 Subject: [PATCH 474/746] fix `find-files' to convert an initial string into a path Merge to 5.2.1 (cherry picked from commit 60c418b20ea2e1c8218c653c259b5ca1fa690943) --- collects/racket/file.rkt | 3 ++- collects/tests/racket/filelib.rktl | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/collects/racket/file.rkt b/collects/racket/file.rkt index 6a768e6704..d7b808c922 100644 --- a/collects/racket/file.rkt +++ b/collects/racket/file.rkt @@ -546,7 +546,8 @@ (define (do-paths paths acc) (cond [(null? paths) acc] [else (do-paths (cdr paths) (do-path (car paths) acc))])) - (if path (do-path path init) (do-paths (sorted-dirlist) init))) + (define (to-path s) (if (path? s) s (string->path s))) + (if path (do-path (to-path path) init) (do-paths (sorted-dirlist) init))) (define (find-files f [path #f]) (reverse diff --git a/collects/tests/racket/filelib.rktl b/collects/tests/racket/filelib.rktl index c3eeb32f6e..3212c5e6f0 100644 --- a/collects/tests/racket/filelib.rktl +++ b/collects/tests/racket/filelib.rktl @@ -68,6 +68,12 @@ (test (list (build-path (current-directory) "filelib.rktl")) find-files (lambda (f) (regexp-match "filelib[.]rktl$" (path->string f))) (current-directory)) + ;; check that path as string gives paths (not strings) to checker and result: + (test (list (current-directory) + (build-path (current-directory) "filelib.rktl")) + find-files (lambda (f) (or (equal? f (current-directory)) + (regexp-match "filelib[.]rktl$" (path->string f)))) + (path->string (current-directory))) (let ([rel2 (fold-files (lambda (name kind accum) (test kind name (if (file-exists? name) From 2f0fbdba21a1201a291abfa0c3e1720109076348 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Wed, 11 Jan 2012 18:24:03 -0500 Subject: [PATCH 475/746] Union types instead of clobbering them in the type table. This fixes a bug where only the last branch of a case-> type would get stored. (cherry picked from commit 87a53159dd3d69a6f9bbbe8fef543a966e6015ce) --- .../optimizer/tests/case-arrow.rkt | 24 +++++++++++++++++++ collects/typed-racket/types/type-table.rkt | 20 ++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 collects/tests/typed-racket/optimizer/tests/case-arrow.rkt diff --git a/collects/tests/typed-racket/optimizer/tests/case-arrow.rkt b/collects/tests/typed-racket/optimizer/tests/case-arrow.rkt new file mode 100644 index 0000000000..50ce7bf603 --- /dev/null +++ b/collects/tests/typed-racket/optimizer/tests/case-arrow.rkt @@ -0,0 +1,24 @@ +#; +( +TR missed opt: case-arrow.rkt 21:2 (+ min (/ (* (- max min) x) p)) -- exact ops inside float expr -- caused by: 21:15 (- max min) (3 times) +TR missed opt: case-arrow.rkt 21:2 (+ min (/ (* (- max min) x) p)) -- all args float-arg-expr, result not Float -- caused by: 21:5 min, 21:18 max, 21:22 min, 21:27 x, 21:30 p (4 times) +) +#lang typed/racket + +;; Typechecking functions with case-> types causes the body to be typechecked +;; multiple times, which is fine, except that it used to cause the type table +;; to only have information for the last branch (clobbering). This would cause +;; this program to be optimized, which is not safe. + +(define p (- (expt 2 31) 1)) +(define A (expt 7 5)) +(define x 42) + +(: gen-random : (case-> (Integer Integer → Exact-Rational) + (Float Float → Float))) +(define (gen-random min max) + (set! x (modulo (* A x) p)) + (+ min (/ (* (- max min) x) p))) + +(void (gen-random 2.3 7.4)) +(void (gen-random 2 7)) diff --git a/collects/typed-racket/types/type-table.rkt b/collects/typed-racket/types/type-table.rkt index 5b19d7f860..acbab23847 100644 --- a/collects/typed-racket/types/type-table.rkt +++ b/collects/typed-racket/types/type-table.rkt @@ -4,7 +4,7 @@ "../utils/utils.rkt" (contract-req) (rep type-rep object-rep) - (only-in (types utils) tc-results?) + (types utils union) (utils tc-utils) (env init-envs)) @@ -15,7 +15,23 @@ (define (add-typeof-expr e t) (when (optimize?) - (hash-set! table e t))) + (hash-update! table e + ;; when typechecking a case-> type, types get added for + ;; the same subexpression multiple times, combine them + (lambda (old) + (match* (old t) + [((tc-result1: old-t) (tc-result1: t-t)) + (ret (Un old-t t-t))] + [((tc-results: old-ts) (tc-results: t-ts)) + ;; filters don't matter at this point, since only + ;; the optimizer reads this table + (unless (= (length old-ts) (length t-ts)) + (int-err + "type table: number of values don't agree ~a ~a" + old-ts t-ts)) + (ret (map Un old-ts t-ts))] + [(_ _) t])) ; irrelevant to the optimizer, just clobber + t))) (define (type-of e) (hash-ref table e From 58467ac5b94f7f66b65ab9127a07e90f304313db Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Fri, 13 Jan 2012 22:48:28 -0700 Subject: [PATCH 476/746] Contracts for almost all icon-producing functions More documentation (Now contains an animated GIF! We have achieved Web 1.0!) Fixed stop sign double-rendering bug Compiled logos size 256 (no rendering time for sizes < 256; intended size almost instantaneous) Please merge into release (cherry picked from commit 0c5ea11056bd24d808d9b901efcef5a2e9ddde39) --- collects/images/icons/arrow.rkt | 44 +- collects/images/icons/control.rkt | 157 ++++--- collects/images/icons/file.rkt | 68 ++- collects/images/icons/misc.rkt | 217 +++++++--- collects/images/icons/stickman.rkt | 63 ++- collects/images/icons/style.rkt | 22 +- collects/images/icons/tool.rkt | 8 +- collects/images/logos.rkt | 302 ++----------- collects/images/private/logos.rkt | 288 +++++++++++++ collects/images/private/utils.rkt | 4 +- collects/images/scribblings/icons.scrbl | 403 +++++++----------- .../images/scribblings/running-stickman.gif | Bin 0 -> 43705 bytes collects/images/tests/icon-tests.rkt | 2 +- 13 files changed, 861 insertions(+), 717 deletions(-) create mode 100644 collects/images/private/logos.rkt create mode 100644 collects/images/scribblings/running-stickman.gif diff --git a/collects/images/icons/arrow.rkt b/collects/images/icons/arrow.rkt index e15626e6b1..bbcdd5f3f8 100644 --- a/collects/images/icons/arrow.rkt +++ b/collects/images/icons/arrow.rkt @@ -7,17 +7,18 @@ "../private/utils.rkt" "style.rkt") -(provide - (activate-contract-out - flat-right-arrow-flomap - flat-right-over-arrow-flomap - right-arrow-flomap left-arrow-flomap up-arrow-flomap down-arrow-flomap - right-over-arrow-flomap left-over-arrow-flomap - right-under-arrow-flomap left-under-arrow-flomap - right-arrow-icon left-arrow-icon up-arrow-icon down-arrow-icon - right-over-arrow-icon left-over-arrow-icon - right-under-arrow-icon left-under-arrow-icon) - (only-doc-out (all-defined-out))) +(provide (activate-contract-out + flat-right-arrow-flomap + flat-right-over-arrow-flomap + right-arrow-icon right-arrow-flomap + left-arrow-icon left-arrow-flomap + up-arrow-icon up-arrow-flomap + down-arrow-icon down-arrow-flomap + right-over-arrow-icon right-over-arrow-flomap + left-over-arrow-icon left-over-arrow-flomap + right-under-arrow-icon right-under-arrow-flomap + left-under-arrow-icon left-under-arrow-flomap) + (only-doc-out (all-defined-out))) (defproc (flat-right-arrow-flomap [color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0))] @@ -105,12 +106,15 @@ ) flomap? (flomap-flip-horizontal (right-under-arrow-flomap color height material))) -(define-simple-icon-wrapper left-arrow-icon left-arrow-flomap) -(define-simple-icon-wrapper right-arrow-icon right-arrow-flomap) -(define-simple-icon-wrapper up-arrow-icon up-arrow-flomap) -(define-simple-icon-wrapper down-arrow-icon down-arrow-flomap) - -(define-simple-icon-wrapper right-over-arrow-icon right-over-arrow-flomap) -(define-simple-icon-wrapper left-over-arrow-icon left-over-arrow-flomap) -(define-simple-icon-wrapper right-under-arrow-icon right-under-arrow-flomap) -(define-simple-icon-wrapper left-under-arrow-icon left-under-arrow-flomap) +(define-icon-wrappers + ([color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [left-arrow-icon left-arrow-flomap] + [right-arrow-icon right-arrow-flomap] + [up-arrow-icon up-arrow-flomap] + [down-arrow-icon down-arrow-flomap] + [right-over-arrow-icon right-over-arrow-flomap] + [left-over-arrow-icon left-over-arrow-flomap] + [right-under-arrow-icon right-under-arrow-flomap] + [left-under-arrow-icon left-under-arrow-flomap]) diff --git a/collects/images/icons/control.rkt b/collects/images/icons/control.rkt index e0eb70afb8..36c244378a 100644 --- a/collects/images/icons/control.rkt +++ b/collects/images/icons/control.rkt @@ -1,50 +1,57 @@ #lang racket/base -(require racket/class +(require racket/class racket/draw + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" + "../private/deep-flomap.rkt" "../private/utils.rkt" "style.rkt") -(provide (all-defined-out)) +(provide (activate-contract-out + play-icon play-flomap + back-icon back-flomap + fast-forward-icon fast-forward-flomap + rewind-icon rewind-flomap + bar-icon bar-flomap + stop-icon stop-flomap + record-icon record-flomap + pause-icon pause-flomap + step-icon step-flomap + step-back-icon step-back-flomap + continue-icon continue-flomap + continue-back-icon continue-back-flomap) + (only-doc-out (all-defined-out))) -(define play-points - (list '(0 . 0) '(4 . 0) - '(23 . 13) '(23 . 18) - '(4 . 31) '(0 . 31))) +(define (flat-play-flomap color height) + (draw-icon-flomap + 24 32 + (λ (dc) + (send dc set-brush color 'solid) + (send dc draw-polygon (list (cons 0 0) (cons 4 0) + (cons 23 13) (cons 23 18) + (cons 4 31) (cons 0 31)))) + (/ height 32))) -(define (play-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (play-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] - (draw-rendered-icon-flomap - 24 32 (λ (dc) - (send dc set-brush color 'solid) - (send dc draw-polygon play-points)) - (/ height 32) - material))) + (define fm (flat-play-flomap color height)) + (flomap-render-icon fm material))) -(define (fast-forward-flomap color [height (default-icon-height)] [material (default-icon-material)]) - (make-cached-flomap - [height color material] - (draw-rendered-icon-flomap - 32 32 (λ (dc) - (send dc set-brush color 'solid) - (send dc draw-polygon (list '(0 . 0) '(4 . 0) - '(17 . 13) '(17 . 18) - '(4 . 31) '(0 . 31))) - (send dc translate 2 0) - (send dc draw-polygon (list - ;; right side - '(14 . 2) - '(27 . 13) '(27 . 18) - '(14 . 29) - ;; left side - '(8 . 29) - '(18 . 19) '(18 . 12) - '(8 . 2)))) - (/ height 32) - material))) +(defproc (fast-forward-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (define fm (play-flomap color height material)) + (flomap-pin* 3/2 1/2 1 1/2 fm fm)) -(define (stop-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (stop-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (draw-rendered-icon-flomap @@ -54,7 +61,10 @@ (/ height 32) material))) -(define (record-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (record-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (draw-rendered-icon-flomap @@ -64,7 +74,10 @@ (/ height 32) material))) -(define (bar-flomap color height material) +(defproc (bar-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (draw-rendered-icon-flomap @@ -74,52 +87,76 @@ (/ height 32) material))) -(define back-flomap (compose flomap-flip-horizontal play-flomap)) -(define reverse-flomap (compose flomap-flip-horizontal fast-forward-flomap)) +(defproc (back-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (play-flomap color height material))) -(define (pause-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (rewind-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (fast-forward-flomap color height material))) + +(defproc (pause-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/8 height)))) 0) (bar-flomap color height material))) -(define (step-flomap color [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (step-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (play-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (bar-flomap color height material))) -(define (step-back-flomap color [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (step-back-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (back-flomap color height material))) -(define (continue-flomap color [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (continue-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (play-flomap color height material))) -(define (continue-back-flomap color [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (continue-back-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (back-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (bar-flomap color height material))) -(define play-icon (compose flomap->bitmap play-flomap)) -(define back-icon (compose flomap->bitmap back-flomap)) -(define fast-forward-icon (compose flomap->bitmap fast-forward-flomap)) -(define reverse-icon (compose flomap->bitmap reverse-flomap)) -(define bar-icon (compose flomap->bitmap bar-flomap)) -(define stop-icon (compose flomap->bitmap stop-flomap)) -(define record-icon (compose flomap->bitmap record-flomap)) -(define pause-icon (compose flomap->bitmap pause-flomap)) -(define step-icon (compose flomap->bitmap step-flomap)) -(define step-back-icon (compose flomap->bitmap step-back-flomap)) -(define continue-icon (compose flomap->bitmap continue-flomap)) -(define continue-back-icon (compose flomap->bitmap continue-back-flomap)) +(define-icon-wrappers + ([color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [play-icon play-flomap] + [back-icon back-flomap] + [fast-forward-icon fast-forward-flomap] + [rewind-icon rewind-flomap] + [bar-icon bar-flomap] + [stop-icon stop-flomap] + [record-icon record-flomap] + [pause-icon pause-flomap] + [step-icon step-flomap] + [step-back-icon step-back-flomap] + [continue-icon continue-flomap] + [continue-back-icon continue-back-flomap]) diff --git a/collects/images/icons/file.rkt b/collects/images/icons/file.rkt index 4d7fedd6f1..f44ea734a8 100644 --- a/collects/images/icons/file.rkt +++ b/collects/images/icons/file.rkt @@ -1,15 +1,25 @@ #lang racket/base -(require racket/draw racket/class +(require racket/class racket/draw + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" "arrow.rkt" "style.rkt") -(provide (all-defined-out)) +(provide (activate-contract-out + floppy-disk-icon floppy-disk-flomap + save-icon save-flomap + load-icon load-flomap + small-save-icon small-save-flomap + small-load-icon small-load-flomap) + (only-doc-out (all-defined-out))) -(define (floppy-disk-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (floppy-disk-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (define scale (/ height 32)) @@ -96,36 +106,54 @@ [fm (flomap-ct-superimpose fm label-fm)]) fm))) -(define (save-flomap arrow-color color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (save-flomap [arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (right-arrow-flomap arrow-color (* 3/4 height) material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (floppy-disk-flomap color height material))) -(define (load-flomap arrow-color color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (load-flomap [arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (floppy-disk-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (right-arrow-flomap arrow-color (* 3/4 height) material))) -(define (small-save-flomap arrow-color color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (small-save-flomap [arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-pin* 0 0 11/16 0 (floppy-disk-flomap color height material) (right-arrow-flomap arrow-color (* 3/4 height) material))) -(define (small-load-flomap arrow-color color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (small-load-flomap [arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-pin* 1 1 5/16 1 (floppy-disk-flomap color height material) (right-arrow-flomap arrow-color (* 3/4 height) material))) -(define floppy-disk-icon (compose flomap->bitmap floppy-disk-flomap)) -(define save-icon (compose flomap->bitmap save-flomap)) -(define load-icon (compose flomap->bitmap load-flomap)) -(define small-save-icon (compose flomap->bitmap small-save-flomap)) -(define small-load-icon (compose flomap->bitmap small-load-flomap)) +(define-icon-wrappers + ([color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [floppy-disk-icon floppy-disk-flomap]) + +(define-icon-wrappers + ([arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [save-icon save-flomap] + [load-icon load-flomap] + [small-save-icon small-save-flomap] + [small-load-icon small-load-flomap]) diff --git a/collects/images/icons/misc.rkt b/collects/images/icons/misc.rkt index 493ed64fba..61b2366202 100644 --- a/collects/images/icons/misc.rkt +++ b/collects/images/icons/misc.rkt @@ -1,12 +1,26 @@ #lang racket/base (require racket/draw racket/class racket/math racket/sequence + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" "style.rkt") -(provide (all-defined-out)) +(provide (activate-contract-out + text-icon text-flomap + recycle-icon recycle-flomap + x-icon x-flomap + check-icon check-flomap + regular-polygon-icon regular-polygon-flomap + octagon-icon octagon-flomap + stop-sign-icon stop-sign-flomap + stop-signs-icon stop-signs-flomap + magnifying-glass-icon magnifying-glass-flomap + left-magnifying-glass-icon left-magnifying-glass-flomap + bomb-icon bomb-flomap + left-bomb-icon left-bomb-flomap) + (only-doc-out (all-defined-out))) ;; =================================================================================================== ;; Unrendered flomaps @@ -37,39 +51,41 @@ (/ height 32))) (define (flat-regular-polygon-flomap sides start color size) - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-brush color 'solid) - (define dθ (/ (* 2 pi) sides)) - (define θs (sequence->list (in-range start (+ start (* 2 pi)) dθ))) - (define max-frac (apply max (append (map (compose abs cos) θs) - (map (compose abs sin) θs)))) - (send dc draw-polygon (for/list ([θ (in-list θs)]) - (cons (+ 15.5 (/ (* 15.5 (cos θ)) max-frac)) - (+ 15.5 (/ (* 15.5 (sin θ)) max-frac)))))) - (/ size 32))) + (let ([start (- start)]) + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-brush color 'solid) + (define dθ (/ (* 2 pi) sides)) + (define θs (sequence->list (in-range start (+ start (* 2 pi)) dθ))) + (define max-frac (apply max (append (map (compose abs cos) θs) + (map (compose abs sin) θs)))) + (send dc draw-polygon (for/list ([θ (in-list θs)]) + (cons (+ 15.5 (/ (* 15.5 (cos θ)) max-frac)) + (+ 15.5 (/ (* 15.5 (sin θ)) max-frac)))))) + (/ size 32)))) ;; =================================================================================================== ;; Rendered flomaps -(define (text-flomap str font color trim? outline? - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (text-flomap [str string?] [font (is-a?/c font%)] + [color (or/c string? (is-a?/c color%))] + [trim? boolean? #t] + [outline (or/c 'auto (and/c rational? (>=/c 0))) 'auto] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (define size (max 32 (send font get-point-size))) (define family (send font get-family)) (define style (send font get-style)) (define weight (send font get-weight)) (define underline? (send font get-underlined)) (define smoothing (send font get-smoothing)) - (define size - (let* ([size (inexact->exact (ceiling height))]) - (min 255 (if trim? (* 2 size) size)))) (make-cached-flomap - [height str family style weight underline? smoothing color trim? outline? material] - (let ([font (make-object font% size family style weight underline? smoothing #t)]) + [height str family style weight underline? smoothing color trim? outline material] + (let ([font (make-object font% size family style weight underline? smoothing #t)] + [outline (if (equal? outline 'auto) (/ height 32) outline)]) (define-values (w h) (get-text-size str font)) - (define outline-amt (if outline? (/ height 32) 0)) - (define ceiling-amt (inexact->exact (ceiling outline-amt))) + (define ceiling-amt (inexact->exact (ceiling outline))) (define fm (let* ([fm (draw-flomap w h (λ (dc) @@ -79,14 +95,19 @@ [fm (if trim? (flomap-trim fm) fm)] [fm (flomap-resize fm #f (- height (* 2 ceiling-amt)))] [fm (flomap-inset fm ceiling-amt)] - [fm (if outline? (flomap-outlined fm outline-amt) fm)]) + [fm (if (outline . > . 0) (flomap-outlined fm outline) fm)]) fm)) (flomap-render-icon fm material)))) -(define (recycle-flomap color [height (default-icon-height)] [material (default-icon-material)]) - (text-flomap "♻" (make-object font% 64 'default) color #t #t height material)) +(defproc (recycle-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (define size (max 1 (min 1024 (inexact->exact (ceiling (* 2 height)))))) + (text-flomap "♻" (make-object font% size 'default) color #t (/ height 64) height material)) -(define (x-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (x-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? (make-cached-flomap [height color material] (define scale (/ height 32)) @@ -96,7 +117,9 @@ [dfm (deep-flomap-raise dfm (* -8 scale))]) (deep-flomap-render-icon dfm material)))) -(define (check-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (check-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? (make-cached-flomap [height color material] (define scale (/ height 32)) @@ -106,29 +129,44 @@ [dfm (deep-flomap-raise dfm (* -12 scale))]) (deep-flomap-render-icon dfm material)))) -(define (regular-polygon-flomap sides start color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (regular-polygon-flomap [sides exact-positive-integer?] + [start real?] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height sides start color material] (flomap-render-icon (flat-regular-polygon-flomap sides start color height) material))) -(define (octagon-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (octagon-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + #:document-body (regular-polygon-flomap 8 (/ (* 2 pi) 16) color height material)) -(define (stop-sign-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (stop-sign-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? (make-cached-flomap [height color material] (define scale (/ height 32)) - (let* ([indent-fm (fm* 0.5 (x-flomap "black" (* 22 scale)))] + (let* ([indent-fm (fm* 0.5 (flat-x-flomap "black" (* 22 scale)))] [indent-dfm (deep-flomap-raise (flomap->deep-flomap indent-fm) (* -1 scale))] - [fm (regular-polygon-flomap 8 (/ (* 2 pi) 16) color height)] + [fm (flat-regular-polygon-flomap 8 (/ (* 2 pi) 16) color height)] [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-cc-superimpose 'add dfm indent-dfm)] [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-cc-superimpose 'add dfm indent-dfm)] [fm (deep-flomap-render-icon dfm material)]) (flomap-cc-superimpose fm (x-flomap "azure" (* 22 scale) metal-material))))) +(defproc (stop-signs-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (define fm (stop-sign-flomap color (* height 2/3) material)) + (flomap-pin* 3/16 1/4 0 0 + fm (flomap-pin* 3/16 1/4 0 0 fm fm))) + ;; --------------------------------------------------------------------------------------------------- ;; Magnifying glass @@ -146,9 +184,11 @@ 0.2 0.8 0.0 0.0)) -(define (magnifying-glass-flomap metal-color handle-color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (magnifying-glass-flomap [metal-color (or/c string? (is-a?/c color%))] + [handle-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height metal-color handle-color material] (define scale (/ height 32)) @@ -213,12 +253,21 @@ handle-fm (flomap-pin* 1/2 1/2 1/2 1/2 circle-fm glass-fm)))) +(defproc (left-magnifying-glass-flomap [metal-color (or/c string? (is-a?/c color%))] + [handle-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (magnifying-glass-flomap metal-color handle-color height material))) + ;; --------------------------------------------------------------------------------------------------- ;; Bomb -(define (left-bomb-flomap cap-color bomb-color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (left-bomb-flomap [cap-color (or/c string? (is-a?/c color%))] + [bomb-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height cap-color bomb-color material] (define scale (/ height 32)) @@ -229,15 +278,15 @@ (send dc set-brush "gold" 'solid) (draw-path-commands dc 0 0 - '((m 3.5 0) - (c -5 0 -3.29080284 10.4205 -3 11.5 - 1.1137011 4.1343 2 6.5 0 8.5 - -0.5711131 2.0524 1.5 4 3.5 3.5 - 2.5711131 -2.5524 3.1327042 -5.5355 2 -9.5 - -2 -7 -2 -9 -1.5 -9 - 0 1 -0.5 2 1 3.5 - 2 0.5 4 -1.5 3.5 -3.5 - -2 -2 -2 -5 -5.5 -5)))) + '((m 3.5 0) + (c -5 0 -3.29080284 10.4205 -3 11.5 + 1.1137011 4.1343 2 6.5 0 8.5 + -0.5711131 2.0524 1.5 4 3.5 3.5 + 2.5711131 -2.5524 3.1327042 -5.5355 2 -9.5 + -2 -7 -2 -9 -1.5 -9 + 0 1 -0.5 2 1 3.5 + 2 0.5 4 -1.5 3.5 -3.5 + -2 -2 -2 -5 -5.5 -5)))) scale)] [dfm (flomap->deep-flomap fm)] [dfm (deep-flomap-icon-style dfm)] @@ -281,26 +330,56 @@ (deep-flomap-render-icon sphere-dfm material))) (flomap-lt-superimpose sphere-fm cap-fm fuse-fm))) -(define (stop-signs-flomap color [height (default-icon-height)] [material (default-icon-material)]) - (define fm (stop-sign-flomap color (* height 2/3) material)) - (flomap-pin* 3/16 1/4 0 0 - fm (flomap-pin* 3/16 1/4 0 0 fm fm))) - -(define left-magnifying-glass-flomap (compose flomap-flip-horizontal magnifying-glass-flomap)) -(define bomb-flomap (compose flomap-flip-horizontal left-bomb-flomap)) +(defproc (bomb-flomap [cap-color (or/c string? (is-a?/c color%))] + [bomb-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (left-bomb-flomap cap-color bomb-color height material))) ;; =================================================================================================== ;; Bitmaps (icons) -(define text-icon (compose flomap->bitmap text-flomap)) -(define recycle-icon (compose flomap->bitmap recycle-flomap)) -(define regular-polygon-icon (compose flomap->bitmap regular-polygon-flomap)) -(define octagon-icon (compose flomap->bitmap octagon-flomap)) -(define x-icon (compose flomap->bitmap x-flomap)) -(define stop-sign-icon (compose flomap->bitmap stop-sign-flomap)) -(define stop-signs-icon (compose flomap->bitmap stop-signs-flomap)) -(define check-icon (compose flomap->bitmap check-flomap)) -(define magnifying-glass-icon (compose flomap->bitmap magnifying-glass-flomap)) -(define left-magnifying-glass-icon (compose flomap->bitmap left-magnifying-glass-flomap)) -(define bomb-icon (compose flomap->bitmap bomb-flomap)) -(define left-bomb-icon (compose flomap->bitmap left-bomb-flomap)) +(defproc (text-icon [str string?] [font (is-a?/c font%)] + [color (or/c string? (is-a?/c color%))] + [trim? boolean? #t] + [outline (or/c 'auto (and/c rational? (>=/c 0))) 'auto] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (text-flomap str font color trim? outline height material))) + +(defproc (regular-polygon-icon [sides exact-positive-integer?] + [start real?] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (regular-polygon-flomap sides start color height material))) + +(define-icon-wrappers + ([color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [recycle-icon recycle-flomap] + [x-icon x-flomap] + [check-icon check-flomap] + [octagon-icon octagon-flomap] + [stop-sign-icon stop-sign-flomap] + [stop-signs-icon stop-signs-flomap]) + +(define-icon-wrappers + ([metal-color (or/c string? (is-a?/c color%))] + [handle-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [magnifying-glass-icon magnifying-glass-flomap] + [left-magnifying-glass-icon left-magnifying-glass-flomap]) + +(define-icon-wrappers + ([cap-color (or/c string? (is-a?/c color%))] + [bomb-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [bomb-icon bomb-flomap] + [left-bomb-icon left-bomb-flomap]) diff --git a/collects/images/icons/stickman.rkt b/collects/images/icons/stickman.rkt index cd6cf8124f..69f2e48a3c 100644 --- a/collects/images/icons/stickman.rkt +++ b/collects/images/icons/stickman.rkt @@ -1,13 +1,19 @@ #lang racket/base -(require racket/class racket/vector racket/match racket/math +(require racket/class racket/draw racket/vector racket/match racket/math + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" "style.rkt") -(provide standing-stickman-flomap standing-stickman-icon - running-stickman-flomap running-stickman-icon) +(provide (activate-contract-out + standing-stickman-icon standing-stickman-flomap + running-stickman-icon running-stickman-flomap) + (only-doc-out (all-defined-out))) + +;; =================================================================================================== +;; Common (define (cons+ p1 p2) (match-define (cons x1 y1) p1) @@ -31,6 +37,9 @@ (define shin-length 6.5) (define shoulder-breadth 7) +;; =================================================================================================== +;; Standing + (define standing-torso-angle -90) (define standing-neck-angle 5) (define standing-left-knee-angle 200) @@ -100,9 +109,12 @@ (polar->cartesian (+ standing-right-elbow-angle standing-torso-angle standing-right-hand-angle) lower-arm-length))) -(define (standing-stickman-flomap color arm-color head-color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (standing-stickman-flomap [color (or/c string? (is-a?/c color%))] + [arm-color (or/c string? (is-a?/c color%))] + [head-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color arm-color head-color material] (flomap-lt-superimpose @@ -161,6 +173,9 @@ (/ height 32) material)))) +;; =================================================================================================== +;; Running + (define running-neck-angle 20) (define running-torso-angle -70) @@ -245,7 +260,7 @@ (define (running-head-flomap t color height material) (make-cached-flomap [height t color material] - (draw-short-rendered-icon-flomap + (draw-rendered-icon-flomap 26 32 (λ (dc) (send dc set-pen "black" line-width 'solid) (send dc set-brush color 'solid) @@ -257,7 +272,7 @@ (define (running-leg-flomap t body? color height material) (make-cached-flomap [height t body? color material] - (draw-short-rendered-icon-flomap + (draw-rendered-icon-flomap 26 32 (λ (dc) (draw-running-leg dc t "black" (+ leg-width (* 2 line-width))) (when body? @@ -270,16 +285,20 @@ (define (running-arm-flomap t color height material) (make-cached-flomap [height t color material] - (draw-short-rendered-icon-flomap + (draw-rendered-icon-flomap 26 32 (λ (dc) (draw-running-arm dc t "black" (+ arm-width (* 2 line-width))) (draw-running-arm dc t color arm-width)) (/ height 32) material))) -(define (running-stickman-flomap t color arm-color head-color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (running-stickman-flomap [t rational?] + [color (or/c string? (is-a?/c color%))] + [arm-color (or/c string? (is-a?/c color%))] + [head-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height t color arm-color head-color material] (flomap-lt-superimpose (running-arm-flomap (+ t 0.5) arm-color height material) @@ -288,14 +307,28 @@ (running-head-flomap t head-color height material) (running-arm-flomap t arm-color height material)))) -(define standing-stickman-icon (compose flomap->bitmap standing-stickman-flomap)) -(define running-stickman-icon (compose flomap->bitmap running-stickman-flomap)) +(defproc (standing-stickman-icon [color (or/c string? (is-a?/c color%))] + [arm-color (or/c string? (is-a?/c color%))] + [head-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (standing-stickman-flomap color arm-color head-color height material))) + +(defproc (running-stickman-icon [t rational?] + [color (or/c string? (is-a?/c color%))] + [arm-color (or/c string? (is-a?/c color%))] + [head-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (running-stickman-flomap t color arm-color head-color height material))) #;; FOR TESTING ONLY: Do not let this find its way into the repo uncommented! (begin (require racket/gui (planet "animated-canvas.rkt" ("williams" "animated-canvas.plt" 2 4))) - (define size 20) + (define size 64) (standing-stickman-icon halt-icon-color "white" halt-icon-color size) diff --git a/collects/images/icons/style.rkt b/collects/images/icons/style.rkt index f40a5454cd..d8e99d8378 100644 --- a/collects/images/icons/style.rkt +++ b/collects/images/icons/style.rkt @@ -2,6 +2,7 @@ (require racket/draw unstable/parameter-group racket/contract unstable/latent-contract/defthing + (for-syntax unstable/latent-contract/serialize-syntax) "../private/flomap.rkt" "../private/deep-flomap.rkt") @@ -24,8 +25,8 @@ (define glass-icon-material (deep-flomap-material-value 'cubic-zirconia 1.0 0.75 0.15 - 0.5 0.2 1.0 - 0.0 0.4 0.25 + 1.0 0.2 1.0 + 0.2 0.4 0.25 0.08)) (define metal-icon-color "lightsteelblue") @@ -51,7 +52,7 @@ (define s (/ (deep-flomap-height dfm) 32)) (let* ([dfm (deep-flomap-emboss dfm (* s 2) (* s 2))] [dfm (deep-flomap-bulge-round dfm (* s 6))] - [dfm (deep-flomap-raise dfm (* s 18))]) + [dfm (deep-flomap-raise dfm (* s 20))]) dfm)) (define (draw-icon-flomap w h draw-proc scale) @@ -93,9 +94,12 @@ ;; =================================================================================================== ;; Syntax for writing icon functions -(define-syntax-rule (define-simple-icon-wrapper icon-fun flomap-fun) - (defproc (icon-fun [color (or/c string? (is-a?/c color%))] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)] - ) (is-a?/c bitmap%) - (flomap->bitmap (flomap-fun color height material)))) +(define-syntax (define-icon-wrappers stx) + (syntax-case stx () + [(_ ([arg-name arg-props ...] ...) + [icon-fun flomap-fun] ...) + (syntax/loc stx + (begin + (defproc (icon-fun [arg-name arg-props ...] ...) (is-a?/c bitmap%) + (flomap->bitmap (flomap-fun arg-name ...))) + ...))])) diff --git a/collects/images/icons/tool.rkt b/collects/images/icons/tool.rkt index 06ccc52b6b..8903f407d8 100644 --- a/collects/images/icons/tool.rkt +++ b/collects/images/icons/tool.rkt @@ -27,8 +27,8 @@ (define (macro-stepper-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) (flomap-ht-append - (text-flomap "#'" (make-object font% 12 'system 'normal 'normal) - macro-stepper-hash-color #t #t height material) + (text-flomap "#'" (make-object font% (max 1 (min 1024 height)) 'system) + macro-stepper-hash-color #t 'auto height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/32 height)))) 0) (step-flomap syntax-icon-color height material))) @@ -36,8 +36,8 @@ (flomap-pin* 0 0 7/16 0 (step-flomap syntax-icon-color height material) - (text-flomap "#'" (make-object font% 12 'system 'normal 'bold) - macro-stepper-hash-color #t #t (* 3/4 height) material))) + (text-flomap "#'" (make-object font% (max 1 (min 1024 height)) 'system) + macro-stepper-hash-color #t 'auto (* 3/4 height) material))) (define (debugger-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) (flomap-ht-append diff --git a/collects/images/logos.rkt b/collects/images/logos.rkt index c397aa2012..8edff88ae0 100644 --- a/collects/images/logos.rkt +++ b/collects/images/logos.rkt @@ -1,287 +1,33 @@ #lang racket/base -(require racket/draw racket/class racket/match racket/math racket/flonum +(require racket/promise + (prefix-in private- "private/logos.rkt") "private/flomap.rkt" - "private/deep-flomap.rkt" - "icons/style.rkt" - "private/utils.rkt") + "compile-time.rkt" + (for-syntax racket/base + (prefix-in private- "private/logos.rkt") + "private/flomap.rkt")) -(provide plt-logo planet-logo) +(provide plt-logo planet-logo + (rename-out [private-plt-flomap plt-flomap] + [private-planet-flomap planet-flomap])) -(define glass-logo-material - (deep-flomap-material-value - 'cubic-zirconia 0.7 0.6 0.4 - 0.2 0.1 1.0 - 0.2 0.1 0.1 - 0.0)) +;; Use a delay to keep from using more memory than necessary (saves 256KB) +(define standard-plt-logo (delay (compiled-bitmap (private-plt-logo 256)))) -(define lambda-path-commands - '((m 97.5 10) - (c -12.267574371681416 0.22160039646017698 - -23.938206584070794 4.486409061946903 - -35.40358116814159 8.431642279646018 - 5.002013451327434 5.357118980530973 - 4.2474160707964606 7.049306166371681 - 6.430565946902655 6.642370378761062 - 8.354521486725664 -2.0234602477876105 - 20.745877522123894 -6.732496424778761 - 26.26655603539823 2.1904900530973452 - 12.036272707964603 15.204891185840708 - 17.140790371681415 34.66372757522124 - 18.964158300884954 53.635833203539825 - 2.3373978053097346 11.526810053097345 - -21.433330407079644 52.79757139823009 - -28.736806513274335 69.27072283185841 - -11.871354336283186 20.946142017699113 - -22.417494088495573 42.68413054867256 - -35.79320863716814 62.74737614159292 - 3.198686017699115 4.233302088495575 - 7.820428460176991 2.5766558584070793 - 12.171064637168142 1.925754336283186 - 3.714682336283186 -0.5565213451327433 - 7.429373734513274 -1.1130336283185842 - 11.14405607079646 -1.6695504424778762 - 11.979952707964602 -28.4038887079646 - 24.914903221238937 -54.476528141592915 - 36.156529274336286 -83.1860083539823 - 5.122632495575221 -11.831699256637167 - 7.625016637168141 -18.33969500884956 - 13.711282973451327 -26.087614300884955 - 7.215226336283186 4.414282761061947 - 9.363369911504424 15.302112283185838 - 13.299630442477875 22.814352991150443 - 11.600370407079646 29.849948884955747 - 23.150614654867255 59.71926315044247 - 34.09924077876106 89.81329104424779 - 2.8656957168141592 0.9979197168141594 - 5.806954477876106 3.9796174159292033 - 8.525185132743362 1.105811256637168 - 7.150265769911504 -4.4088093451327435 - 15.474823929203538 -7.170211115044248 - 21.428106194690265 -13.26414385840708 - -1.6986936637168142 -8.23685210619469 - -7.156455079646018 -15.941115469026549 - -10.48132417699115 -23.86248042477876 - -21.07570067256637 -42.11971171681416 - -41.39651398230088 -86.79632424778761 - -54.5885927079646 -132.15014060176992 - -4.858603610619468 -14.274800141592921 - -10.841368920353982 -31.4765361840708 - -26.303927504424777 -37.111590060176994 - -3.5224240707964602 -1.0457545628318583 - -7.2342065840707965 -1.2467313274336282 - -10.888935079646018 -1.2461164743362831))) +(define (plt-logo height) + (cond [(height . = . 256) (force standard-plt-logo)] + [(height . <= . 256) + (flomap->bitmap (flomap-resize (bitmap->flomap (force standard-plt-logo)) #f height))] + [else + (private-plt-logo height)])) -(define (draw-lambda dc x y w h) - (define-values (sx sy) (send dc get-scale)) - (draw-path-commands dc x y (scale-path-commands lambda-path-commands (/ w 240) (/ h 240))) - (send dc set-scale sx sy)) -(define blue-θ-start (* -45 (/ pi 180))) -(define blue-θ-end (* 110 (/ pi 180))) +(define standard-planet-logo (delay (compiled-bitmap (private-planet-logo 256)))) -(define logo-red-color (make-object color% 255 36 32)) -(define logo-blue-color (make-object color% 32 36 255)) -(define lambda-outline-color (make-object color% 16 16 64)) -(define (lambda-pen color width) (make-object pen% color width 'solid 'projecting 'miter)) - -(define (make-arc-path x y w h start end [ccw? #t]) - (define p (new dc-path%)) - (send p arc x y w h start end ccw?) - (send p close) - p) - -(define (make-random-flomap c w h) - (build-flomap c w h (λ (k x y i) (random)))) - -(define (flomap-rough fm z-amt) - (match-define (flomap _ c w h) fm) - (fm+ fm (fm* z-amt (make-random-flomap c w h)))) - -(define (plt-flomap height) - (make-cached-flomap - [height] - (define scale (/ height 256)) - (define bulge-fm - (draw-icon-flomap - 256 256 (λ (dc) - (send dc set-pen logo-red-color 2 'transparent) - (send dc set-brush logo-red-color 'solid) - (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-end blue-θ-start)) - (send dc set-pen logo-blue-color 2 'transparent) - (send dc set-brush logo-blue-color 'solid) - (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-start blue-θ-end)) - (send dc set-pen (lambda-pen lambda-outline-color 10)) - (send dc set-brush lambda-outline-color 'solid) - (draw-lambda dc 8 8 240 240)) - scale)) - - (define (lambda-flomap color pen-width) - (draw-icon-flomap - 256 256 (λ (dc) - (send dc set-scale scale scale) - (send dc set-pen (lambda-pen color pen-width)) - (send dc set-brush color 'solid) - (draw-lambda dc 8 8 240 240)) - scale)) - - (let* ([bulge-dfm (flomap->deep-flomap bulge-fm)] - [bulge-dfm (deep-flomap-bulge-spheroid bulge-dfm (* 112 scale))] - [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] - [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 112 scale))] - [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] - [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] - [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] - [fm (flomap-cc-superimpose - fm - (lambda-flomap lambda-outline-color 10) - lambda-fm)] - [fm (flomap-cc-superimpose - (draw-icon-flomap - 256 256 (λ (dc) - (send dc set-pen "lightblue" 2 'solid) - (send dc set-brush "white" 'transparent) - (send dc draw-ellipse 7 7 242 242) - (send dc set-pen lambda-outline-color 4 'solid) - (send dc draw-ellipse 2 2 252 252)) - scale) - fm)]) - fm))) - -(define continents-path-commands - '((m 11.526653 18.937779) - (c 0.05278 0.724075 1.940414 1.202607 0.678885 2.296248 - 0.249172 0.918181 1.040063 1.620575 1.448285 0.308034 - 1.219485 -0.885607 3.250882 -0.938443 3.317014 -2.906655 - -1.599965 -1.033954 -4.029479 -0.431148 -5.444184 0.302373) - (M 11.53125 18.125) - (C 10.786965 18.380649 9.3917452 18.611001 9.1304904 19.245707 - 10.289001 19.269837 11.178405 18.606302 11.53125 18.125) - (M 8.1875 19.65625) - (C 7.2652998 23.370888 8.6787734 19.63772 9.9124431 20.95891 - 10.727811 21.80382 11.739516 20.92275 10.465247 20.422456 - 9.7714766 19.980166 8.3964342 19.699414 8.1875 19.65625) - (M 7.5625 21.125) - (c -0.9196331 -1.962382 -3.205955 1.390782 -4.0978229 2.41995 - -1.707808 2.289408 -2.72190385 5.078558 -2.9334271 7.9238 - 1.0237952 1.983695 5.5272247 2.76676 4.7145431 4.084262 - -0.7368064 1.151552 -0.8906555 2.601652 0.1135446 3.680893 - 2.7495495 2.364498 1.2541019 5.824595 2.5609489 6.229519 - 2.5755284 0.853846 2.7512924 -3.696022 4.1297234 -3.843434 - 0.745066 -1.051147 0.04765 -2.428466 1.056101 -3.411232) - (C 12.318556 36.222109 8.8169859 35.479018 8.6188979 33.8253 - 7.7181807 34.141675 7.0679715 33.334232 6.30372 33.30415 - 5.7220663 34.646967 3.9378253 34.122031 4.3012403 32.699798 - 3.024533 33.043038 4.3605584 31.222879 3.40625 31.28125 - 0.5 33 2.5 26.5 5.0295875 29.903027 - 5.5 30.5 6.9002733 26.371666 8.8261905 25.876953 - 9.8027554 25.533149 9.5159021 24.727855 8.5279357 25.0625 - 7.6214946 24.941384 9.6975411 24.462771 10.075856 24.483273 - 11.540792 24.233047 9.904685 23.334106 9.8601011 22.602389 - 9.0900535 22.676405 9.4028275 22.737933 9.1185443 22.100147 - 6.8948741 22.58513 7.6831847 24.739145 5.9002404 23.244912 - 4.6247757 22.264239 7.321322 21.942832 7.5625 21.125) - (m 15.15625 -0.9375) - (c -1.37421 0.06218 -2.005432 1.159129 -2.784107 1.978327 - -0.114565 1.368674 0.952693 -0.07002 1.385771 0.968032 - 0.953881 -0.129572 -0.01507 -1.993413 1.425543 -2.008859 - -0.269351 0.525838 -0.494795 1.470731 0.411144 1.15174 - -0.646943 0.90275 -1.874871 2.045333 -2.613442 0.960703 - 0.08813 0.809648 -1.042388 0.509104 -1.186702 1.40851 - -0.738698 0.338761 -1.028513 0.375271 -0.383294 1.119927 - -1.340908 -0.226887 -1.979854 2.002883 -0.346874 1.903539 - 3.128783 -3.578714 2.7333 -0.07275 3.379252 -0.61531 - -0.408321 -3.069544 0.823059 1.69915 1.30948 -0.328623 - 0.476726 0.916648 1.583858 0.757279 2.129612 1.386838 - -2.140558 2.214946 -4.171988 -1.055384 -6.363065 -0.232922 - -2.486751 0.823935 -2.418258 3.347586 -3.103635 4.864439 - 0.687061 3.597921 3.669743 1.43585 5.132502 2.724104 - -0.344691 1.08929 0.484513 1.884668 0.473244 3.022942 - -0.01352 2.068761 0.378264 6.65826 1.845318 5.542497 - 1.472489 0.175399 1.430793 -1.740909 2.30904 -2.30502 - -1.36358 -1.181833 2.025569 -1.358588 0.887958 -2.838158 - -0.499809 -1.988948 1.367195 -3.177085 1.789594 -4.928946 - 0.579613 -0.960476 -1.588234 -0.05789 -0.373062 -1.023304 - 0.927113 -0.301781 2.379761 -2.07879 0.994298 -2.428506 - -0.676988 0.933612 -1.737597 -2.080985 -0.549773 -0.651497 - 0.699549 -0.419557 1.900516 1.563553 1.759683 -0.08984 - -0.608903 -3.386912 -2.4601 -6.520148 -5.090986 -8.736865 - -0.200722 0.802307 -1.230158 0.889683 -1.228926 0.0694 - 2.155263 -0.50116 -0.789058 -0.572123 -1.208573 -0.913148) - (M 17.09375 21) - (c -1.221276 0.05745 -0.44882 1.331427 0.232503 0.449916) - (C 17.458514 21.23484 17.234278 21.104353 17.09375 21) - (m -7.5 0.125) - (c -1.2040413 0.60218 1.459244 1.052142 0.289004 0.112253) - (m 8.96875 1.5) - (c 0.38412 0.655402 -0.236077 2.74213 1.030518 1.55154 - 0.0634 -0.524592 -0.59842 -1.401743 -1.030518 -1.55154) - (m -0.21875 0.75) - (c -1.155615 0.198578 0.509999 1.388302 0.06733 0.201634) - (M 10.5 24.53125) - (c -0.117519 1.313533 1.058399 0.642504 0 0))) - -(define water-logo-material - (deep-flomap-material-value - 'cubic-zirconia 1.0 0.7 1.0 - 0.25 0.15 1.0 - 0.15 0.1 0.2 - 0.0)) - -(define logo-under-continents-color "black") -(define logo-continents-color "azure") -(define logo-water-color "lightskyblue") -(define logo-earth-outline-color logo-red-color) - -(define (continents-flomap color height) - (define scale (/ height 32)) - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen lambda-outline-color 3/8 'solid) - (send dc set-brush color 'solid) - (draw-path-commands dc 0 -17 continents-path-commands)) - scale)) - -(define (planet-flomap height) - (make-cached-flomap - [height] - (define scale (/ height 32)) - (define-values (earth-fm earth-z) - (let* ([indent-fm (continents-flomap logo-red-color height)] - [indent-dfm (flomap->deep-flomap indent-fm)] - [indent-dfm (deep-flomap-raise indent-dfm (* -1/8 scale))] - [indent-dfm (deep-flomap-smooth-z indent-dfm (* 1 scale))] - [earth-fm (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen logo-water-color 1/2 'solid) - (send dc set-brush logo-water-color 'solid) - (draw-ellipse/smoothed dc 0.75 0.75 30.5 30.5)) - scale)] - [earth-dfm (flomap->deep-flomap earth-fm)] - [earth-dfm (deep-flomap-bulge-spheroid earth-dfm (* 16 scale))] - [earth-dfm (deep-flomap-cc-superimpose 'add earth-dfm indent-dfm)]) - (values (deep-flomap-render-icon earth-dfm water-logo-material) - (deep-flomap-z earth-dfm)))) - - (define land-fm - (let* ([land-fm (continents-flomap logo-continents-color height)] - [land-dfm (flomap->deep-flomap land-fm)] - ;[land-dfm (deep-flomap-emboss land-dfm (* 2 scale) (* 8 scale))] - [land-dfm (deep-flomap-bulge-spheroid land-dfm (* 16 scale))] - [land-dfm (deep-flomap-smooth-z land-dfm (* 1/2 scale))]) - (deep-flomap-render-icon land-dfm metal-material))) - - (flomap-cc-superimpose - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen "lightblue" 1/2 'solid) - (send dc set-brush "white" 'transparent) - (send dc draw-ellipse 0.5 0.5 31 31) - (send dc set-pen lambda-outline-color 1/2 'solid) - (send dc draw-ellipse -0.25 -0.25 32.5 32.5)) - scale) - earth-fm - land-fm))) - -(define plt-logo (compose flomap->bitmap plt-flomap)) -(define planet-logo (compose flomap->bitmap planet-flomap)) +(define (planet-logo height) + (cond [(height . = . 256) (force standard-planet-logo)] + [(height . <= . 256) + (flomap->bitmap (flomap-resize (bitmap->flomap (force standard-planet-logo)) #f height))] + [else + (private-planet-logo height)])) diff --git a/collects/images/private/logos.rkt b/collects/images/private/logos.rkt new file mode 100644 index 0000000000..dc873b1c72 --- /dev/null +++ b/collects/images/private/logos.rkt @@ -0,0 +1,288 @@ +#lang racket/base + +(require racket/draw racket/class racket/match racket/math racket/flonum + "flomap.rkt" + "deep-flomap.rkt" + "utils.rkt" + "../icons/style.rkt") + +(provide plt-logo planet-logo + plt-flomap planet-flomap) + +(define glass-logo-material + (deep-flomap-material-value + 'cubic-zirconia 0.7 0.6 0.4 + 0.2 0.1 1.0 + 0.2 0.1 0.1 + 0.0)) + +(define lambda-path-commands + '((m 97.5 10) + (c -12.267574371681416 0.22160039646017698 + -23.938206584070794 4.486409061946903 + -35.40358116814159 8.431642279646018 + 5.002013451327434 5.357118980530973 + 4.2474160707964606 7.049306166371681 + 6.430565946902655 6.642370378761062 + 8.354521486725664 -2.0234602477876105 + 20.745877522123894 -6.732496424778761 + 26.26655603539823 2.1904900530973452 + 12.036272707964603 15.204891185840708 + 17.140790371681415 34.66372757522124 + 18.964158300884954 53.635833203539825 + 2.3373978053097346 11.526810053097345 + -21.433330407079644 52.79757139823009 + -28.736806513274335 69.27072283185841 + -11.871354336283186 20.946142017699113 + -22.417494088495573 42.68413054867256 + -35.79320863716814 62.74737614159292 + 3.198686017699115 4.233302088495575 + 7.820428460176991 2.5766558584070793 + 12.171064637168142 1.925754336283186 + 3.714682336283186 -0.5565213451327433 + 7.429373734513274 -1.1130336283185842 + 11.14405607079646 -1.6695504424778762 + 11.979952707964602 -28.4038887079646 + 24.914903221238937 -54.476528141592915 + 36.156529274336286 -83.1860083539823 + 5.122632495575221 -11.831699256637167 + 7.625016637168141 -18.33969500884956 + 13.711282973451327 -26.087614300884955 + 7.215226336283186 4.414282761061947 + 9.363369911504424 15.302112283185838 + 13.299630442477875 22.814352991150443 + 11.600370407079646 29.849948884955747 + 23.150614654867255 59.71926315044247 + 34.09924077876106 89.81329104424779 + 2.8656957168141592 0.9979197168141594 + 5.806954477876106 3.9796174159292033 + 8.525185132743362 1.105811256637168 + 7.150265769911504 -4.4088093451327435 + 15.474823929203538 -7.170211115044248 + 21.428106194690265 -13.26414385840708 + -1.6986936637168142 -8.23685210619469 + -7.156455079646018 -15.941115469026549 + -10.48132417699115 -23.86248042477876 + -21.07570067256637 -42.11971171681416 + -41.39651398230088 -86.79632424778761 + -54.5885927079646 -132.15014060176992 + -4.858603610619468 -14.274800141592921 + -10.841368920353982 -31.4765361840708 + -26.303927504424777 -37.111590060176994 + -3.5224240707964602 -1.0457545628318583 + -7.2342065840707965 -1.2467313274336282 + -10.888935079646018 -1.2461164743362831))) + +(define (draw-lambda dc x y w h) + (define-values (sx sy) (send dc get-scale)) + (draw-path-commands dc x y (scale-path-commands lambda-path-commands (/ w 240) (/ h 240))) + (send dc set-scale sx sy)) + +(define blue-θ-start (* -45 (/ pi 180))) +(define blue-θ-end (* 110 (/ pi 180))) + +(define logo-red-color (make-object color% 255 36 32)) +(define logo-blue-color (make-object color% 32 36 255)) +(define lambda-outline-color (make-object color% 16 16 64)) +(define (lambda-pen color width) (make-object pen% color width 'solid 'projecting 'miter)) + +(define (make-arc-path x y w h start end [ccw? #t]) + (define p (new dc-path%)) + (send p arc x y w h start end ccw?) + (send p close) + p) + +(define (make-random-flomap c w h) + (build-flomap c w h (λ (k x y i) (random)))) + +(define (flomap-rough fm z-amt) + (match-define (flomap _ c w h) fm) + (fm+ fm (fm* z-amt (make-random-flomap c w h)))) + +(define (plt-flomap height) + (make-cached-flomap + [height] + (define scale (/ height 256)) + (define bulge-fm + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-pen logo-red-color 2 'transparent) + (send dc set-brush logo-red-color 'solid) + (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-end blue-θ-start)) + (send dc set-pen logo-blue-color 2 'transparent) + (send dc set-brush logo-blue-color 'solid) + (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-start blue-θ-end)) + (send dc set-pen (lambda-pen lambda-outline-color 10)) + (send dc set-brush lambda-outline-color 'solid) + (draw-lambda dc 8 8 240 240)) + scale)) + + (define (lambda-flomap color pen-width) + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-scale scale scale) + (send dc set-pen (lambda-pen color pen-width)) + (send dc set-brush color 'solid) + (draw-lambda dc 8 8 240 240)) + scale)) + + (let* ([bulge-dfm (flomap->deep-flomap bulge-fm)] + [bulge-dfm (deep-flomap-bulge-spheroid bulge-dfm (* 112 scale))] + [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] + [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 112 scale))] + [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] + [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] + [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] + [fm (flomap-cc-superimpose + fm + (lambda-flomap lambda-outline-color 10) + lambda-fm)] + [fm (flomap-cc-superimpose + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-pen "lightblue" 2 'solid) + (send dc set-brush "white" 'transparent) + (send dc draw-ellipse 7 7 242 242) + (send dc set-pen lambda-outline-color 4 'solid) + (send dc draw-ellipse 2 2 252 252)) + scale) + fm)]) + fm))) + +(define continents-path-commands + '((m 11.526653 18.937779) + (c 0.05278 0.724075 1.940414 1.202607 0.678885 2.296248 + 0.249172 0.918181 1.040063 1.620575 1.448285 0.308034 + 1.219485 -0.885607 3.250882 -0.938443 3.317014 -2.906655 + -1.599965 -1.033954 -4.029479 -0.431148 -5.444184 0.302373) + (M 11.53125 18.125) + (C 10.786965 18.380649 9.3917452 18.611001 9.1304904 19.245707 + 10.289001 19.269837 11.178405 18.606302 11.53125 18.125) + (M 8.1875 19.65625) + (C 7.2652998 23.370888 8.6787734 19.63772 9.9124431 20.95891 + 10.727811 21.80382 11.739516 20.92275 10.465247 20.422456 + 9.7714766 19.980166 8.3964342 19.699414 8.1875 19.65625) + (M 7.5625 21.125) + (c -0.9196331 -1.962382 -3.205955 1.390782 -4.0978229 2.41995 + -1.707808 2.289408 -2.72190385 5.078558 -2.9334271 7.9238 + 1.0237952 1.983695 5.5272247 2.76676 4.7145431 4.084262 + -0.7368064 1.151552 -0.8906555 2.601652 0.1135446 3.680893 + 2.7495495 2.364498 1.2541019 5.824595 2.5609489 6.229519 + 2.5755284 0.853846 2.7512924 -3.696022 4.1297234 -3.843434 + 0.745066 -1.051147 0.04765 -2.428466 1.056101 -3.411232) + (C 12.318556 36.222109 8.8169859 35.479018 8.6188979 33.8253 + 7.7181807 34.141675 7.0679715 33.334232 6.30372 33.30415 + 5.7220663 34.646967 3.9378253 34.122031 4.3012403 32.699798 + 3.024533 33.043038 4.3605584 31.222879 3.40625 31.28125 + 0.5 33 2.5 26.5 5.0295875 29.903027 + 5.5 30.5 6.9002733 26.371666 8.8261905 25.876953 + 9.8027554 25.533149 9.5159021 24.727855 8.5279357 25.0625 + 7.6214946 24.941384 9.6975411 24.462771 10.075856 24.483273 + 11.540792 24.233047 9.904685 23.334106 9.8601011 22.602389 + 9.0900535 22.676405 9.4028275 22.737933 9.1185443 22.100147 + 6.8948741 22.58513 7.6831847 24.739145 5.9002404 23.244912 + 4.6247757 22.264239 7.321322 21.942832 7.5625 21.125) + (m 15.15625 -0.9375) + (c -1.37421 0.06218 -2.005432 1.159129 -2.784107 1.978327 + -0.114565 1.368674 0.952693 -0.07002 1.385771 0.968032 + 0.953881 -0.129572 -0.01507 -1.993413 1.425543 -2.008859 + -0.269351 0.525838 -0.494795 1.470731 0.411144 1.15174 + -0.646943 0.90275 -1.874871 2.045333 -2.613442 0.960703 + 0.08813 0.809648 -1.042388 0.509104 -1.186702 1.40851 + -0.738698 0.338761 -1.028513 0.375271 -0.383294 1.119927 + -1.340908 -0.226887 -1.979854 2.002883 -0.346874 1.903539 + 3.128783 -3.578714 2.7333 -0.07275 3.379252 -0.61531 + -0.408321 -3.069544 0.823059 1.69915 1.30948 -0.328623 + 0.476726 0.916648 1.583858 0.757279 2.129612 1.386838 + -2.140558 2.214946 -4.171988 -1.055384 -6.363065 -0.232922 + -2.486751 0.823935 -2.418258 3.347586 -3.103635 4.864439 + 0.687061 3.597921 3.669743 1.43585 5.132502 2.724104 + -0.344691 1.08929 0.484513 1.884668 0.473244 3.022942 + -0.01352 2.068761 0.378264 6.65826 1.845318 5.542497 + 1.472489 0.175399 1.430793 -1.740909 2.30904 -2.30502 + -1.36358 -1.181833 2.025569 -1.358588 0.887958 -2.838158 + -0.499809 -1.988948 1.367195 -3.177085 1.789594 -4.928946 + 0.579613 -0.960476 -1.588234 -0.05789 -0.373062 -1.023304 + 0.927113 -0.301781 2.379761 -2.07879 0.994298 -2.428506 + -0.676988 0.933612 -1.737597 -2.080985 -0.549773 -0.651497 + 0.699549 -0.419557 1.900516 1.563553 1.759683 -0.08984 + -0.608903 -3.386912 -2.4601 -6.520148 -5.090986 -8.736865 + -0.200722 0.802307 -1.230158 0.889683 -1.228926 0.0694 + 2.155263 -0.50116 -0.789058 -0.572123 -1.208573 -0.913148) + (M 17.09375 21) + (c -1.221276 0.05745 -0.44882 1.331427 0.232503 0.449916) + (C 17.458514 21.23484 17.234278 21.104353 17.09375 21) + (m -7.5 0.125) + (c -1.2040413 0.60218 1.459244 1.052142 0.289004 0.112253) + (m 8.96875 1.5) + (c 0.38412 0.655402 -0.236077 2.74213 1.030518 1.55154 + 0.0634 -0.524592 -0.59842 -1.401743 -1.030518 -1.55154) + (m -0.21875 0.75) + (c -1.155615 0.198578 0.509999 1.388302 0.06733 0.201634) + (M 10.5 24.53125) + (c -0.117519 1.313533 1.058399 0.642504 0 0))) + +(define water-logo-material + (deep-flomap-material-value + 'cubic-zirconia 1.0 0.7 1.0 + 0.25 0.15 1.0 + 0.15 0.1 0.2 + 0.0)) + +(define logo-under-continents-color "black") +(define logo-continents-color "azure") +(define logo-water-color "lightskyblue") +(define logo-earth-outline-color logo-red-color) + +(define (continents-flomap color height) + (define scale (/ height 32)) + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen lambda-outline-color 3/8 'solid) + (send dc set-brush color 'solid) + (draw-path-commands dc 0 -17 continents-path-commands)) + scale)) + +(define (planet-flomap height) + (make-cached-flomap + [height] + (define scale (/ height 32)) + (define-values (earth-fm earth-z) + (let* ([indent-fm (continents-flomap logo-red-color height)] + [indent-dfm (flomap->deep-flomap indent-fm)] + [indent-dfm (deep-flomap-raise indent-dfm (* -1/8 scale))] + [indent-dfm (deep-flomap-smooth-z indent-dfm (* 1 scale))] + [earth-fm (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen logo-water-color 1/2 'solid) + (send dc set-brush logo-water-color 'solid) + (draw-ellipse/smoothed dc 0.75 0.75 30.5 30.5)) + scale)] + [earth-dfm (flomap->deep-flomap earth-fm)] + [earth-dfm (deep-flomap-bulge-spheroid earth-dfm (* 16 scale))] + [earth-dfm (deep-flomap-cc-superimpose 'add earth-dfm indent-dfm)]) + (values (deep-flomap-render-icon earth-dfm water-logo-material) + (deep-flomap-z earth-dfm)))) + + (define land-fm + (let* ([land-fm (continents-flomap logo-continents-color height)] + [land-dfm (flomap->deep-flomap land-fm)] + ;[land-dfm (deep-flomap-emboss land-dfm (* 2 scale) (* 8 scale))] + [land-dfm (deep-flomap-bulge-spheroid land-dfm (* 16 scale))] + [land-dfm (deep-flomap-smooth-z land-dfm (* 1/2 scale))]) + (deep-flomap-render-icon land-dfm metal-material))) + + (flomap-cc-superimpose + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen "lightblue" 1/2 'solid) + (send dc set-brush "white" 'transparent) + (send dc draw-ellipse 0.5 0.5 31 31) + (send dc set-pen lambda-outline-color 1/2 'solid) + (send dc draw-ellipse -0.25 -0.25 32.5 32.5)) + scale) + earth-fm + land-fm))) + +(define plt-logo (compose flomap->bitmap plt-flomap)) +(define planet-logo (compose flomap->bitmap planet-flomap)) diff --git a/collects/images/private/utils.rkt b/collects/images/private/utils.rkt index e9256a570a..167ec3aa43 100644 --- a/collects/images/private/utils.rkt +++ b/collects/images/private/utils.rkt @@ -64,9 +64,7 @@ (define (get-total-time-spent) total-time-spent) (define (make-cached-flomap* name proc size . args) - (define rendered-size - (cond [(size . < . 32) 32] - [else (expt 2 (inexact->exact (ceiling (/ (log size) (log 2)))))])) + (define rendered-size (if (size . < . 32) 32 size)) (define fm (weak-value-hash-ref! flomap-cache (list name rendered-size args) (λ () (apply proc rendered-size args)))) (flomap-scale fm (/ size rendered-size))) diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl index 58a193f50d..0f52745d3e 100644 --- a/collects/images/scribblings/icons.scrbl +++ b/collects/images/scribblings/icons.scrbl @@ -3,10 +3,18 @@ @(require scribble/eval unstable/latent-contract/defthing (for-label images/icons/arrow + images/icons/control + images/icons/file + images/icons/misc + images/icons/stickman mrlib/switchable-button racket racket/draw) - images/icons/arrow) + images/icons/arrow + images/icons/control + images/icons/file + images/icons/misc + images/icons/stickman) @(define (author-email) "neil.toronto@gmail.com") @@ -15,7 +23,8 @@ @(define icons-eval (make-base-eval)) -@interaction-eval[#:eval icons-eval (require racket/math racket/list images/icons/style)] +@interaction-eval[#:eval icons-eval (require racket/class racket/draw racket/math racket/list + images/icons/style)] @;{ @section{Introduction (What is an icon, really?)} @@ -41,6 +50,11 @@ It is composed of @(go-icon (solid-icon-color "blue") 16 'diffuse) to connote st The author of this collection is available to adapt or create SVG icons for DrRacket tools, and charges no more than your immortal soul. +@interaction[#:eval icons-eval + (require slideshow/pict) + (cc-superimpose (bitmap (record-icon "forestgreen" 96 glass-icon-material)) + (bitmap (step-icon "azure" 48 plastic-icon-material)))] + @section{Icon Parameters} @doc-apply[toolbar-icon-height]{ @@ -64,303 +78,216 @@ The style of DrRacket icons, used as a default argument throughout the @racketmo @section[#:tag "arrows"]{Arrow Icons} @defmodule[images/icons/arrow] - @interaction-eval[#:eval icons-eval (require images/icons/arrow)] @doc-apply[right-arrow-icon] @doc-apply[left-arrow-icon] @doc-apply[up-arrow-icon] @doc-apply[down-arrow-icon]{ -Cardinal direction arrows. - -@interaction[#:eval icons-eval - (list (right-arrow-icon syntax-icon-color (toolbar-icon-height)) - (left-arrow-icon run-icon-color) - (up-arrow-icon halt-icon-color 37) - (down-arrow-icon "lightblue" 44 glass-icon-material))] +@examples[#:eval icons-eval + (list (right-arrow-icon syntax-icon-color (toolbar-icon-height)) + (left-arrow-icon run-icon-color) + (up-arrow-icon halt-icon-color 37) + (down-arrow-icon "lightblue" 44 glass-icon-material))] } @doc-apply[right-over-arrow-icon] @doc-apply[left-over-arrow-icon] @doc-apply[right-under-arrow-icon] @doc-apply[left-under-arrow-icon]{ -@interaction[#:eval icons-eval - (list (right-over-arrow-icon metal-icon-color (toolbar-icon-height)) - (left-over-arrow-icon dark-metal-icon-color) - (right-under-arrow-icon run-icon-color 37) - (left-under-arrow-icon "lightgreen" 44 glass-icon-material))] +@examples[#:eval icons-eval + (list (right-over-arrow-icon metal-icon-color (toolbar-icon-height)) + (left-over-arrow-icon dark-metal-icon-color) + (right-under-arrow-icon run-icon-color 37) + (left-under-arrow-icon "lightgreen" 44 glass-icon-material))] } @section[#:tag "control"]{Control Icons} -@section[#:tag "file"]{File Icons} +@defmodule[images/icons/control] +@interaction-eval[#:eval icons-eval (require images/icons/control)] -@section[#:tag "tool"]{Tool Icons} - -@section[#:tag "stickman"]{Stickman Icons} - -@section[#:tag "misc"]{Miscellaneous Icons} - -@;{ -@subsection{Control Icons} - -@doc-apply[go-icon] -@doc-apply[bar-icon] +@doc-apply[play-icon] @doc-apply[back-icon] +@doc-apply[fast-forward-icon] +@doc-apply[rewind-icon] +@doc-apply[bar-icon] @doc-apply[stop-icon] @doc-apply[record-icon] +@doc-apply[pause-icon] @doc-apply[step-icon] @doc-apply[step-back-icon] @doc-apply[continue-icon] -@doc-apply[continue-back-icon] -@doc-apply[fast-forward-icon] -@doc-apply[rewind-icon] -@doc-apply[pause-icon]{ -These return typical ``playback'' icons. - -@interaction[#:eval icons-eval +@doc-apply[continue-back-icon]{ +Typical ``playback control'' icons. +For example, a colorful tape deck: +@interaction[#:eval icons-eval (for/list ([make-icon (list rewind-icon continue-back-icon step-back-icon back-icon pause-icon stop-icon - go-icon step-icon + play-icon step-icon continue-icon fast-forward-icon record-icon)] - [style (in-cycle icon-styles)]) - (make-icon (solid-icon-color "darkseagreen") 32 style))] - -The remaining icon @(bar-icon #f 16), returned by @racket[bar-icon], is used to build the others. + [color (list run-icon-color halt-icon-color + syntax-icon-color metal-icon-color + dark-metal-icon-color dark-metal-icon-color + metal-icon-color syntax-icon-color + halt-icon-color run-icon-color + "red")] + [material (in-cycle (list plastic-icon-material + glass-icon-material))]) + (make-icon color 32 material))] +The remaining icon @(bar-icon "red" 16), returned by @racket[bar-icon], is used to build the others. } -@subsection{Arrow Icons} +@section[#:tag "file"]{File Icons} -@doc-apply[up-arrow-icon] -@doc-apply[down-arrow-icon] -@doc-apply[left-arrow-icon] -@doc-apply[right-arrow-icon]{ +@defmodule[images/icons/file] +@interaction-eval[#:eval icons-eval (require images/icons/file)] + +@doc-apply[floppy-disk-icon]{ +@examples[#:eval icons-eval (floppy-disk-icon "gold" 32 glass-icon-material)] +} + +@doc-apply[save-icon] +@doc-apply[small-save-icon] +@doc-apply[load-icon] +@doc-apply[small-load-icon]{ @examples[#:eval icons-eval - (for/list ([make-icon (list up-arrow-icon down-arrow-icon - left-arrow-icon right-arrow-icon)]) - (for/list ([style (in-list icon-styles)]) - (make-icon (solid-icon-color "brown") (default-icon-height) style)))] + (for/list ([make-icon (list save-icon small-save-icon + load-icon small-load-icon)] + [color (list run-icon-color halt-icon-color + metal-icon-color dark-metal-icon-color)]) + (make-icon syntax-icon-color color 32))] } -@subsection{Sign Icons} +@section[#:tag "misc"]{Miscellaneous Icons} -@doc-apply[stop-sign-icon]{ -@examples[#:eval icons-eval (list (stop-sign-icon (default-icon-height) 'diffuse) - (stop-sign-icon (default-icon-height) 'shiny))] +@defmodule[images/icons/misc] +@interaction-eval[#:eval icons-eval (require images/icons/misc)] + +@doc-apply[text-icon]{ +Renders a text string as an icon. For example, +@interaction[#:eval icons-eval + (text-icon "An Important Point!" + (make-object font% 48 'decorative 'normal 'bold #t) + "lightskyblue" #t 2 48)] + +Before rendering, the drawn text is scaled so that it is exactly @racket[height] pixels tall. +Make sure the font is large enough that scaling does not create blurry and jagged edge artifacts, as in the following example: +@interaction[#:eval icons-eval + (text-icon "Q" (make-object font% 32 'default 'normal 'bold) + "green" #t 0 96)] +When @racket[str] contains tall letters or @racket[trim?] is @racket[#f], using @racket[height] as the font size should be sufficient. + +To make it easy to create a large enough font, @racket[text-icon] always interpets font sizes as being in pixels, never points. +See @racket[font%] for details on font sizes. + +If @racket[trim?] is @racket[#f], the drawn text is not cropped before rendering. +Otherwise, it is cropped to the smallest rectangle containing all the non-zero-alpha pixels. +Rendering very small glyphs shows the difference dramatically: +@interaction[#:eval icons-eval + (define font (make-object font% 32 'default)) + (list (text-icon "." font "white") + (text-icon "." font "white" #f))] +Note that both icons are @racket[(default-icon-height)] pixels tall. + +When @racket[outline] is @racket['auto], the outline drawn around the text is @racket[(/ height 32)] pixels wide. + +Because different platforms have slightly different fonts, @racket[text-icon] cannot guarantee the icons it returns have a consistent look or width across all platforms. } -@subsection{Check Icons} - -@doc-apply[check-icon]{ -@examples[#:eval icons-eval - (list (check-icon (solid-icon-color "green") 29 'diffuse) - (check-icon (solid-icon-color "green") 29 'shiny))] +@doc-apply[recycle-icon]{ +Returns the universal recycling symbol, rendered as an icon. +Its implementation calls @racket[text-icon] with the string @racket["\u267b"]. +@examples[#:eval icons-eval (recycle-icon "forestgreen" 48)] } @doc-apply[x-icon]{ -@examples[#:eval icons-eval - (for/list ([color icon-colors] - [style (in-cycle icon-styles)]) - (x-icon color 29 style))] +Returns an ``x'' icon that is guaranteed to look the same on all platforms. +(Anything similar that would be constructed by @racket[text-icon] would differ at least slightly across platforms.) +@examples[#:eval icons-eval (x-icon "red" 32)] } -@subsection{Miscellaneous Icons} +@doc-apply[check-icon]{ +@examples[#:eval icons-eval (check-icon "darkgreen" 32)] +} + +@doc-apply[regular-polygon-icon]{ +Renders the largest regular polygon with @racket[sides] sides, with the first vertex at angle @racket[start], that can be centered in a @racket[height] × @racket[height] box. +@examples[#:eval icons-eval (for/list ([sides (in-range 1 9)] + [material (in-cycle (list plastic-icon-material + glass-icon-material))]) + (regular-polygon-icon sides (* 1/4 pi) "cornflowerblue" 32 + material))] +} + +@doc-apply[octagon-icon]{ +Equivalent to @racket[(regular-polygon-icon 8 (/ (* 2 pi) 16) color height material)]. +@examples[#:eval icons-eval (octagon-icon halt-icon-color 32)] +} + +@doc-apply[stop-sign-icon]{ +@examples[#:eval icons-eval + (stop-sign-icon halt-icon-color 32 glass-icon-material)] +} + +@doc-apply[stop-signs-icon]{ +@examples[#:eval icons-eval + (stop-signs-icon halt-icon-color 32 plastic-icon-material)] +} @doc-apply[magnifying-glass-icon]{ -@examples[#:eval icons-eval (list (magnifying-glass-icon 31 'diffuse) - (magnifying-glass-icon 31 'shiny))] -Note that the uncolorized magnifying glass has a brown handle. -} - -@doc-apply[magnifying-glass-left-icon]{ -@examples[#:eval icons-eval (list (magnifying-glass-left-icon 31 'diffuse) - (magnifying-glass-left-icon 31 'shiny))] -} - -@doc-apply[disk-icon]{ @examples[#:eval icons-eval - (for/list ([color icon-colors] - [style (in-cycle icon-styles)]) - (disk-icon color 33 style))] + (magnifying-glass-icon "azure" "lightblue" 32 glass-icon-material)] } -@doc-apply[earth-icon]{ -@examples[#:eval icons-eval (list (earth-icon 48 'diffuse) - (earth-icon 48 'shiny))] -} - -@doc-apply[moon-icon]{ -@examples[#:eval icons-eval (list (moon-icon 48 'diffuse) - (moon-icon 48 'shiny))] -} - -@subsection{Symbols} - -@doc-apply[hash-quote-icon]{ -@examples[#:eval icons-eval (list (hash-quote-icon (toolbar-icon-height) 'diffuse) - (hash-quote-icon (toolbar-icon-height) 'shiny))] -} - -@doc-apply[plus-icon]{ +@doc-apply[left-magnifying-glass-icon]{ @examples[#:eval icons-eval - (for/list ([color icon-colors] - [style (in-cycle icon-styles)]) - (plus-icon color 24 style))] + (left-magnifying-glass-icon metal-icon-color "red" 32)] } -@doc-apply[times-icon]{ +@doc-apply[bomb-icon]{ @examples[#:eval icons-eval - (for/list ([color icon-colors] - [style (in-cycle icon-styles)]) - (times-icon color 24 style))] + (bomb-icon "azure" "black" 32 glass-icon-material)] } -@subsection{Logos} - -@doc-apply[plt-logo]{ +@doc-apply[left-bomb-icon]{ @examples[#:eval icons-eval - (list (plt-logo 128 'diffuse) (plt-logo 128 'shiny))] + (left-bomb-icon metal-icon-color dark-metal-icon-color 32)] } -@doc-apply[planet-logo]{ -@examples[#:eval icons-eval (list (planet-logo 128 'diffuse) - (planet-logo 128 'shiny))] +@section[#:tag "stickman"]{Stickman Icons} + +@defmodule[images/icons/stickman] +@interaction-eval[#:eval icons-eval (require images/icons/stickman)] + +@doc-apply[standing-stickman-icon]{ +Returns the icon displayed in DrRacket's lower-right corner when no program is running. +@examples[#:eval icons-eval (standing-stickman-icon run-icon-color "white" run-icon-color 64)] } +@doc-apply[running-stickman-icon]{ +Returns a frame of the icon animated in DrRacket's lower-right corner when a program is running. +The frame returned is for time @racket[t] of a run cycle with a one-second period. -@section{Icon Constants and Contracts} - -@;{ -@doc-apply[icon-colors]{ -A list containing the names of allowed icon colors. - -When an SVG icon source file is rendered, it is rendered once directly. Then, for each color corresponding to a symbol in @racket[icon-colors], it is colorized by replacing gradients, and then rendered. - -When loading an icon, a @racket[#f] color name loads an uncolorized rendering. -Every icon can be loaded with a @racket[#f] color name. -An icon can be loaded using any name in @racket[icon-colors] only if its SVG source has gradients that can be colorized. -See @secref["new-icons"] for details. - -The actual hues associated with the color names are the hues of the first seven @racketmodname[plot] color numbers. -The following example illustrates the correspondence: +It is difficult to put a code example in the API documentation that produces an animation. +However, we might use code similar to the following to sample from the run cycle: @interaction[#:eval icons-eval - (require plot) - (for/list ([color (rest icon-colors)]) - (stop-flomap color 48)) - (parameterize ([plot-width 48] - [plot-height 48] - [plot-decorations? #f] - [plot-background-alpha 0]) - (for/list ([n (in-range 7)]) - (plot3d-pict (surface3d (λ (x y) (- (sqr x) (sqr y))) -1 1 -1 1 - #:color n #:line-color n - #:samples 11 #:line-width 1))))] -This example also shows how to use @racketmodname[plot] to create icon @racket[pict]s from mathematical functions. -}} + (for/list ([t (in-range 0 1 1/12)]) + (running-stickman-icon t run-icon-color "white" run-icon-color 32))] +If instead of putting the icons in a list, we call their @racket[save-file] methods and hand-assemble the files into a GIF, we get something like this: -@doc-apply[icon-color/c]{ -A contract that identifies color names. +@centered[@image["scribblings/running-stickman.gif"]] + +Here, the run cycle is sampled and played back at 30 Hz. +The previous example samples the run cycle at 12 Hz, or every @racket[1/12] second. +DrRacket samples it at 12 Hz and plays it back at 5 Hz at the most. + +The stickman's joint angles are defined by continuous periodic functions, so the run cycle can be sampled at any resolution, or at any real-valued time @racket[t]. +The cycle is modeled after the run cycle of the player's avatar in the Commodore 64 game @link["http://en.wikipedia.org/wiki/Impossible_Mission"]{Impossible Mission}. } -@doc-apply[icon-styles]{ -Typical icon styles. +@section[#:tag "tool"]{Tool Icons} -It is not necessary to have a version of each icon in each style. -But if an icon has different styles, it should have these. -} - -@doc-apply[icon-style/c]{ -A contract that identifies icon styles. -} - - -@section{Icon @racket[pict]s} - -@interaction-eval[#:eval icons-eval (require slideshow/pict)] - -It is more flexible, but a little more complicated, to load icons as @racket[pict]s. -As picts, icons can easily be appended, inset, superimposed, blurred, and more. -For example, it is easy to make modern-looking media player controls using @racket[cc-superimpose] and the @racket['shiny] style: -@interaction[#:eval icons-eval - (define media-icon-background (record-flomap 'blue 64 'shiny)) - (list (cc-superimpose media-icon-background - (step-back-flomap 'white 32 'shiny)) - (cc-superimpose media-icon-background - (pause-flomap 'white 32 'shiny)) - (cc-superimpose media-icon-background - (step-flomap 'white 32 'shiny)))] - -Almost all of the functions in preceeding sections are defined in terms of the @racket[pict]-producing functions documented in this section. - -To use these functions effectively, you should require @racketmodname[icons] and @racketmodname[slideshow/pict] together. -Use @racket[bitmap] to convert a @racket[bitmap%] (e.g. an icon) to a @racket[pict], and @racket[pict->bitmap] to convert back. - -Converting from @racket[pict]s to bitmaps can be lossy. For example, converting text can look especially horrible: -@interaction[#:eval icons-eval - (scale (text "Hello" null 10) 5) - (scale (bitmap (pict->bitmap (text "Hello" null 10))) 5)] - -Therefore, when composing icons from parts, try to work only with @racket[pict]s, and convert to an icon using @racket[pict->bitmap] as the last step. - -When composing icons from parts, it is fine to use @racket[pict]s converted from @racket[bitmap%]s. -Without scaling or rotating, the conversion is lossless: -@interaction[#:eval icons-eval - (define not-blurry (magnifying-glass-icon 64 'shiny)) - not-blurry - (for/fold ([icon not-blurry]) ([i (in-range 30)]) - (pict->bitmap (bitmap icon)))] - -Avoid converting between @racket[pict]s and @racket[bitmap%]s more than once if bitmap-backed @racket[pict]s are scaled, rotated by angles that are not multiples of 90 degrees, or superimposed or appended at non-integer coordinates. -Avoid scaling up in general. - -@doc-apply[load-flomap]{ -Corresponds to @racket[load-icon]. In fact, @racket[load-icon] uses @racket[load-flomap] to load the icon as a @racket[pict], and passes it to @racket[pict->bitmap]. -} - -@doc-apply[go-flomap] -@doc-apply[bar-flomap] -@doc-apply[back-flomap] -@doc-apply[stop-flomap] -@doc-apply[record-flomap] -@doc-apply[step-flomap] -@doc-apply[step-back-flomap] -@doc-apply[continue-flomap] -@doc-apply[continue-back-flomap] -@doc-apply[fast-forward-flomap] -@doc-apply[rewind-flomap] -@doc-apply[pause-flomap]{ -These return typical ``playback'' icons, as @racket[pict]s. - -@interaction[#:eval icons-eval - (for/fold ([icon (blank)]) - ([make-flomap (list rewind-flomap continue-back-flomap - step-back-flomap back-flomap - pause-flomap stop-flomap - go-flomap step-flomap - continue-flomap fast-forward-flomap - record-flomap)]) - (hc-append icon (make-flomap 'black 32 'shiny) (blank 12)))] -} - -@doc-apply[up-arrow-flomap]{ Corresponds to @racket[up-arrow-icon]. } -@doc-apply[down-arrow-flomap]{ Corresponds to @racket[down-arrow-icon]. } -@doc-apply[left-arrow-flomap]{ Corresponds to @racket[left-arrow-icon]. } -@doc-apply[right-arrow-flomap]{ Corresponds to @racket[right-arrow-icon]. } - -@doc-apply[stop-sign-flomap]{ Corresponds to @racket[stop-sign-icon]. } -@doc-apply[check-flomap]{ Corresponds to @racket[check-icon]. } -@doc-apply[x-flomap]{ Corresponds to @racket[x-icon]. } -@doc-apply[magnifying-glass-flomap]{ Corresponds to @racket[magnifying-glass-icon]. } -@doc-apply[magnifying-glass-left-flomap]{ Corresponds to @racket[magnifying-glass-left-icon]. } -@doc-apply[disk-flomap]{ Corresponds to @racket[disk-icon]. } -@doc-apply[earth-flomap]{ Corresponds to @racket[earth-icon]. } -@doc-apply[moon-flomap]{ Corresponds to @racket[moon-icon]. } -@doc-apply[hash-quote-flomap]{ Corresponds to @racket[hash-quote-icon]. } -@doc-apply[plus-flomap]{ Corresponds to @racket[plus-icon]. } -@doc-apply[times-flomap]{ Corresponds to @racket[times-icon]. } -@doc-apply[plt-logo-pict]{ Corresponds to @racket[plt-logo]. } -@doc-apply[planet-logo-pict]{ Corresponds to @racket[planet-logo]. } - -} \ No newline at end of file +@section[#:tag "const"]{Icon Constants and Contracts} diff --git a/collects/images/scribblings/running-stickman.gif b/collects/images/scribblings/running-stickman.gif new file mode 100644 index 0000000000000000000000000000000000000000..79d9de52eeb7bd22649aa140242dd220d2bc0c42 GIT binary patch literal 43705 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 literal 0 HcmV?d00001 diff --git a/collects/images/tests/icon-tests.rkt b/collects/images/tests/icon-tests.rkt index fc6817a7f1..a362914aa2 100644 --- a/collects/images/tests/icon-tests.rkt +++ b/collects/images/tests/icon-tests.rkt @@ -37,7 +37,7 @@ ;; Other icons, various colors (define icon-procss - (list (list reverse-icon continue-back-icon step-back-icon back-icon pause-icon + (list (list rewind-icon continue-back-icon step-back-icon back-icon pause-icon stop-icon record-icon play-icon step-icon continue-icon fast-forward-icon) (list right-arrow-icon left-arrow-icon up-arrow-icon down-arrow-icon right-over-arrow-icon left-over-arrow-icon right-under-arrow-icon left-under-arrow-icon) From f13f4e4a8a5b9d12d4d88548ef63fe4fd9f77359 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Fri, 13 Jan 2012 23:51:31 -0700 Subject: [PATCH 477/746] Documented logos Please merge into release (cherry picked from commit 15f48a7b03912ee5687d207f14373f179ce49167) --- collects/images/logos.rkt | 31 ++++++++++++------- collects/images/private/logos.rkt | 8 +++-- .../images/scribblings/compile-time.scrbl | 2 +- collects/images/scribblings/logos.scrbl | 26 ++++++++++++++++ 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/collects/images/logos.rkt b/collects/images/logos.rkt index 8edff88ae0..015d0abf39 100644 --- a/collects/images/logos.rkt +++ b/collects/images/logos.rkt @@ -1,33 +1,40 @@ #lang racket/base -(require racket/promise - (prefix-in private- "private/logos.rkt") +(require racket/class racket/draw racket/promise + racket/contract unstable/latent-contract unstable/latent-contract/defthing + (rename-in "private/logos.rkt" + [plt-logo uncached-plt-logo] + [planet-logo uncached-planet-logo]) "private/flomap.rkt" "compile-time.rkt" (for-syntax racket/base - (prefix-in private- "private/logos.rkt") + (rename-in "private/logos.rkt" + [plt-logo uncached-plt-logo] + [planet-logo uncached-planet-logo]) "private/flomap.rkt")) -(provide plt-logo planet-logo - (rename-out [private-plt-flomap plt-flomap] - [private-planet-flomap planet-flomap])) +(provide (activate-contract-out + plt-logo plt-flomap + planet-logo planet-flomap) + (only-doc-out (all-from-out "private/logos.rkt")) + (only-doc-out (all-defined-out))) ;; Use a delay to keep from using more memory than necessary (saves 256KB) -(define standard-plt-logo (delay (compiled-bitmap (private-plt-logo 256)))) +(define standard-plt-logo (delay (compiled-bitmap (uncached-plt-logo 256)))) -(define (plt-logo height) +(defproc (plt-logo [height (and/c rational? (>=/c 0)) 256]) (is-a?/c bitmap%) (cond [(height . = . 256) (force standard-plt-logo)] [(height . <= . 256) (flomap->bitmap (flomap-resize (bitmap->flomap (force standard-plt-logo)) #f height))] [else - (private-plt-logo height)])) + (uncached-plt-logo height)])) -(define standard-planet-logo (delay (compiled-bitmap (private-planet-logo 256)))) +(define standard-planet-logo (delay (compiled-bitmap (uncached-planet-logo 256)))) -(define (planet-logo height) +(defproc (planet-logo [height (and/c rational? (>=/c 0)) 256]) (is-a?/c bitmap%) (cond [(height . = . 256) (force standard-planet-logo)] [(height . <= . 256) (flomap->bitmap (flomap-resize (bitmap->flomap (force standard-planet-logo)) #f height))] [else - (private-planet-logo height)])) + (uncached-planet-logo height)])) diff --git a/collects/images/private/logos.rkt b/collects/images/private/logos.rkt index dc873b1c72..4fbc7fb615 100644 --- a/collects/images/private/logos.rkt +++ b/collects/images/private/logos.rkt @@ -1,13 +1,15 @@ #lang racket/base (require racket/draw racket/class racket/match racket/math racket/flonum + racket/contract unstable/latent-contract unstable/latent-contract/defthing "flomap.rkt" "deep-flomap.rkt" "utils.rkt" "../icons/style.rkt") (provide plt-logo planet-logo - plt-flomap planet-flomap) + plt-flomap planet-flomap + (only-doc-out (all-defined-out))) (define glass-logo-material (deep-flomap-material-value @@ -99,7 +101,7 @@ (match-define (flomap _ c w h) fm) (fm+ fm (fm* z-amt (make-random-flomap c w h)))) -(define (plt-flomap height) +(defproc (plt-flomap [height (and/c rational? (>=/c 0)) 256]) flomap? (make-cached-flomap [height] (define scale (/ height 256)) @@ -243,7 +245,7 @@ (draw-path-commands dc 0 -17 continents-path-commands)) scale)) -(define (planet-flomap height) +(defproc (planet-flomap [height (and/c rational? (>=/c 0)) 256]) flomap? (make-cached-flomap [height] (define scale (/ height 32)) diff --git a/collects/images/scribblings/compile-time.scrbl b/collects/images/scribblings/compile-time.scrbl index b23069dada..677b1da753 100644 --- a/collects/images/scribblings/compile-time.scrbl +++ b/collects/images/scribblings/compile-time.scrbl @@ -7,5 +7,5 @@ @(define (author-email) "neil.toronto@gmail.com") -@title{Embedding Computed Bitmaps in Source Files} +@title{Embedding Bitmaps in Compiled Files} @author{@(author+email "Neil Toronto" (author-email))} diff --git a/collects/images/scribblings/logos.scrbl b/collects/images/scribblings/logos.scrbl index a2fdaa610f..fcfd4373ac 100644 --- a/collects/images/scribblings/logos.scrbl +++ b/collects/images/scribblings/logos.scrbl @@ -1,6 +1,7 @@ #lang scribble/manual @(require scribble/eval + unstable/latent-contract/defthing (for-label images/logos racket) images/logos) @@ -9,3 +10,28 @@ @title{Logos} @author{@(author+email "Neil Toronto" (author-email))} + +@defmodule[images/logos] + +@(define logos-eval (make-base-eval)) +@interaction-eval[#:eval logos-eval (require images/logos images/icons/style)] + +@doc-apply[plt-logo]{ +Returns the PLT logo, rendered on clear glass and blue metal by the ray tracer that renders icons. + +A 256×256 (default-size) rendering is compiled into the @racketmodname[images/logos] module using @racket[compiled-bitmap], meaning that constructing the logo at that size and smaller is cheap. +In fact, constructing the logo at the default size is essentially free: +@interaction[#:eval logos-eval + (time (plt-logo)) + (time (plt-logo 128)) + (time (plt-logo 257))] +} + +@doc-apply[planet-logo]{ +Returns an unofficial PLaneT logo. This is used as the PLaneT icon when DrRacket downloads PLaneT packages. + +As with the @racket[plt-logo], a default-size rendering is compiled into the @racketmodname[images/logos] module for performance reasons. +@interaction[#:eval logos-eval + (time (planet-logo)) + (planet-logo (default-icon-height))] +} From 0faf99b6311e3033967a3316047ab9f625edcff1 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Fri, 13 Jan 2012 22:00:06 -0900 Subject: [PATCH 478/746] Removed timing examples (not reliable) Please merge into release (cherry picked from commit 599dda47450e0e00eeee8ebe85a40a3e200e3046) --- collects/images/scribblings/logos.scrbl | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/collects/images/scribblings/logos.scrbl b/collects/images/scribblings/logos.scrbl index fcfd4373ac..1d5c40c47d 100644 --- a/collects/images/scribblings/logos.scrbl +++ b/collects/images/scribblings/logos.scrbl @@ -19,19 +19,18 @@ @doc-apply[plt-logo]{ Returns the PLT logo, rendered on clear glass and blue metal by the ray tracer that renders icons. +@examples[#:eval logos-eval (plt-logo)] + A 256×256 (default-size) rendering is compiled into the @racketmodname[images/logos] module using @racket[compiled-bitmap], meaning that constructing the logo at that size and smaller is cheap. -In fact, constructing the logo at the default size is essentially free: -@interaction[#:eval logos-eval - (time (plt-logo)) - (time (plt-logo 128)) - (time (plt-logo 257))] +In fact, constructing the logo at the default size is essentially free because it does not need to be downscaled. } @doc-apply[planet-logo]{ Returns an unofficial PLaneT logo. This is used as the PLaneT icon when DrRacket downloads PLaneT packages. +@examples[#:eval logos-eval + (planet-logo) + (planet-logo (default-icon-height))] + As with the @racket[plt-logo], a default-size rendering is compiled into the @racketmodname[images/logos] module for performance reasons. -@interaction[#:eval logos-eval - (time (planet-logo)) - (planet-logo (default-icon-height))] } From a5f236d18abefe351dedaa0372ab831f91b9418a Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Sat, 14 Jan 2012 14:20:28 -0700 Subject: [PATCH 479/746] Finished images/icons contracts and docs Please merge into release (cherry picked from commit b78ee4258ccd9832953eae96136923f1054df93b) --- collects/images/icons/file.rkt | 2 +- collects/images/icons/misc.rkt | 40 ++---- collects/images/icons/style.rkt | 101 +++++++++---- collects/images/icons/tool.rkt | 60 ++++++-- collects/images/scribblings/icons.scrbl | 180 +++++++++++++++++++----- collects/images/scribblings/logos.scrbl | 8 +- 6 files changed, 278 insertions(+), 113 deletions(-) diff --git a/collects/images/icons/file.rkt b/collects/images/icons/file.rkt index f44ea734a8..3af621ade2 100644 --- a/collects/images/icons/file.rkt +++ b/collects/images/icons/file.rkt @@ -43,7 +43,7 @@ [dfm (flomap->deep-flomap fm)] [dfm (deep-flomap-icon-style dfm)] [dfm (deep-flomap-scale-z dfm 1/16)]) - (deep-flomap-render-icon dfm metal-material))) + (deep-flomap-render-icon dfm metal-icon-material))) (define bottom-indent-fm (draw-icon-flomap diff --git a/collects/images/icons/misc.rkt b/collects/images/icons/misc.rkt index 61b2366202..caee86151a 100644 --- a/collects/images/icons/misc.rkt +++ b/collects/images/icons/misc.rkt @@ -158,7 +158,7 @@ [dfm (deep-flomap-icon-style dfm)] [dfm (deep-flomap-cc-superimpose 'add dfm indent-dfm)] [fm (deep-flomap-render-icon dfm material)]) - (flomap-cc-superimpose fm (x-flomap "azure" (* 22 scale) metal-material))))) + (flomap-cc-superimpose fm (x-flomap light-metal-icon-color (* 22 scale) metal-icon-material))))) (defproc (stop-signs-flomap [color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0)) (default-icon-height)] @@ -177,20 +177,13 @@ 0.25 0.25 0.0 0.0)) -(define magnifying-glass-metal-material - (deep-flomap-material-value - 3.0 0.5 0.0 1.0 - 0.8 0.1 0.2 - 0.2 0.8 0.0 - 0.0)) - -(defproc (magnifying-glass-flomap [metal-color (or/c string? (is-a?/c color%))] +(defproc (magnifying-glass-flomap [frame-color (or/c string? (is-a?/c color%))] [handle-color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0)) (default-icon-height)] [material deep-flomap-material-value? (default-icon-material)] ) flomap? (make-cached-flomap - [height metal-color handle-color material] + [height frame-color handle-color material] (define scale (/ height 32)) (define glass-fm (let* ([fm (draw-icon-flomap @@ -198,7 +191,7 @@ (send dc set-pen handle-color 1 'solid) (send dc set-brush "azure" 'solid) (draw-ellipse/smoothed dc 0 0 18 18) - (send dc set-alpha 0.75) + (send dc set-alpha 0.5) (send dc set-pen "black" 1 'solid) (send dc set-brush "white" 'transparent) (draw-ellipse/smoothed dc 0 0 18 18)) @@ -214,26 +207,23 @@ (send dc set-pen "black" 3 'solid) (send dc set-brush "black" 'solid) (draw-ellipse/smoothed dc 1 1 26 26) - (send dc set-pen metal-color 1 'solid) - (send dc set-brush metal-color 'solid) + (send dc set-pen frame-color 1 'solid) + (send dc set-brush frame-color 'solid) (draw-ellipse/smoothed dc 1 1 26 26)) scale)] [indent-fm (draw-icon-flomap 28 28 (λ (dc) - (send dc set-pen metal-color 1 'solid) - (send dc set-brush metal-color 'solid) + (send dc set-pen frame-color 1 'solid) + (send dc set-brush frame-color 'solid) (draw-ellipse/smoothed dc 5 5 18 18)) scale)] [indent-dfm (flomap->deep-flomap indent-fm)] - [indent-dfm (deep-flomap-raise indent-dfm (* -3 scale))] - ;[indent-dfm (deep-flomap-smooth-z indent-dfm (* 2 scale))] + [indent-dfm (deep-flomap-raise indent-dfm (* -4 scale))] [dfm (flomap->deep-flomap fm)] - ;[dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* 4 scale))] + [dfm (deep-flomap-raise dfm (* 12 scale))] [dfm (deep-flomap-cc-superimpose 'add dfm indent-dfm)] - [dfm (deep-flomap-smooth-z dfm (* 1 scale))] - ) - (deep-flomap-render-icon dfm magnifying-glass-metal-material))) + [dfm (deep-flomap-smooth-z dfm (* 2/3 scale))]) + (deep-flomap-render-icon dfm metal-icon-material))) (define handle-fm (let* ([fm (draw-icon-flomap @@ -253,12 +243,12 @@ handle-fm (flomap-pin* 1/2 1/2 1/2 1/2 circle-fm glass-fm)))) -(defproc (left-magnifying-glass-flomap [metal-color (or/c string? (is-a?/c color%))] +(defproc (left-magnifying-glass-flomap [frame-color (or/c string? (is-a?/c color%))] [handle-color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0)) (default-icon-height)] [material deep-flomap-material-value? (default-icon-material)] ) flomap? - (flomap-flip-horizontal (magnifying-glass-flomap metal-color handle-color height material))) + (flomap-flip-horizontal (magnifying-glass-flomap frame-color handle-color height material))) ;; --------------------------------------------------------------------------------------------------- ;; Bomb @@ -369,7 +359,7 @@ [stop-signs-icon stop-signs-flomap]) (define-icon-wrappers - ([metal-color (or/c string? (is-a?/c color%))] + ([frame-color (or/c string? (is-a?/c color%))] [handle-color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0)) (default-icon-height)] [material deep-flomap-material-value? (default-icon-material)]) diff --git a/collects/images/icons/style.rkt b/collects/images/icons/style.rkt index d8e99d8378..35a95ca76a 100644 --- a/collects/images/icons/style.rkt +++ b/collects/images/icons/style.rkt @@ -1,12 +1,80 @@ #lang racket (require racket/draw unstable/parameter-group - racket/contract unstable/latent-contract/defthing - (for-syntax unstable/latent-contract/serialize-syntax) + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt") -(provide (all-defined-out)) +(provide light-metal-icon-color + metal-icon-color + dark-metal-icon-color + syntax-icon-color + halt-icon-color + run-icon-color + plastic-icon-material + glass-icon-material + metal-icon-material + (activate-contract-out + default-icon-height + toolbar-icon-height + default-icon-material) + (only-doc-out (all-defined-out))) + +(defthing light-metal-icon-color (or/c string? (is-a?/c color%)) #:document-value + "azure") + +(defthing metal-icon-color (or/c string? (is-a?/c color%)) #:document-value + "lightsteelblue") + +(defthing dark-metal-icon-color (or/c string? (is-a?/c color%)) #:document-value + "steelblue") + +(defthing syntax-icon-color (or/c string? (is-a?/c color%)) #:document-value + (make-object color% 76 76 255)) + +(defthing halt-icon-color (or/c string? (is-a?/c color%)) #:document-value + (make-object color% 255 32 24)) + +(defthing run-icon-color (or/c string? (is-a?/c color%)) #:document-value + "lawngreen") + +(defparam default-icon-height (and/c rational? (>=/c 0)) 24) +(defparam toolbar-icon-height (and/c rational? (>=/c 0)) 16) + +(defthing plastic-icon-material deep-flomap-material-value? + (deep-flomap-material-value + 'cubic-zirconia 1.0 0.0 1.0 + 1.0 0.3 1.0 + 0.8 0.2 0.0 + 0.0)) + +(defthing glass-icon-material deep-flomap-material-value? + (deep-flomap-material-value + 'cubic-zirconia 1.0 0.75 0.2 + 1.0 0.2 1.0 + 0.2 0.4 0.25 + 0.08)) + +(defthing metal-icon-material deep-flomap-material-value? + (deep-flomap-material-value + 2.0 2.0 0.0 1.0 + 0.7 0.15 0.0 + 0.2 0.8 0.0 + 0.0)) + +(defparam default-icon-material deep-flomap-material-value? plastic-icon-material) + +;; =================================================================================================== +;; Unpublished so far + +(provide deep-flomap-render-icon + deep-flomap-icon-style + draw-icon-flomap + flomap-render-icon + draw-rendered-icon-flomap + flomap-render-thin-icon + draw-short-rendered-icon-flomap + define-icon-wrappers) (define icon-lighting (deep-flomap-lighting-value @@ -15,33 +83,6 @@ '(1.0 1.0 1.0) '(1.0 1.0 1.0))) -(define plastic-icon-material - (deep-flomap-material-value - 'cubic-zirconia 1.0 0.0 1.0 - 1.0 0.3 1.0 - 0.8 0.2 0.0 - 0.0)) - -(define glass-icon-material - (deep-flomap-material-value - 'cubic-zirconia 1.0 0.75 0.15 - 1.0 0.2 1.0 - 0.2 0.4 0.25 - 0.08)) - -(define metal-icon-color "lightsteelblue") -(define dark-metal-icon-color "steelblue") -(define syntax-icon-color (make-object color% 76 76 255)) -(define halt-icon-color (make-object color% 255 32 24)) -(define run-icon-color "lawngreen") - -(define default-icon-material (make-parameter plastic-icon-material)) -(define default-icon-height (make-parameter 24)) -(define toolbar-icon-height (make-parameter 16)) - -;(default-icon-material glass-icon-material) -;(default-icon-material matte-material) - (define (deep-flomap-render-icon dfm material) ;(printf "rendering~n") (parameterize/group ([deep-flomap-material material] diff --git a/collects/images/icons/tool.rkt b/collects/images/icons/tool.rkt index 8903f407d8..3b341c08d8 100644 --- a/collects/images/icons/tool.rkt +++ b/collects/images/icons/tool.rkt @@ -1,6 +1,7 @@ #lang racket/base (require racket/draw racket/class racket/math racket/sequence + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" @@ -8,52 +9,81 @@ "misc.rkt" "style.rkt") -(provide (all-defined-out)) +(provide debugger-bomb-color + macro-stepper-hash-color + (activate-contract-out + check-syntax-icon check-syntax-flomap + small-check-syntax-icon small-check-syntax-flomap + macro-stepper-icon macro-stepper-flomap + small-macro-stepper-icon small-macro-stepper-flomap + debugger-icon debugger-flomap + small-debugger-icon small-debugger-flomap) + (only-doc-out (all-defined-out))) -(define debugger-bomb-color (make-object color% 128 32 32)) -(define macro-stepper-hash-color (make-object color% 30 96 30)) +(defthing debugger-bomb-color (or/c string? (is-a?/c color%)) #:document-value + (make-object color% 128 32 32)) -(define (check-syntax-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) +;; Actual color is too dark after rendering +;(define macro-stepper-hash-color (make-object color% 30 96 30)) +(defthing macro-stepper-hash-color (or/c string? (is-a?/c color%)) #:document-value + (make-object color% 90 192 90)) + +(defproc (check-syntax-flomap [height (and/c rational? (>=/c 0)) (toolbar-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-ht-append (left-magnifying-glass-flomap metal-icon-color "chocolate" height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/32 height)))) 0) (check-flomap syntax-icon-color height material))) -(define (small-check-syntax-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) +(defproc (small-check-syntax-flomap [height (and/c rational? (>=/c 0)) (toolbar-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-pin* 1 1 5/16 1 (check-flomap syntax-icon-color height material) (magnifying-glass-flomap metal-icon-color "chocolate" (* 3/4 height) material))) -(define (macro-stepper-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) +(defproc (macro-stepper-flomap [height (and/c rational? (>=/c 0)) (toolbar-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-ht-append (text-flomap "#'" (make-object font% (max 1 (min 1024 height)) 'system) macro-stepper-hash-color #t 'auto height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/32 height)))) 0) (step-flomap syntax-icon-color height material))) -(define (small-macro-stepper-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) +(defproc (small-macro-stepper-flomap [height (and/c rational? (>=/c 0)) (toolbar-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-pin* 0 0 7/16 0 (step-flomap syntax-icon-color height material) (text-flomap "#'" (make-object font% (max 1 (min 1024 height)) 'system) macro-stepper-hash-color #t 'auto (* 3/4 height) material))) -(define (debugger-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) +(defproc (debugger-flomap [height (and/c rational? (>=/c 0)) (toolbar-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-ht-append (left-bomb-flomap metal-icon-color debugger-bomb-color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (step-flomap run-icon-color height material))) -(define (small-debugger-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) +(defproc (small-debugger-flomap [height (and/c rational? (>=/c 0)) (toolbar-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-pin* 0 0 9/16 0 (step-flomap run-icon-color height material) (left-bomb-flomap metal-icon-color debugger-bomb-color (* 3/4 height) material))) -(define check-syntax-icon (compose flomap->bitmap check-syntax-flomap)) -(define small-check-syntax-icon (compose flomap->bitmap small-check-syntax-flomap)) -(define macro-stepper-icon (compose flomap->bitmap macro-stepper-flomap)) -(define small-macro-stepper-icon (compose flomap->bitmap small-macro-stepper-flomap)) -(define debugger-icon (compose flomap->bitmap debugger-flomap)) -(define small-debugger-icon (compose flomap->bitmap small-debugger-flomap)) +(define-icon-wrappers + ([height (and/c rational? (>=/c 0)) (toolbar-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [check-syntax-icon check-syntax-flomap] + [small-check-syntax-icon small-check-syntax-flomap] + [macro-stepper-icon macro-stepper-flomap] + [small-macro-stepper-icon small-macro-stepper-flomap] + [debugger-icon debugger-flomap] + [small-debugger-icon small-debugger-flomap]) diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl index 0f52745d3e..383c8ee5b3 100644 --- a/collects/images/scribblings/icons.scrbl +++ b/collects/images/scribblings/icons.scrbl @@ -2,19 +2,25 @@ @(require scribble/eval unstable/latent-contract/defthing - (for-label images/icons/arrow + (for-label racket racket/draw + images/icons/arrow images/icons/control images/icons/file images/icons/misc images/icons/stickman + images/icons/tool + images/icons/style + images/logos mrlib/switchable-button - racket - racket/draw) + slideshow/pict) + racket/class racket/draw images/icons/arrow images/icons/control images/icons/file images/icons/misc - images/icons/stickman) + images/icons/stickman + images/icons/tool + images/icons/style) @(define (author-email) "neil.toronto@gmail.com") @@ -23,56 +29,129 @@ @(define icons-eval (make-base-eval)) -@interaction-eval[#:eval icons-eval (require racket/class racket/draw racket/math racket/list - images/icons/style)] +@interaction-eval[#:eval icons-eval (require racket/class racket/draw racket/math racket/list)] -@;{ -@section{Introduction (What is an icon, really?)} -@margin-note*{This introduction describes an ideal, not necessarily the current state of things.} +@section{What is an icon?} +@margin-note*{This section describes an ideal that DrRacket and its tools are steadily approaching.} -As a first approximation, an icon is just a small bitmap with an alpha channel. -But the icons in this collection are not simply loaded from disk. -They are generated programmatically by drawing on a @racket[dc<%>], -Icons can also be rendered , resized, generated programmatically by drawing on a , or composed using @racket[pict] functions. +As a first approximation, an icon is just a small @racket[bitmap%], usually with an alpha channel. -The @racketmodname[icons] module is intended to make it possible to do all of these things, and to make it easy to get common icons in different colors, heights and styles. +But an icon also communicates. +Its shape and color are a visual metaphor for an action or a message. +Icons should be @bold{easily recognizable}, @bold{distinguishable}, @bold{visually consistent}, and @bold{metaphorically appropriate} for the actions and messages they are used with. +It can be difficult to meet all four requirements at once (``distinguishable'' and ``visually consistent' are often at odds), but good examples, good abstractions, and an existing icon library help considerably. -An icon communicates. Its shape and color are a visual metaphor for an action or a message. Icons should be easily recognizable, distinguishable, visually consistent, and metaphorically appropriate for the actions and messages they are used with. This is difficult to do well, but good examples, good abstractions, and an existing icon library help considerably. +@(define (hash-quote) (text-icon "#'" (make-object font% 32 'system) + macro-stepper-hash-color #t 'auto 16)) +@(define (step) (step-icon syntax-icon-color 16)) +@(define (play) (play-icon syntax-icon-color 16)) +@(define (bar) (bar-icon syntax-icon-color 16)) +@(define (macro-stepper) (macro-stepper-icon 16)) -@(define (hash-quote) (hash-quote-flomap (solid-icon-color '(41 128 38)) 16)) -@(define (step) (step-flomap (solid-icon-color "blue") 16 'diffuse)) -@(define (macro-stepper) (ht-append (hash-quote) (step))) - -Example: The Macro Stepper tool composes a new icon @(hash-quote) and an existing icon @(step), resulting in @(macro-stepper) for its toolbar icon. -The @(hash-quote) icon connotes syntax, and is the color of a syntax-quote as rendered by DrRacket by default. -The @(step) icon is colored like DrRacket colors identifier syntax by default, and is shaped using metaphors used in debugger toolbars, TV remotes, and music players around the world. -It is composed of @(go-icon (solid-icon-color "blue") 16 'diffuse) to connote starting and @(bar-icon (solid-icon-color "blue") 16 'diffuse) to connote immediately stopping---a ``step.'' +Example: The Macro Stepper icon is composed by appending a text icon @(hash-quote) and a step icon @(step) to get @(macro-stepper). +The syntax quote icon @(hash-quote) is the color that DrRacket colors syntax quotes by default. +The step icon @(step) is colored like DrRacket colors identifier syntax by default, and is shaped using metaphors used in debugger toolbars, TV remotes, and music players around the world. +It is composed of @(play) to connote starting and @(bar) to connote immediately stopping. -The author of this collection is available to adapt or create SVG icons for DrRacket tools, and charges no more than your immortal soul. +It would not do to have just @(step) as the Macro Stepper icon: it would be too easily confused with the Debugger icon @(step-icon run-icon-color 16), +especially for new users and people with certain forms of color-blindness, and thus fail to be distinguishable enough. +As another example, the Check Syntax icon @(check-syntax-icon 16) connotes inspecting and passing. Note that the check mark is also the color of syntax. + +@section{About These Icons} + +The icons in this collection are designed to be composed to create new ones: they are simple, thematically consistent, and can be constructed in any size and color. +Further, slideshow's @racket[pict] combiners offer a way to compose them almost arbitrarily. +For example, a media player application might create a large ``step'' button by superimposing a @racket[record-icon] and a @racket[step-icon]: @interaction[#:eval icons-eval - (require slideshow/pict) - (cc-superimpose (bitmap (record-icon "forestgreen" 96 glass-icon-material)) - (bitmap (step-icon "azure" 48 plastic-icon-material)))] + (require slideshow/pict images/icons/control images/icons/style) + (pict->bitmap + (cc-superimpose + (bitmap (record-icon "forestgreen" 96 glass-icon-material)) + (bitmap (step-icon light-metal-icon-color 48 metal-icon-material))))] -@section{Icon Parameters} +All the icons in this collection are first drawn using standard @racket[dc<%>] drawing commands. +Then, to get lighting effects, they are turned into 3D objects and @link["http://en.wikipedia.org/wiki/Ray_tracing_%28graphics%29"]{ray traced}. +Many are afterward composed to create new icons; for example, the @racket[stop-signs-icon] @(stop-signs-icon halt-icon-color 16) superimposes three @racket[stop-sign-icon]s, and the @racket[magnifying-glass-icon] @(magnifying-glass-icon metal-icon-color "orange" 16) is composed of three others (frame, glass and handle). + +The ray tracer helps keep icons visually consistent with each other and with physical objects in day-to-day life. +As an example of the latter, the @racket[record-icon], when rendered in clear glass, looks like the clear, round button on a @link["http://en.wikipedia.org/wiki/Wiimote"]{Wii Remote}. +See the @racket[plt-logo] and @racket[planet-logo] functions for more striking examples. + +When the rendering API is stable enough to publish, it will allow anyone who can draw a shape to turn that shape into a visually consistent icon. + + +@section{Icon Style} + +@defmodule[images/icons/style] +@interaction-eval[#:eval icons-eval (require images/icons/style)] + +Use these constants and parameters to help keep icon sets visually consistent. + +@doc-apply[light-metal-icon-color] +@doc-apply[metal-icon-color] +@doc-apply[dark-metal-icon-color]{ +Good colors to use with @racket[metal-icon-material]. See @racket[bomb-icon] and @racket[magnifying-glass-icon] for examples. +} + +@doc-apply[syntax-icon-color] +@doc-apply[halt-icon-color] +@doc-apply[run-icon-color]{ +Standard toolbar icon colors. + +Use @racket[syntax-icon-color] in icons that connote macro expansion or syntax. Example: +@interaction[#:eval icons-eval (step-icon syntax-icon-color 32)] + +Use @racket[halt-icon-color] in icons that connote stopping or errors. Example: +@interaction[#:eval icons-eval (stop-icon halt-icon-color 32)] + +Use @racket[run-icon-color] in icons that connote executing programs or evaluation. Examples: +@interaction[#:eval icons-eval + (play-icon run-icon-color 32) + (require images/icons/stickman) + (running-stickman-icon 0.9 run-icon-color "white" run-icon-color 32)] + +For new users and for accessibility reasons, do not try to differentiate icons for similar functions only by color. +} + +@doc-apply[default-icon-height]{ +The height of DrRacket's standard icons. +} @doc-apply[toolbar-icon-height]{ The height of DrRacket toolbar icons. -Use @racket[(toolbar-icon-height)] as the @racket[height] argument when loading common icons that will be used in DrRacket toolbars and buttons, or in the toolbars and buttons of DrRacket tools. +Use @racket[(toolbar-icon-height)] as the @racket[height] argument for common icons that will be used in toolbars, status bars, and buttons. (When making an icon for DrRacket's main toolbar, try to keep it nearly square so that it will not take up too much horizontal space when the toolbar is docked vertically. If you cannot, as with the Macro Stepper, send a thinner icon as the @racket[alternate-bitmap] argument to a @racket[switchable-button%].) } -@doc-apply[default-icon-height]{ -The height of standard (e.g. not toolbar) DrRacket icons, used as a default argument through the @racketmodname[icons] module. +@doc-apply[plastic-icon-material] +@doc-apply[glass-icon-material] +@doc-apply[metal-icon-material]{ +Materials for icons. + +Plastic is opaque and reflects a little more than glass. + +Glass is transparent but frosted, so it scatters refracted light. +It has the high refractive index of @link["http://en.wikipedia.org/wiki/Cubic_zirconia"]{cubic zirconia}, or fake diamond. +The ``glassy look'' cannot actually be achieved using glass. + +Metal reflects the most, its @link["http://en.wikipedia.org/wiki/Specular_highlight"]{specular highlight} is nearly the same color as the material (in the others, the highlight is white), +and it diffuses much more ambient light than directional. This is because, while plastic and glass mostly reflect light directly, metal mostly absorbs light and re-emits it. + +@examples[#:eval icons-eval + (require images/icons/misc) + (for/list ([material (list plastic-icon-material + glass-icon-material + metal-icon-material)]) + (bomb-icon light-metal-icon-color dark-metal-icon-color 32 material))] } -@doc-apply[default-icon-style]{ -The style of DrRacket icons, used as a default argument throughout the @racketmodname[icons] module. -} +@doc-apply[default-icon-material]{ +The material used for rendering most icons and icon parts. +There are exceptions; for example, the @racket[floppy-disk-icon] always renders the sliding cover in metal. } @section[#:tag "arrows"]{Arrow Icons} @@ -146,7 +225,7 @@ The remaining icon @(bar-icon "red" 16), returned by @racket[bar-icon], is used @interaction-eval[#:eval icons-eval (require images/icons/file)] @doc-apply[floppy-disk-icon]{ -@examples[#:eval icons-eval (floppy-disk-icon "gold" 32 glass-icon-material)] +@examples[#:eval icons-eval (floppy-disk-icon "crimson" 32 glass-icon-material)] } @doc-apply[save-icon] @@ -239,7 +318,8 @@ Equivalent to @racket[(regular-polygon-icon 8 (/ (* 2 pi) 16) color height mater @doc-apply[magnifying-glass-icon]{ @examples[#:eval icons-eval - (magnifying-glass-icon "azure" "lightblue" 32 glass-icon-material)] + (magnifying-glass-icon light-metal-icon-color "lightblue" 32 + glass-icon-material)] } @doc-apply[left-magnifying-glass-icon]{ @@ -249,7 +329,7 @@ Equivalent to @racket[(regular-polygon-icon 8 (/ (* 2 pi) 16) color height mater @doc-apply[bomb-icon]{ @examples[#:eval icons-eval - (bomb-icon "azure" "black" 32 glass-icon-material)] + (bomb-icon light-metal-icon-color "black" 32 glass-icon-material)] } @doc-apply[left-bomb-icon]{ @@ -290,4 +370,28 @@ The cycle is modeled after the run cycle of the player's avatar in the Commodore @section[#:tag "tool"]{Tool Icons} -@section[#:tag "const"]{Icon Constants and Contracts} +@defmodule[images/icons/tool] +@interaction-eval[#:eval icons-eval (require images/icons/tool)] + +@doc-apply[check-syntax-icon] +@doc-apply[small-check-syntax-icon]{ +Icons for Check Syntax. The @racket[small-check-syntax-icon] is used when the toolbar is on the side. +@examples[#:eval icons-eval (list (check-syntax-icon 32) (small-check-syntax-icon 32))] +} + +@doc-apply[macro-stepper-icon] +@doc-apply[small-macro-stepper-icon]{ +Icons for the Macro Stepper. The @racket[small-macro-stepper-icon] is used when the toolbar is on the side. +@examples[#:eval icons-eval (list (macro-stepper-icon 32) (small-macro-stepper-icon 32))] +} + +@doc-apply[debugger-icon] +@doc-apply[small-debugger-icon]{ +Icons for the Debugger. The @racket[small-debugger-icon] is used when the toolbar is on the side. +@examples[#:eval icons-eval (list (debugger-icon 32) (small-debugger-icon 32))] +} + +@doc-apply[debugger-bomb-color] +@doc-apply[macro-stepper-hash-color]{ +Constants used within @racketmodname[images/icons/tool]. +} diff --git a/collects/images/scribblings/logos.scrbl b/collects/images/scribblings/logos.scrbl index 1d5c40c47d..d3917d2b60 100644 --- a/collects/images/scribblings/logos.scrbl +++ b/collects/images/scribblings/logos.scrbl @@ -17,12 +17,12 @@ @interaction-eval[#:eval logos-eval (require images/logos images/icons/style)] @doc-apply[plt-logo]{ -Returns the PLT logo, rendered on clear glass and blue metal by the ray tracer that renders icons. +Returns the PLT logo, rendered in tinted glass and azure metal by the ray tracer that renders icons. @examples[#:eval logos-eval (plt-logo)] -A 256×256 (default-size) rendering is compiled into the @racketmodname[images/logos] module using @racket[compiled-bitmap], meaning that constructing the logo at that size and smaller is cheap. -In fact, constructing the logo at the default size is essentially free because it does not need to be downscaled. +A 256×256 (default height) rendering is compiled into the @racketmodname[images/logos] module using @racket[compiled-bitmap], meaning that constructing the logo at that size and smaller is cheap. +In fact, constructing the logo at the default height is essentially free because it does not need to be downscaled. } @doc-apply[planet-logo]{ @@ -32,5 +32,5 @@ Returns an unofficial PLaneT logo. This is used as the PLaneT icon when DrRacket (planet-logo) (planet-logo (default-icon-height))] -As with the @racket[plt-logo], a default-size rendering is compiled into the @racketmodname[images/logos] module for performance reasons. +As with the @racket[plt-logo], a default-height rendering is compiled into the @racketmodname[images/logos] module for performance reasons. } From df9c2f8d7b9843ae7cdebdfa21cd108b59f45666 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 15 Jan 2012 17:04:38 -0700 Subject: [PATCH 480/746] fix typo (patch from Gustavo Massaccesi) Closes PR 12489 Merge to 5.2.1 (cherry picked from commit 96dea8c732d7ea6f07800fa82eb1133c91f63e67) --- collects/scribblings/reference/chaperones.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/reference/chaperones.scrbl b/collects/scribblings/reference/chaperones.scrbl index 41269cd949..cad6b8962d 100644 --- a/collects/scribblings/reference/chaperones.scrbl +++ b/collects/scribblings/reference/chaperones.scrbl @@ -431,7 +431,7 @@ not be used if @racket[vec] is immutable.} [prop-val any] ... ...) (and/c box? chaperone?)]{ -Like @racket[prox-box], but with support for immutable boxes. The +Like @racket[impersonate-box], but with support for immutable boxes. The @racket[unbox-proc] procedure must produce the same value or a chaperone of the original value, and @racket[set-proc] must produce the same value or a chaperone of the value that it is given. The From 324234ff667584d4feac3e587ce233f8ea1e59db Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 15 Jan 2012 20:27:20 -0500 Subject: [PATCH 481/746] Minor improvements, mainly to the header/status suffixes. (cherry picked from commit 3bdf05d7e179c8e46a997975462ff0e232193ab4) --- collects/meta/build/build | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index d0691965f9..d0debf4b33 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -706,12 +706,13 @@ git_get() { # inputs: git repository, git branch, path in $maindir } base_status="" +machine_suffix="" write_status() { - local message="$*" + local message="${*}${machine_suffix}" if [[ "$gitbranch" != "master" ]]; then message="($gitbranch build) $message" fi - if [[ "$machine" = "$workmachine" ]]; then + if [[ "x$machine_suffix" = "x" ]]; then if [[ ! -e "$statusfile" ]]; then touch "$statusfile" chcon --type=httpd_sys_content_t "$statusfile" @@ -724,16 +725,12 @@ write_status() { } header() { - local suffix="" - if [[ "${machine:-$workmachine}" != "$workmachine" ]]; then - suffix=" [$machine($platform)]" - fi local status="" case "x$1" in - ( "x-s" ) shift; status="${*}${suffix}"; base_status="$*";; - ( "x+s" ) shift; status="$base_status, ${*}${suffix}";; + ( "x-s" ) shift; status="$*"; base_status="$*";; + ( "x+s" ) shift; status="$base_status, $*";; esac - local message="${*}${suffix}" + local message="${*}${machine_suffix}" local line="============================================================" local message_len=${#message} local idx1=$(( ( 77 - $message_len ) / 2 )) @@ -1025,6 +1022,9 @@ MAIN_BUILD() { _run lockfile -r 0 -l 10800 "$lockfile" trap cleanup_run_files 0 3 9 15 + # cleanup bg logs early so the status won't show bogus leftovers + _rm "$bglogfile-"* + ## -------------------------------------------------------------------------- header -s "Begin ($(date +'%Y-%m-%d %H:%M'))" @@ -1075,7 +1075,6 @@ MAIN_BUILD() { header -s "Dispatching build jobs" local m - _rm "$bglogfile-"* if is_yes make_bins; then for m in "${machines[@]}"; do DO_COPY_BUILD "$m"; done else @@ -2206,6 +2205,9 @@ if [[ "$1" = "--dispatch" ]]; then machine="$1"; go="$2"; shift 2 init_repo_vars # set the repository variables according to the env vars machineget platform # set the global platform for dependable script pieces + if [[ "${machine:-$workmachine}" != "$workmachine" ]]; then + machine_suffix=" [$machine($platform)]" + fi show "Working on $machine($platform)" show "Dispatching to $go($*)" "$go" "$@" From 0d93dd54dbd6c8a00d4d9756748a6a7442aa6959 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 15 Jan 2012 20:28:04 -0500 Subject: [PATCH 482/746] Tiny typo. (cherry picked from commit e8356b3b91c4bbc66a5d03b35044662e6fbc3211) --- collects/scribblings/reference/paths.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/reference/paths.scrbl b/collects/scribblings/reference/paths.scrbl index 08e044a7c1..b7bb93978c 100644 --- a/collects/scribblings/reference/paths.scrbl +++ b/collects/scribblings/reference/paths.scrbl @@ -313,7 +313,7 @@ a complete path, it is returned as the result. Otherwise, @racket[base]. If @racket[base] is not a complete path, the @exnraise[exn:fail:contract]. -The @racket[path] and @racket[base] arguments can paths for any +The @racket[path] and @racket[base] arguments can be paths for any platform; if they are for different platforms, the @exnraise[exn:fail:contract]. From 853e6be73809cd7138d498ebeca51d175acd3cde Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 15 Jan 2012 20:34:48 -0500 Subject: [PATCH 483/746] New build request functionality. (cherry picked from commit 4d04c04aa24d5af56a71c16abfc4cf940bc0f1a3) --- collects/meta/build/current-build-status.cgi | 80 ++++++++++++++++---- 1 file changed, 66 insertions(+), 14 deletions(-) diff --git a/collects/meta/build/current-build-status.cgi b/collects/meta/build/current-build-status.cgi index 94b72c16b3..aa5d59cc49 100644 --- a/collects/meta/build/current-build-status.cgi +++ b/collects/meta/build/current-build-status.cgi @@ -1,11 +1,46 @@ -# these should be writable +# these should be writable (for the web server) cache="/tmp/racket-build-status-cache" cachelock="$cache-lock" +requestfile="/tmp/racket-build-request" +requeststatusfile="/tmp/racket-build-request-status" printf 'Content-type: text/plain\r\nAccess-Control-Allow-Origin: *\r\n\r\n' -# cache status reports (avoids excessive work during builds) +if [[ "$PATH_INFO" = "/request" ]]; then + error() { echo "Error: $*"; exit 0; } + if [[ -e "$lockfile" ]]; then + if [[ -e "$statusfile" ]]; then error "a build is in progress" + else error "builds temporarily disabled"; fi + fi + request_rx='^([^&@]+@racket-lang[.]org)&([^&]+)&([0-9]+)$' + if [[ ! "$QUERY_STRING" =~ $request_rx ]]; then error "invalid request"; fi + username="${BASH_REMATCH[1]}" + branch="${BASH_REMATCH[2]}" + cookie="${BASH_REMATCH[3]}" + date="$(date +'%Y-%m-%d %H:%M')" + prevuser="" + if [[ -e "$requestfile" ]]; then + prevuser="$(cat "$requestfile" | head -1)" + rm -f "$requestfile" || error "could not remove previous request file" + rm -f "$requeststatusfile" + fi + touch "$requestfile" || error "could not create request file" + { echo "$username"; echo "$branch"; echo "$date"; echo "$cookie"; } \ + > "$requestfile" + if [[ "x$prevuser" = "x" ]]; then + echo "Request created for $username" + elif [[ "x$prevuser" = "x$username" ]]; then + echo "Request re-created for $username" + else + echo "Request created for $username, overwriting request for $prevuser" + fi + exit 0 +fi +############################################################################### +# status reporting + +# cache status reports (avoids excessive work during builds) # use a lockfile as a cheap hack to time cache refreshing if ! lockfile -r 0 -l 25 -s 0 "$cachelock" >& /dev/null \ && [[ -e "$cache" ]]; then @@ -14,14 +49,14 @@ fi { -files="" -if [[ -e "$lockfile" ]]; then L="Y"; else L="N"; fi -if [[ -e "$statusfile" ]]; then S="Y"; else S="N"; fi -if [[ -e "$statusfile_last" ]]; then S1="Y"; else S1="N"; fi +check_exists() { if [[ -e "$2" ]]; then eval "$1=Y"; else eval "$1=N"; fi; } +check_exists L "$lockfile" +check_exists S "$statusfile" +check_exists SL "$statusfile_last" +check_exists R "$requestfile" +check_exists RS "$requeststatusfile" -if [[ "$L$S" = "NY" ]]; then - printf 'Last build crashed abnormally.\n' -elif [[ "$S" = "Y" ]]; then +if [[ "$L$S" = "YY" ]]; then time_for_file() { local t="$(($(date +"%s") - $(stat -c "%Z" "$1")))" printf "%d:%02d:%02d" "$((t/3600))" "$(((t%3600)/60))" "$((t%60))" @@ -48,7 +83,26 @@ elif [[ "$S" = "Y" ]]; then fi else printf 'No build is running.\n' - if [[ "$S1" = "Y" ]]; then + if [[ "$L" = "Y" ]]; then + # lockfile exists, but no statusfile + printf '(Builds temporarily disabled.)\n' + elif [[ "$S" = "Y" ]]; then + # statusfile exists, but no lockfile + printf '(Last build crashed abnormally: status file not removed.)\n' + fi + if [[ "$R" = "Y" ]]; then + echo "" + { read R_user; read R_branch; read R_date; } < "$requestfile" + printf 'Pending build request for %s' "$R_user" + if [[ "x$R_branch" != "xmaster" ]]; then + printf ' (%s branch)' "$R_branch" + fi + echo " made at $R_date" + if [[ "$RS" = "Y" ]]; then awk '{ print " " $0 }' < "$requeststatusfile" + else echo " The request is fresh, and was not noticed by the system."; fi + fi + if [[ "$SL" = "Y" ]]; then + echo "" last="$(cat "$statusfile_last")" if [[ "x$last" = "xDone ("*")" ]]; then last="${last#Done (}" @@ -64,10 +118,8 @@ else printf 'Last build was unsuccessful (%s)\n' "$last" fi fi - if [[ "$L" = "Y" ]]; then - printf '(Builds temporarily disabled)\n' - fi fi -} > "$cache" 2>&1 +} > "$cache.$$" 2>&1 +mv "$cache.$$" "$cache" cat "$cache" From b96b647e2bdedde6d5c7c9fca68fdd291f016d42 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 15 Jan 2012 20:38:18 -0500 Subject: [PATCH 484/746] Disable some builds. * The darwin build on kauai (the machine is no longer maintained, and has no cairo installed). * The two debian builds (also no cairo). * Remove comment from osx64 build (which is now done on Robby's machine). (cherry picked from commit 4b17fe731afb623e64fad71ad59c345d941a5427) --- collects/meta/build/build | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index d0debf4b33..a14d589b84 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -85,8 +85,8 @@ defbuild "pitcairn2" "x86_64-win32" "test_gui=yes" \ "workdir=C:/build" # same here (see also commit log!) # The LDFLAGS is a workaround for a bug in Fink, see # http://wiki.finkproject.org/index.php/Fink:Packaging:Preparing_for_10.5#OpenGL_Bug -defbuild "kauai" "ppc-darwin" "configure_args=--enable-xonx --disable-mac64" \ - "LDFLAGS=-dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib" +# defbuild "kauai" "ppc-darwin" "configure_args=--enable-xonx --disable-mac64" \ +# "LDFLAGS=-dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib" defbuild "weatherwax" "ppc-osx-mac" \ "configure_args=--enable-sdk=/Developer/SDKs/MacOSX10.4u.sdk" defbuild "macintel" "i386-osx-mac" \ @@ -100,11 +100,10 @@ defbuild "ccs-linux" "i386-linux-ubuntu-karmic" "moveto=/proj/racket" # defbuild "brownbuild" "i386-linux-debian" # really an AMD64 machine # defbuild "inga" "i386-freebsd" # defbuild "chicago-unstable" "i386-linux-debian-unstable" -# These builds are courtesy of Mason Loring Bliss -defbuild "blisses1" "x86_64-linux-debian-lenny" -defbuild "blisses2" "x86_64-linux-debian-squeeze" -# And this is from Stephen De Gabrielle defbuild "osx64" "x86_64-osx-mac" +# These builds are courtesy of Mason Loring Bliss +# defbuild "blisses1" "x86_64-linux-debian-lenny" +# defbuild "blisses2" "x86_64-linux-debian-squeeze" # Start the main build last defbuild "$workmachine" "x86_64-linux-f14" "copytobak=$maindir" "test_gui=yes" msets "/" From a8642d8a4b7b5dc05392965066234b4c05641942 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Sun, 15 Jan 2012 20:57:02 -0700 Subject: [PATCH 485/746] Lightened icon outlines Added lambda icon, foot icon, search forward/back icons Doc fixes Stepper: icons on buttons, logo and about dialog Macro stepper: icons on buttons, logo and about dialog Please merge into release (cherry picked from commit 4a09c0458129dca9074dfb2947743dbc2ce8573c) --- collects/icons/bomb-32x32.png | Bin 2262 -> 2281 bytes collects/icons/macro-stepper-32x32.png | Bin 0 -> 2605 bytes collects/icons/stepper-32x32.png | Bin 0 -> 2549 bytes collects/images/gui.rkt | 97 +++++ collects/images/icons/arrow.rkt | 2 + collects/images/icons/control.rkt | 64 +++- collects/images/icons/file.rkt | 3 +- collects/images/icons/misc.rkt | 143 ++++++-- collects/images/icons/stickman.rkt | 31 +- collects/images/icons/style.rkt | 21 +- collects/images/logos.rkt | 345 ++++++++++++++++-- collects/images/private/logos.rkt | 290 --------------- .../images/scribblings/compile-time.scrbl | 2 + collects/images/scribblings/icons.scrbl | 83 +++-- collects/images/scribblings/logos.scrbl | 18 +- .../images/scribblings/running-stickman.gif | Bin 43705 -> 44789 bytes collects/macro-debugger/info.rkt | 1 + collects/macro-debugger/view/stepper.rkt | 62 +++- collects/stepper/drracket-button.rkt | 2 +- collects/stepper/info.rkt | 2 +- collects/stepper/private/mred-extensions.rkt | 17 +- collects/stepper/private/view-controller.rkt | 74 +++- collects/stepper/stepper-tool.rkt | 3 +- .../private/danish-string-constants.rkt | 8 +- .../private/english-string-constants.rkt | 4 +- .../private/french-string-constants.rkt | 4 +- .../private/german-string-constants.rkt | 4 +- .../private/japanese-string-constants.rkt | 8 +- .../private/korean-string-constants.rkt | 4 +- .../private/portuguese-string-constants.rkt | 8 +- .../private/russian-string-constants.rkt | 8 +- .../simplified-chinese-string-constants.rkt | 8 +- .../private/spanish-string-constants.rkt | 6 +- .../traditional-chinese-string-constants.rkt | 8 +- .../private/ukrainian-string-constants.rkt | 8 +- 35 files changed, 851 insertions(+), 487 deletions(-) create mode 100644 collects/icons/macro-stepper-32x32.png create mode 100644 collects/icons/stepper-32x32.png create mode 100644 collects/images/gui.rkt delete mode 100644 collects/images/private/logos.rkt diff --git a/collects/icons/bomb-32x32.png b/collects/icons/bomb-32x32.png index 2b491a0d17adff3b500d9f6de4c5e5bd755e2689..ba3f641e231049fd3727b9b062e206fca3acb90c 100644 GIT binary patch delta 2251 zcmV;+2sHQB5$O?-Hh-Q;L_t(og|(JzjGR>&$A9OXcP=}#yWRV4cYB#FEzqKEfkI6H z0f~xo30SJMQA0v721RHvY2<^ciG~mm0}2MC@$!jME{1|ip`k4{P(WH}?ZsMm?e2DW zr@OOrpLs9m96!uE%g}Cx5Bele-VZZ#{=fHs{^vO(05(BKGJnBS*5gJc(IU#RLXq!3 z3a|5jF7XVgx8fYQ@+Qu|^(RE>fzhq-+xsb>Ja5hR{L0HdtFc|e3L!AAmAv@uAD-Iy zKLgkV*Sozu^WaOgv@QUmfPsJQfJg3%(7pK)ZrXSU7C|mE!Gk~g0fWh=eQndHnuJoF zg-WH(cU_tjiGOS?7Ms>Vuvf#=S9Esn{pz-D`r`ncc!E36yN2du6W{?pAYsX+@agL% zk>L-xbZILZ@Mz)2n{VaC7oJ<&ohi_h9wVs~0It@_thECLtuIOk!N!A*Bk#TLx<_P3 z$HPC{wykn50CjbghcEj&ZK-pj?7-3C71q>Fw+1mUSB$o*2ghi9~{yWRj*>3`Z%j7UTO|vT`Nei3H0NiKcuu zd)KZfpM3sI2x%>%Tm@qw(h8{_gF6{#WCC8^4S#=pM$vi6YD%Rl<74B@Oiy7D95}F_ zTy6%0U|wr0Jv}|NcXW_UCW%HO2*7B~1OI3LM=a%RpsJby6ubGvl*1Etl_J-Q4{4fnsr6&4DO|gNLD90Y4A77q&XK<#!Z83m#*$^=C!qv zNG6FyA_yTc)}oX`Nl8Qq`eU(#kn)$C)_<>W0+1+1jvj?_6?`B1R{-S_SAFeHR$Tif zJZpLXy?qRwIL6|oD;PR)oIS5?r&P#tO`YNaK!Yd8IuuY^bhmam2MPbW$L`F{n{=?TiE z0+mvMWeXOuzP*{Qra0}Lo%mWaHaUqghHAA+zEEH~li~E#6cgz*r>CbWl*=_pYYD7H z1KL`o5DNI517HMi4iB+zIt$6B+QcI%IQhZ5=tPqKj!v#v*iTAWVoD(+5vHHO3GG0e@Z);D;R;LtqR# z6!opG4Jd2T)?xt%V7_GGKp(cZ6QOnO4me$eyfH+B00}4|kV2reMoEeCePnpH0j#w( z2xHLo4u$Hr*TuaMMhH=MHbK)=g!``j0-`Ano)44LFq0Ft8&YeO5FY|qi!=r)M9r0O zrrSD1*t+2vG&tZIgMS->2x~_i>2QC1F zvVaM#t&7)FU$@^ihHCBUYk0-cioQ&O*ohHH4ZwIBcI<#aLl70X#>_gPYR9LRi7*!* z0jP`D0YdRQfY$&}(Yk`xTh$tkKA7d!ai6F$u;Z`rk9R?cD1S!Enzap!ns8AAwR7EI zvxeD}&xS7CbMFlMwYAj^+3daQZ8$L?NX?9JVLDATeFC&6DN6NG@rJi*e7o5JGl%e8 z02*+ODa4if@pi5EDu7dlm)2?ab?2Fy@#N|e;Y5I%*ci z=YunIM1M4TdwQ%);y`sGo#0U~MfR7@%rQIVt5GW1hDS zK%EIt(E3n9%68w{PdP%w>H;QoL^oKj!yL?ZxW9q51mSN8uV7mf&ntLh()S;)>z(y4 z72tb8uvx+GiZLboVZ z!+{{!a75DDL+4umV;yL$^`ItFsVfECF08%U!hnV5aG|1tQ6t1|E5y^iLqmJF)r|PB Z^&fRecup*nA5;JU002ovPDHLkV1lU|KnDN- delta 2232 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 LNkvXXu0mjfoavy- literal 0 HcmV?d00001 diff --git a/collects/images/gui.rkt b/collects/images/gui.rkt new file mode 100644 index 0000000000..3ea5c95af7 --- /dev/null +++ b/collects/images/gui.rkt @@ -0,0 +1,97 @@ +#lang racket/base + +(require racket/gui racket/class string-constants) + +(provide bitmap-canvas% logo-about-dialog%) + +(define bitmap-canvas% + (class canvas% + (init parent) + (init-field bitmap) + (init [enabled #t] [vert-margin 0] [horiz-margin 0]) + + (inherit get-dc refresh min-width min-height) + + (super-new [parent parent] + [enabled enabled] + [vert-margin vert-margin] + [horiz-margin horiz-margin] + [stretchable-width #f] + [stretchable-height #f] + [style '(transparent no-focus)]) + + (min-width (send bitmap get-width)) + (min-height (send bitmap get-height)) + + (define/public (set-bitmap new-bitmap) + (set! bitmap new-bitmap) + (min-width (send bitmap get-width)) + (min-height (send bitmap get-height)) + (refresh)) + + (define/override (on-paint) + (send (get-dc) draw-bitmap bitmap 0 0)) + )) + +(define message-text% + (class text% + (init messages) + (super-new [auto-wrap #t]) + + (define writable? #t) + (define/augment (can-change-style? start len) writable?) + (define/augment (can-delete? start len) writable?) + (define/augment (can-insert? start len) writable?) + (define/augment (can-load-file? filename format) writable?) + (define/augment (can-save-file? filename format) writable?) + (define/override (can-do-edit-operation? op [recursive? #t]) + (case op + [(copy select-all) #t] + [else writable?])) + + (for ([message (in-list messages)]) + (send this insert message)) + (set! writable? #f))) + +(define message-canvas% + (class editor-canvas% + (init parent messages [horiz-margin 0] [vert-margin 0]) + (super-new [parent parent] + [editor (new message-text% [messages messages])] + [horizontal-inset 0] [vertical-inset 0] + [horiz-margin 0] [vert-margin 0] + [enabled #t] [style '(auto-vscroll auto-hscroll no-border transparent)]))) + +(define logo-about-dialog% + (class dialog% + (init label parent bitmap messages [width 640] [height 200] [enabled #t]) + (super-new [label label] + [parent parent] + [width width] + [height height] + [enabled enabled] + [spacing 10] + [border 10]) + + (define top-panel + (new horizontal-panel% [parent this] [alignment '(center top)] [spacing 20])) + + (define bitmap-canvas + (new bitmap-canvas% [parent top-panel] [bitmap bitmap])) + + (define message-canvas + (new message-canvas% [parent top-panel] [messages messages])) + + (define close-button + (new button% + [label (string-constant close)] + [parent this] + [callback (λ (_1 _2) + (when (send this can-close?) + (send this on-close) + (send this show #f)))] + [style '(border)])) + + (send close-button focus) + )) + diff --git a/collects/images/icons/arrow.rkt b/collects/images/icons/arrow.rkt index bbcdd5f3f8..e894e0fd25 100644 --- a/collects/images/icons/arrow.rkt +++ b/collects/images/icons/arrow.rkt @@ -26,6 +26,7 @@ (let ([color (->color% color)]) (draw-icon-flomap 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (send dc draw-polygon (list '(0 . 9) '(15 . 9) '(14 . 0) '(31 . 15.5) @@ -37,6 +38,7 @@ ) flomap? (draw-icon-flomap 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (draw-path-commands dc 0 0 '((m 0 15) diff --git a/collects/images/icons/control.rkt b/collects/images/icons/control.rkt index 36c244378a..2be8f1ccb3 100644 --- a/collects/images/icons/control.rkt +++ b/collects/images/icons/control.rkt @@ -18,14 +18,17 @@ pause-icon pause-flomap step-icon step-flomap step-back-icon step-back-flomap - continue-icon continue-flomap - continue-back-icon continue-back-flomap) + continue-forward-icon continue-forward-flomap + continue-backward-icon continue-backward-flomap + search-forward-icon search-forward-flomap + search-backward-icon search-backward-flomap) (only-doc-out (all-defined-out))) (define (flat-play-flomap color height) (draw-icon-flomap 24 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (send dc draw-polygon (list (cons 0 0) (cons 4 0) (cons 23 13) (cons 23 18) @@ -45,8 +48,18 @@ [height (and/c rational? (>=/c 0)) (default-icon-height)] [material deep-flomap-material-value? (default-icon-material)] ) flomap? - (define fm (play-flomap color height material)) - (flomap-pin* 3/2 1/2 1 1/2 fm fm)) + (make-cached-flomap + [height color material] + (define fm (draw-rendered-icon-flomap + 20 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) + (send dc set-brush color 'solid) + (send dc draw-polygon (list (cons 0 0) (cons 4 0) + (cons 19 13) (cons 19 18) + (cons 4 31) (cons 0 31)))) + (/ height 32) + material)) + (flomap-hc-append fm fm))) (defproc (stop-flomap [color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0)) (default-icon-height)] @@ -56,6 +69,7 @@ [height color material] (draw-rendered-icon-flomap 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (send dc draw-polygon (list '(0 . 0) '(31 . 0) '(31 . 31) '(0 . 31)))) (/ height 32) @@ -69,6 +83,7 @@ [height color material] (draw-rendered-icon-flomap 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (draw-ellipse/smoothed dc 0 0 32 32)) (/ height 32) @@ -82,6 +97,7 @@ [height color material] (draw-rendered-icon-flomap 8 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (send dc draw-polygon (list '(0 . 0) '(7 . 0) '(7 . 31) '(0 . 31)))) (/ height 32) @@ -126,24 +142,42 @@ (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (back-flomap color height material))) -(defproc (continue-flomap [color (or/c string? (is-a?/c color%))] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)] - ) flomap? +(defproc (continue-forward-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (play-flomap color height material))) -(defproc (continue-back-flomap [color (or/c string? (is-a?/c color%))] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)] - ) flomap? +(defproc (continue-backward-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (back-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (bar-flomap color height material))) +(defproc (search-forward-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-hc-append + (fast-forward-flomap color height material) + (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) + (bar-flomap color height material))) + +(defproc (search-backward-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-hc-append + (bar-flomap color height material) + (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) + (rewind-flomap color height material))) + (define-icon-wrappers ([color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0)) (default-icon-height)] @@ -158,5 +192,7 @@ [pause-icon pause-flomap] [step-icon step-flomap] [step-back-icon step-back-flomap] - [continue-icon continue-flomap] - [continue-back-icon continue-back-flomap]) + [continue-forward-icon continue-forward-flomap] + [continue-backward-icon continue-backward-flomap] + [search-forward-icon search-forward-flomap] + [search-backward-icon search-backward-flomap]) diff --git a/collects/images/icons/file.rkt b/collects/images/icons/file.rkt index 3af621ade2..18ca17c374 100644 --- a/collects/images/icons/file.rkt +++ b/collects/images/icons/file.rkt @@ -69,7 +69,7 @@ (send dc draw-rectangle 2.5 i 16 1))) scale)] [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-bulge-vertical dfm (* 4 scale))]) + [dfm (deep-flomap-bulge-vertical dfm (* 2 scale))]) (deep-flomap-render-icon dfm matte-material))) (define top-indent-fm @@ -84,6 +84,7 @@ (define case-fm (draw-icon-flomap 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (send dc draw-polygon (list '(0 . 3) '(3 . 0) '(28 . 0) '(31 . 3) diff --git a/collects/images/icons/misc.rkt b/collects/images/icons/misc.rkt index caee86151a..344a2288f6 100644 --- a/collects/images/icons/misc.rkt +++ b/collects/images/icons/misc.rkt @@ -16,6 +16,8 @@ octagon-icon octagon-flomap stop-sign-icon stop-sign-flomap stop-signs-icon stop-signs-flomap + foot-icon foot-flomap + lambda-icon lambda-flomap magnifying-glass-icon magnifying-glass-flomap left-magnifying-glass-icon left-magnifying-glass-flomap bomb-icon bomb-flomap @@ -30,7 +32,8 @@ (define mx 23.5) (draw-icon-flomap 32 32 (λ (dc) - (send dc set-pen (make-object pen% "black" 12 'solid 'projecting 'miter)) + (send dc set-pen (make-object pen% (icon-color->outline-color color) + 12 'solid 'projecting 'miter)) (send dc draw-line mn mn mx mx) (send dc draw-line mn mx mx mn) (send dc set-pen (make-object pen% color 10 'solid 'projecting 'miter)) @@ -41,6 +44,7 @@ (define (flat-check-flomap color height) (draw-icon-flomap 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (draw-path-commands dc 0 0 '((m 0 19) @@ -54,6 +58,7 @@ (let ([start (- start)]) (draw-icon-flomap 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (define dθ (/ (* 2 pi) sides)) (define θs (sequence->list (in-range start (+ start (* 2 pi)) dθ))) @@ -84,20 +89,22 @@ [height str family style weight underline? smoothing color trim? outline material] (let ([font (make-object font% size family style weight underline? smoothing #t)] [outline (if (equal? outline 'auto) (/ height 32) outline)]) + (define outline-color (icon-color->outline-color color)) + (define r (/ (send outline-color red) 255.0)) + (define g (/ (send outline-color green) 255.0)) + (define b (/ (send outline-color blue) 255.0)) (define-values (w h) (get-text-size str font)) (define ceiling-amt (inexact->exact (ceiling outline))) - (define fm - (let* ([fm (draw-flomap - w h (λ (dc) - (send dc set-font font) - (send dc set-text-foreground color) - (send dc draw-text str 0 0 #t)))] - [fm (if trim? (flomap-trim fm) fm)] - [fm (flomap-resize fm #f (- height (* 2 ceiling-amt)))] - [fm (flomap-inset fm ceiling-amt)] - [fm (if (outline . > . 0) (flomap-outlined fm outline) fm)]) - fm)) - (flomap-render-icon fm material)))) + (let* ([fm (draw-flomap + w h (λ (dc) + (send dc set-font font) + (send dc set-text-foreground color) + (send dc draw-text str 0 0 #t)))] + [fm (if trim? (flomap-trim fm) fm)] + [fm (flomap-resize fm #f (- height (* 2 ceiling-amt)))] + [fm (flomap-inset fm ceiling-amt)] + [fm (if (outline . > . 0) (flomap-outlined fm outline (list r g b)) fm)]) + (flomap-render-icon fm material))))) (defproc (recycle-flomap [color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0)) (default-icon-height)] @@ -129,6 +136,79 @@ [dfm (deep-flomap-raise dfm (* -12 scale))]) (deep-flomap-render-icon dfm material)))) +(define lambda-path-commands + '((m 8.5 1.5) + (c -1.6356765828908555 0.029546719528023596 + -3.191760877876106 0.5981878749262537 + -4.720477489085545 1.1242189706194692) + (c 0.6669351268436579 0.7142825307374631 + 0.5663221427728614 0.9399074888495575 + 0.8574087929203539 0.8856493838348083) + (c 1.1139361982300886 -0.26979469970501474 + 2.7661170029498527 -0.8976661899705014 + 3.5022074713864306 0.2920653404129794) + (c 1.604836361061947 2.027318824778761 + 2.2854387162241885 4.621830343362832 + 2.528554440117994 7.151444427138643) + (c 0.3116530407079646 1.536908007079646 + -2.857777387610619 7.039676186430679 + -3.8315742017699113 9.23609637758112) + (c -1.5828472448377582 2.792818935693215 + -2.9889992117994097 5.691217406489675 + -4.772427818289086 8.366316818879056) + (c 0.42649146902654866 0.5644402784660767 + 1.0427237946902654 0.34355411445427725 + 1.6228086182890855 0.25676724483775815) + (c 0.49529097817109147 -0.07420284601769911 + 0.9905831646017699 -0.14840448377581122 + 1.4858741427728612 -0.22260672566371684) + (c 1.5973270277286136 -3.787185161061947 + 3.3219870961651914 -7.263537085545722 + 4.820870569911505 -11.091467780530973) + (c 0.6830176660766961 -1.5775599008849557 + 1.0166688849557521 -2.445292667846608 + 1.8281710631268435 -3.4783485734513273) + (c 0.9620301781710914 0.5885710348082596 + 1.2484493215339232 2.040281637758112 + 1.77328405899705 3.0419137321533922) + (c 1.5467160542772862 3.979993184660766 + 3.0867486206489674 7.962568420058997 + 4.546565437168141 11.975105472566373) + (c 0.3820927622418879 0.13305596224188793 + 0.7742605970501475 0.5306156554572271 + 1.1366913510324481 0.14744150088495575) + (c 0.9533687693215339 -0.5878412460176992 + 2.0633098572271384 -0.9560281486725664 + 2.857080825958702 -1.7685525144542773) + (c -0.2264924884955752 -1.0982469474926253 + -0.9541940106194691 -2.1254820625368733 + -1.3975098902654866 -3.181664056637168) + (c -2.8100934230088495 -5.615961562241888 + -5.519535197640117 -11.572843233038348 + -7.278479027728613 -17.620018746902655) + (c -0.6478138147492625 -1.9033066855457228 + -1.4455158560471977 -4.19687149120944 + -3.5071903339233037 -4.948212008023599) + (c -0.46965654277286134 -0.13943394171091444 + -0.9645608778761062 -0.1662308436578171 + -1.451858010619469 -0.16614886324483774))) + +(defproc (lambda-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (make-cached-flomap + [height color material] + (draw-rendered-icon-flomap + 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 4 'solid) + (send dc set-brush (icon-color->outline-color color) 'solid) + (draw-path-commands dc 4 0 lambda-path-commands) + (set-icon-pen dc color 2 'solid) + (send dc set-brush color 'solid) + (draw-path-commands dc 4 0 lambda-path-commands)) + (/ height 32) + material))) + (defproc (regular-polygon-flomap [sides exact-positive-integer?] [start real?] [color (or/c string? (is-a?/c color%))] @@ -167,6 +247,24 @@ (flomap-pin* 3/16 1/4 0 0 fm (flomap-pin* 3/16 1/4 0 0 fm fm))) +(defproc (foot-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (make-cached-flomap + [height color material] + (draw-rendered-icon-flomap + 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) + (send dc set-brush color 'solid) + (draw-ellipse/smoothed dc 4 8 24 24) + (draw-ellipse/smoothed dc 0 10 5 4.5) + (draw-ellipse/smoothed dc 3 4.5 5.5 5.5) + (draw-ellipse/smoothed dc 8.75 1 6.25 6.25) + (draw-ellipse/smoothed dc 16 0 7 7) + (draw-ellipse/smoothed dc 23.5 1.5 8.5 10)) + (/ height 32) + material))) + ;; --------------------------------------------------------------------------------------------------- ;; Magnifying glass @@ -188,12 +286,8 @@ (define glass-fm (let* ([fm (draw-icon-flomap 18 18 (λ (dc) - (send dc set-pen handle-color 1 'solid) + (set-icon-pen dc (icon-color->outline-color "azure") 1 'solid) (send dc set-brush "azure" 'solid) - (draw-ellipse/smoothed dc 0 0 18 18) - (send dc set-alpha 0.5) - (send dc set-pen "black" 1 'solid) - (send dc set-brush "white" 'transparent) (draw-ellipse/smoothed dc 0 0 18 18)) scale)] [dfm (flomap->deep-flomap fm)] @@ -204,8 +298,9 @@ (define circle-fm (let* ([fm (draw-icon-flomap 28 28 (λ (dc) - (send dc set-pen "black" 3 'solid) - (send dc set-brush "black" 'solid) + (define outline-color (icon-color->outline-color frame-color)) + (send dc set-pen outline-color 3 'solid) + (send dc set-brush outline-color 'solid) (draw-ellipse/smoothed dc 1 1 26 26) (send dc set-pen frame-color 1 'solid) (send dc set-brush frame-color 'solid) @@ -228,6 +323,7 @@ (define handle-fm (let* ([fm (draw-icon-flomap 11 11 (λ (dc) + (set-icon-pen dc (icon-color->outline-color handle-color) 1 'solid) (send dc set-brush handle-color 'solid) (define p (new dc-path%)) (send p move-to 4 0) @@ -286,7 +382,7 @@ (define (bomb-cap-flomap color) (draw-icon-flomap 20 20 (λ (dc) - (send dc set-pen "black" 1 'solid) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) (draw-path-commands dc 0 0 '((m 1.5 11.5) (l 10 -10 2.5 2.5) @@ -306,6 +402,7 @@ (define sphere-fm (let* ([sphere-fm (draw-icon-flomap 30 30 (λ (dc) + (set-icon-pen dc (icon-color->outline-color bomb-color) 1 'solid) (send dc set-brush bomb-color 'solid) (draw-ellipse/smoothed dc 0 0 30 30)) scale)] @@ -356,7 +453,9 @@ [check-icon check-flomap] [octagon-icon octagon-flomap] [stop-sign-icon stop-sign-flomap] - [stop-signs-icon stop-signs-flomap]) + [stop-signs-icon stop-signs-flomap] + [foot-icon foot-flomap] + [lambda-icon lambda-flomap]) (define-icon-wrappers ([frame-color (or/c string? (is-a?/c color%))] diff --git a/collects/images/icons/stickman.rkt b/collects/images/icons/stickman.rkt index 69f2e48a3c..2cca41dc27 100644 --- a/collects/images/icons/stickman.rkt +++ b/collects/images/icons/stickman.rkt @@ -106,8 +106,9 @@ (define standing-right-hand-point (cons+ standing-right-elbow-point - (polar->cartesian (+ standing-right-elbow-angle standing-torso-angle standing-right-hand-angle) - lower-arm-length))) + (polar->cartesian + (+ standing-right-elbow-angle standing-torso-angle standing-right-hand-angle) + lower-arm-length))) (defproc (standing-stickman-flomap [color (or/c string? (is-a?/c color%))] [arm-color (or/c string? (is-a?/c color%))] @@ -120,7 +121,8 @@ (flomap-lt-superimpose (draw-short-rendered-icon-flomap 26 32 (λ (dc) - (send dc set-pen "black" (+ arm-width (* 2 line-width)) 'solid) + (send dc set-pen (icon-color->outline-color arm-color) + (+ arm-width (* 2 line-width)) 'solid) (send dc draw-lines (list standing-right-shoulder-point standing-right-elbow-point standing-right-hand-point)) @@ -132,17 +134,22 @@ material) (draw-short-rendered-icon-flomap 26 32 (λ (dc) - (send dc set-pen "black" (+ body-width (* 2 line-width)) 'solid) + (send dc set-pen (icon-color->outline-color color) + (+ body-width (* 2 line-width)) 'solid) (send dc draw-lines (list standing-neck-point standing-hip-point)) - (send dc set-pen "black" (+ leg-width (* 2 line-width)) 'solid) + + (send dc set-pen (icon-color->outline-color color) + (+ leg-width (* 2 line-width)) 'solid) (send dc draw-lines (list standing-hip-point standing-left-knee-point standing-left-foot-point)) (send dc draw-lines (list standing-hip-point standing-right-knee-point standing-right-foot-point)) + (send dc set-pen color body-width 'solid) (send dc draw-lines (list standing-neck-point standing-hip-point)) + (send dc set-pen color leg-width 'solid) (send dc draw-lines (list standing-hip-point standing-left-knee-point @@ -154,7 +161,8 @@ material) (draw-short-rendered-icon-flomap 26 32 (λ (dc) - (send dc set-pen "black" (+ arm-width (* 2 line-width)) 'solid) + (send dc set-pen (icon-color->outline-color arm-color) + (+ arm-width (* 2 line-width)) 'solid) (send dc draw-lines (list standing-left-shoulder-point standing-left-elbow-point standing-left-hand-point)) @@ -166,7 +174,7 @@ material) (draw-short-rendered-icon-flomap 26 32 (λ (dc) - (send dc set-pen "black" line-width 'solid) + (send dc set-pen (icon-color->outline-color head-color) line-width 'solid) (send dc set-brush head-color 'solid) (match-define (cons x y) standing-head-point) (draw-ellipse/smoothed dc (- x 3.5) (- y 3.5) 8 8)) @@ -262,7 +270,7 @@ [height t color material] (draw-rendered-icon-flomap 26 32 (λ (dc) - (send dc set-pen "black" line-width 'solid) + (send dc set-pen (icon-color->outline-color color) line-width 'solid) (send dc set-brush color 'solid) (match-define (cons x y) (running-head-point t)) (draw-ellipse/smoothed dc (- x 3.5) (- y 3.5) 8 8)) @@ -274,9 +282,10 @@ [height t body? color material] (draw-rendered-icon-flomap 26 32 (λ (dc) - (draw-running-leg dc t "black" (+ leg-width (* 2 line-width))) + (draw-running-leg dc t (icon-color->outline-color color) (+ leg-width (* 2 line-width))) (when body? - (draw-running-body dc t "black" (+ body-width (* 2 line-width))) + (draw-running-body dc t (icon-color->outline-color color) + (+ body-width (* 2 line-width))) (draw-running-body dc t color body-width)) (draw-running-leg dc t color leg-width)) (/ height 32) @@ -287,7 +296,7 @@ [height t color material] (draw-rendered-icon-flomap 26 32 (λ (dc) - (draw-running-arm dc t "black" (+ arm-width (* 2 line-width))) + (draw-running-arm dc t (icon-color->outline-color color) (+ arm-width (* 2 line-width))) (draw-running-arm dc t color arm-width)) (/ height 32) material))) diff --git a/collects/images/icons/style.rkt b/collects/images/icons/style.rkt index 35a95ca76a..94312b185a 100644 --- a/collects/images/icons/style.rkt +++ b/collects/images/icons/style.rkt @@ -74,7 +74,24 @@ draw-rendered-icon-flomap flomap-render-thin-icon draw-short-rendered-icon-flomap - define-icon-wrappers) + define-icon-wrappers + (activate-contract-out + icon-color->outline-color + set-icon-pen)) + +(defproc (set-icon-pen [dc (is-a?/c dc<%>)] + [color (or/c string? (is-a?/c color%))] + [width (>=/c 0)] + [style symbol?]) void? + (send dc set-pen (make-object pen% color width style 'projecting 'miter))) + +(defproc (icon-color->outline-color [color (or/c string? (is-a?/c color%))]) (is-a?/c color%) + (cond [(string? color) (icon-color->outline-color (send the-color-database find-color color))] + [else + (define r (send color red)) + (define g (send color green)) + (define b (send color blue)) + (make-object color% (quotient r 2) (quotient g 2) (quotient b 2))])) (define icon-lighting (deep-flomap-lighting-value @@ -103,7 +120,7 @@ (send dc set-scale scale scale) (send dc set-smoothing 'smoothed) (send dc set-origin (* 0.5 scale) (* 0.5 scale)) - (send dc set-pen (make-object pen% "black" 1 'solid 'projecting 'miter)) + (set-icon-pen dc "black" 10 'solid) (draw-proc dc)))) (define (flomap-render-icon fm material) diff --git a/collects/images/logos.rkt b/collects/images/logos.rkt index 015d0abf39..7d0d2634ab 100644 --- a/collects/images/logos.rkt +++ b/collects/images/logos.rkt @@ -1,40 +1,331 @@ #lang racket/base -(require racket/class racket/draw racket/promise +(require racket/class racket/draw racket/math racket/match racket/contract unstable/latent-contract unstable/latent-contract/defthing - (rename-in "private/logos.rkt" - [plt-logo uncached-plt-logo] - [planet-logo uncached-planet-logo]) "private/flomap.rkt" - "compile-time.rkt" - (for-syntax racket/base - (rename-in "private/logos.rkt" - [plt-logo uncached-plt-logo] - [planet-logo uncached-planet-logo]) - "private/flomap.rkt")) + "private/deep-flomap.rkt" + "private/utils.rkt" + "icons/misc.rkt" + "icons/style.rkt") (provide (activate-contract-out plt-logo plt-flomap - planet-logo planet-flomap) - (only-doc-out (all-from-out "private/logos.rkt")) + planet-logo planet-flomap + stepper-logo stepper-flomap + macro-stepper-logo macro-stepper-logo-flomap) (only-doc-out (all-defined-out))) -;; Use a delay to keep from using more memory than necessary (saves 256KB) -(define standard-plt-logo (delay (compiled-bitmap (uncached-plt-logo 256)))) +(define glass-logo-material + (deep-flomap-material-value + 'cubic-zirconia 0.7 0.6 0.4 + 0.2 0.1 1.0 + 0.2 0.1 0.1 + 0.0)) -(defproc (plt-logo [height (and/c rational? (>=/c 0)) 256]) (is-a?/c bitmap%) - (cond [(height . = . 256) (force standard-plt-logo)] - [(height . <= . 256) - (flomap->bitmap (flomap-resize (bitmap->flomap (force standard-plt-logo)) #f height))] - [else - (uncached-plt-logo height)])) +(define lambda-path-commands + '((m 97.5 10) + (c -12.267574371681416 0.22160039646017698 + -23.938206584070794 4.486409061946903 + -35.40358116814159 8.431642279646018 + 5.002013451327434 5.357118980530973 + 4.2474160707964606 7.049306166371681 + 6.430565946902655 6.642370378761062 + 8.354521486725664 -2.0234602477876105 + 20.745877522123894 -6.732496424778761 + 26.26655603539823 2.1904900530973452 + 12.036272707964603 15.204891185840708 + 17.140790371681415 34.66372757522124 + 18.964158300884954 53.635833203539825 + 2.3373978053097346 11.526810053097345 + -21.433330407079644 52.79757139823009 + -28.736806513274335 69.27072283185841 + -11.871354336283186 20.946142017699113 + -22.417494088495573 42.68413054867256 + -35.79320863716814 62.74737614159292 + 3.198686017699115 4.233302088495575 + 7.820428460176991 2.5766558584070793 + 12.171064637168142 1.925754336283186 + 3.714682336283186 -0.5565213451327433 + 7.429373734513274 -1.1130336283185842 + 11.14405607079646 -1.6695504424778762 + 11.979952707964602 -28.4038887079646 + 24.914903221238937 -54.476528141592915 + 36.156529274336286 -83.1860083539823 + 5.122632495575221 -11.831699256637167 + 7.625016637168141 -18.33969500884956 + 13.711282973451327 -26.087614300884955 + 7.215226336283186 4.414282761061947 + 9.363369911504424 15.302112283185838 + 13.299630442477875 22.814352991150443 + 11.600370407079646 29.849948884955747 + 23.150614654867255 59.71926315044247 + 34.09924077876106 89.81329104424779 + 2.8656957168141592 0.9979197168141594 + 5.806954477876106 3.9796174159292033 + 8.525185132743362 1.105811256637168 + 7.150265769911504 -4.4088093451327435 + 15.474823929203538 -7.170211115044248 + 21.428106194690265 -13.26414385840708 + -1.6986936637168142 -8.23685210619469 + -7.156455079646018 -15.941115469026549 + -10.48132417699115 -23.86248042477876 + -21.07570067256637 -42.11971171681416 + -41.39651398230088 -86.79632424778761 + -54.5885927079646 -132.15014060176992 + -4.858603610619468 -14.274800141592921 + -10.841368920353982 -31.4765361840708 + -26.303927504424777 -37.111590060176994 + -3.5224240707964602 -1.0457545628318583 + -7.2342065840707965 -1.2467313274336282 + -10.888935079646018 -1.2461164743362831))) +(define (draw-lambda dc x y w h) + (define-values (sx sy) (send dc get-scale)) + (draw-path-commands dc x y (scale-path-commands lambda-path-commands (/ w 240) (/ h 240))) + (send dc set-scale sx sy)) -(define standard-planet-logo (delay (compiled-bitmap (uncached-planet-logo 256)))) +(define blue-θ-start (* -45 (/ pi 180))) +(define blue-θ-end (* 110 (/ pi 180))) -(defproc (planet-logo [height (and/c rational? (>=/c 0)) 256]) (is-a?/c bitmap%) - (cond [(height . = . 256) (force standard-planet-logo)] - [(height . <= . 256) - (flomap->bitmap (flomap-resize (bitmap->flomap (force standard-planet-logo)) #f height))] - [else - (uncached-planet-logo height)])) +(define logo-red-color (make-object color% 255 36 32)) +(define logo-blue-color (make-object color% 32 36 255)) +(define lambda-outline-color (make-object color% 16 16 64)) +(define (lambda-pen color width) (make-object pen% color width 'solid 'projecting 'miter)) + +(define (make-arc-path x y w h start end [ccw? #t]) + (define p (new dc-path%)) + (send p arc x y w h start end ccw?) + (send p close) + p) + +(define (make-random-flomap c w h) + (build-flomap c w h (λ (k x y i) (random)))) + +(define (flomap-rough fm z-amt) + (match-define (flomap _ c w h) fm) + (fm+ fm (fm* z-amt (make-random-flomap c w h)))) + +(defproc (plt-flomap [height (and/c rational? (>=/c 0)) 256]) flomap? + (make-cached-flomap + [height] + (define scale (/ height 256)) + (define bulge-fm + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-pen logo-red-color 2 'transparent) + (send dc set-brush logo-red-color 'solid) + (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-end blue-θ-start)) + (send dc set-pen logo-blue-color 2 'transparent) + (send dc set-brush logo-blue-color 'solid) + (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-start blue-θ-end)) + (send dc set-pen (lambda-pen lambda-outline-color 10)) + (send dc set-brush lambda-outline-color 'solid) + (draw-lambda dc 8 8 240 240)) + scale)) + + (define (lambda-flomap color pen-width) + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-scale scale scale) + (send dc set-pen (lambda-pen color pen-width)) + (send dc set-brush color 'solid) + (draw-lambda dc 8 8 240 240)) + scale)) + + (let* ([bulge-dfm (flomap->deep-flomap bulge-fm)] + [bulge-dfm (deep-flomap-bulge-spheroid bulge-dfm (* 112 scale))] + [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] + [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 112 scale))] + [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] + [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] + [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] + [fm (flomap-cc-superimpose + fm + (lambda-flomap lambda-outline-color 10) + lambda-fm)] + [fm (flomap-cc-superimpose + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-pen "lightblue" 2 'solid) + (send dc set-brush "white" 'transparent) + (send dc draw-ellipse 7 7 242 242) + (send dc set-pen lambda-outline-color 4 'solid) + (send dc draw-ellipse 2 2 252 252)) + scale) + fm)]) + fm))) + +(define continents-path-commands + '((m 11.526653 18.937779) + (c 0.05278 0.724075 1.940414 1.202607 0.678885 2.296248 + 0.249172 0.918181 1.040063 1.620575 1.448285 0.308034 + 1.219485 -0.885607 3.250882 -0.938443 3.317014 -2.906655 + -1.599965 -1.033954 -4.029479 -0.431148 -5.444184 0.302373) + (M 11.53125 18.125) + (C 10.786965 18.380649 9.3917452 18.611001 9.1304904 19.245707 + 10.289001 19.269837 11.178405 18.606302 11.53125 18.125) + (M 8.1875 19.65625) + (C 7.2652998 23.370888 8.6787734 19.63772 9.9124431 20.95891 + 10.727811 21.80382 11.739516 20.92275 10.465247 20.422456 + 9.7714766 19.980166 8.3964342 19.699414 8.1875 19.65625) + (M 7.5625 21.125) + (c -0.9196331 -1.962382 -3.205955 1.390782 -4.0978229 2.41995 + -1.707808 2.289408 -2.72190385 5.078558 -2.9334271 7.9238 + 1.0237952 1.983695 5.5272247 2.76676 4.7145431 4.084262 + -0.7368064 1.151552 -0.8906555 2.601652 0.1135446 3.680893 + 2.7495495 2.364498 1.2541019 5.824595 2.5609489 6.229519 + 2.5755284 0.853846 2.7512924 -3.696022 4.1297234 -3.843434 + 0.745066 -1.051147 0.04765 -2.428466 1.056101 -3.411232) + (C 12.318556 36.222109 8.8169859 35.479018 8.6188979 33.8253 + 7.7181807 34.141675 7.0679715 33.334232 6.30372 33.30415 + 5.7220663 34.646967 3.9378253 34.122031 4.3012403 32.699798 + 3.024533 33.043038 4.3605584 31.222879 3.40625 31.28125 + 0.5 33 2.5 26.5 5.0295875 29.903027 + 5.5 30.5 6.9002733 26.371666 8.8261905 25.876953 + 9.8027554 25.533149 9.5159021 24.727855 8.5279357 25.0625 + 7.6214946 24.941384 9.6975411 24.462771 10.075856 24.483273 + 11.540792 24.233047 9.904685 23.334106 9.8601011 22.602389 + 9.0900535 22.676405 9.4028275 22.737933 9.1185443 22.100147 + 6.8948741 22.58513 7.6831847 24.739145 5.9002404 23.244912 + 4.6247757 22.264239 7.321322 21.942832 7.5625 21.125) + (m 15.15625 -0.9375) + (c -1.37421 0.06218 -2.005432 1.159129 -2.784107 1.978327 + -0.114565 1.368674 0.952693 -0.07002 1.385771 0.968032 + 0.953881 -0.129572 -0.01507 -1.993413 1.425543 -2.008859 + -0.269351 0.525838 -0.494795 1.470731 0.411144 1.15174 + -0.646943 0.90275 -1.874871 2.045333 -2.613442 0.960703 + 0.08813 0.809648 -1.042388 0.509104 -1.186702 1.40851 + -0.738698 0.338761 -1.028513 0.375271 -0.383294 1.119927 + -1.340908 -0.226887 -1.979854 2.002883 -0.346874 1.903539 + 3.128783 -3.578714 2.7333 -0.07275 3.379252 -0.61531 + -0.408321 -3.069544 0.823059 1.69915 1.30948 -0.328623 + 0.476726 0.916648 1.583858 0.757279 2.129612 1.386838 + -2.140558 2.214946 -4.171988 -1.055384 -6.363065 -0.232922 + -2.486751 0.823935 -2.418258 3.347586 -3.103635 4.864439 + 0.687061 3.597921 3.669743 1.43585 5.132502 2.724104 + -0.344691 1.08929 0.484513 1.884668 0.473244 3.022942 + -0.01352 2.068761 0.378264 6.65826 1.845318 5.542497 + 1.472489 0.175399 1.430793 -1.740909 2.30904 -2.30502 + -1.36358 -1.181833 2.025569 -1.358588 0.887958 -2.838158 + -0.499809 -1.988948 1.367195 -3.177085 1.789594 -4.928946 + 0.579613 -0.960476 -1.588234 -0.05789 -0.373062 -1.023304 + 0.927113 -0.301781 2.379761 -2.07879 0.994298 -2.428506 + -0.676988 0.933612 -1.737597 -2.080985 -0.549773 -0.651497 + 0.699549 -0.419557 1.900516 1.563553 1.759683 -0.08984 + -0.608903 -3.386912 -2.4601 -6.520148 -5.090986 -8.736865 + -0.200722 0.802307 -1.230158 0.889683 -1.228926 0.0694 + 2.155263 -0.50116 -0.789058 -0.572123 -1.208573 -0.913148) + (M 17.09375 21) + (c -1.221276 0.05745 -0.44882 1.331427 0.232503 0.449916) + (C 17.458514 21.23484 17.234278 21.104353 17.09375 21) + (m -7.5 0.125) + (c -1.2040413 0.60218 1.459244 1.052142 0.289004 0.112253) + (m 8.96875 1.5) + (c 0.38412 0.655402 -0.236077 2.74213 1.030518 1.55154 + 0.0634 -0.524592 -0.59842 -1.401743 -1.030518 -1.55154) + (m -0.21875 0.75) + (c -1.155615 0.198578 0.509999 1.388302 0.06733 0.201634) + (M 10.5 24.53125) + (c -0.117519 1.313533 1.058399 0.642504 0 0))) + +(define water-logo-material + (deep-flomap-material-value + 'cubic-zirconia 1.0 0.7 1.0 + 0.25 0.15 1.0 + 0.15 0.1 0.2 + 0.0)) + +(define logo-under-continents-color "black") +(define logo-continents-color "azure") +(define logo-water-color "lightskyblue") +(define logo-earth-outline-color logo-red-color) + +(define (continents-flomap color height) + (define scale (/ height 32)) + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen lambda-outline-color 3/8 'solid) + (send dc set-brush color 'solid) + (draw-path-commands dc 0 -17 continents-path-commands)) + scale)) + +(defproc (planet-flomap [height (and/c rational? (>=/c 0)) 256]) flomap? + (make-cached-flomap + [height] + (define scale (/ height 32)) + (define-values (earth-fm earth-z) + (let* ([indent-fm (continents-flomap logo-red-color height)] + [indent-dfm (flomap->deep-flomap indent-fm)] + [indent-dfm (deep-flomap-raise indent-dfm (* -1/8 scale))] + [indent-dfm (deep-flomap-smooth-z indent-dfm (* 1 scale))] + [earth-fm (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen logo-water-color 1/2 'solid) + (send dc set-brush logo-water-color 'solid) + (draw-ellipse/smoothed dc 0.75 0.75 30.5 30.5)) + scale)] + [earth-dfm (flomap->deep-flomap earth-fm)] + [earth-dfm (deep-flomap-bulge-spheroid earth-dfm (* 16 scale))] + [earth-dfm (deep-flomap-cc-superimpose 'add earth-dfm indent-dfm)]) + (values (deep-flomap-render-icon earth-dfm water-logo-material) + (deep-flomap-z earth-dfm)))) + + (define land-fm + (let* ([land-fm (continents-flomap logo-continents-color height)] + [land-dfm (flomap->deep-flomap land-fm)] + ;[land-dfm (deep-flomap-emboss land-dfm (* 2 scale) (* 8 scale))] + [land-dfm (deep-flomap-bulge-spheroid land-dfm (* 16 scale))] + [land-dfm (deep-flomap-smooth-z land-dfm (* 1/2 scale))]) + (deep-flomap-render-icon land-dfm metal-material))) + + (flomap-cc-superimpose + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen "lightblue" 1/2 'solid) + (send dc set-brush "white" 'transparent) + (send dc draw-ellipse 0.5 0.5 31 31) + (send dc set-pen lambda-outline-color 1/2 'solid) + (send dc draw-ellipse -0.25 -0.25 32.5 32.5)) + scale) + earth-fm + land-fm))) + +(defproc (stepper-flomap [height (and/c rational? (>=/c 0)) 96]) flomap? + (flomap-pin* + 1/2 20/32 1/2 1/2 + (foot-flomap "forestgreen" height glass-icon-material) + (lambda-flomap light-metal-icon-color (* 5/8 height) metal-icon-material))) + +(defproc (macro-stepper-logo-flomap [height (and/c rational? (>=/c 0)) 96]) flomap? + (define outline-color (icon-color->outline-color light-metal-icon-color)) + + (define (draw-hash dc) + (send dc draw-polygon '((5 . 0) (8 . 0) (6 . 19) (3 . 19))) + (send dc draw-polygon '((13 . 0) (16 . 0) (14 . 19) (11 . 19))) + (send dc draw-polygon '((1 . 4) (1 . 7) (19 . 7) (19 . 4))) + (send dc draw-polygon '((0 . 12) (0 . 15) (18 . 15) (18 . 12)))) + + (flomap-pin* + 1/2 20/32 1/2 1/2 + (foot-flomap (make-object color% 34 42 160) height glass-icon-material) + (draw-rendered-icon-flomap + 32 32 (λ (dc) + (send dc translate 6 6) + (set-icon-pen dc outline-color 2 'solid) + (send dc set-brush outline-color 'solid) + (draw-hash dc) + (send dc set-pen "black" 1 'transparent) + (send dc set-brush light-metal-icon-color 'solid) + (draw-hash dc)) + (/ (* 3/4 height) 32) + metal-icon-material))) + +(define-icon-wrappers + ([height (and/c rational? (>=/c 0)) 256]) + [plt-logo plt-flomap]) + +(define-icon-wrappers + ([height (and/c rational? (>=/c 0)) 96]) + [planet-logo planet-flomap] + [stepper-logo stepper-flomap] + [macro-stepper-logo macro-stepper-logo-flomap]) diff --git a/collects/images/private/logos.rkt b/collects/images/private/logos.rkt deleted file mode 100644 index 4fbc7fb615..0000000000 --- a/collects/images/private/logos.rkt +++ /dev/null @@ -1,290 +0,0 @@ -#lang racket/base - -(require racket/draw racket/class racket/match racket/math racket/flonum - racket/contract unstable/latent-contract unstable/latent-contract/defthing - "flomap.rkt" - "deep-flomap.rkt" - "utils.rkt" - "../icons/style.rkt") - -(provide plt-logo planet-logo - plt-flomap planet-flomap - (only-doc-out (all-defined-out))) - -(define glass-logo-material - (deep-flomap-material-value - 'cubic-zirconia 0.7 0.6 0.4 - 0.2 0.1 1.0 - 0.2 0.1 0.1 - 0.0)) - -(define lambda-path-commands - '((m 97.5 10) - (c -12.267574371681416 0.22160039646017698 - -23.938206584070794 4.486409061946903 - -35.40358116814159 8.431642279646018 - 5.002013451327434 5.357118980530973 - 4.2474160707964606 7.049306166371681 - 6.430565946902655 6.642370378761062 - 8.354521486725664 -2.0234602477876105 - 20.745877522123894 -6.732496424778761 - 26.26655603539823 2.1904900530973452 - 12.036272707964603 15.204891185840708 - 17.140790371681415 34.66372757522124 - 18.964158300884954 53.635833203539825 - 2.3373978053097346 11.526810053097345 - -21.433330407079644 52.79757139823009 - -28.736806513274335 69.27072283185841 - -11.871354336283186 20.946142017699113 - -22.417494088495573 42.68413054867256 - -35.79320863716814 62.74737614159292 - 3.198686017699115 4.233302088495575 - 7.820428460176991 2.5766558584070793 - 12.171064637168142 1.925754336283186 - 3.714682336283186 -0.5565213451327433 - 7.429373734513274 -1.1130336283185842 - 11.14405607079646 -1.6695504424778762 - 11.979952707964602 -28.4038887079646 - 24.914903221238937 -54.476528141592915 - 36.156529274336286 -83.1860083539823 - 5.122632495575221 -11.831699256637167 - 7.625016637168141 -18.33969500884956 - 13.711282973451327 -26.087614300884955 - 7.215226336283186 4.414282761061947 - 9.363369911504424 15.302112283185838 - 13.299630442477875 22.814352991150443 - 11.600370407079646 29.849948884955747 - 23.150614654867255 59.71926315044247 - 34.09924077876106 89.81329104424779 - 2.8656957168141592 0.9979197168141594 - 5.806954477876106 3.9796174159292033 - 8.525185132743362 1.105811256637168 - 7.150265769911504 -4.4088093451327435 - 15.474823929203538 -7.170211115044248 - 21.428106194690265 -13.26414385840708 - -1.6986936637168142 -8.23685210619469 - -7.156455079646018 -15.941115469026549 - -10.48132417699115 -23.86248042477876 - -21.07570067256637 -42.11971171681416 - -41.39651398230088 -86.79632424778761 - -54.5885927079646 -132.15014060176992 - -4.858603610619468 -14.274800141592921 - -10.841368920353982 -31.4765361840708 - -26.303927504424777 -37.111590060176994 - -3.5224240707964602 -1.0457545628318583 - -7.2342065840707965 -1.2467313274336282 - -10.888935079646018 -1.2461164743362831))) - -(define (draw-lambda dc x y w h) - (define-values (sx sy) (send dc get-scale)) - (draw-path-commands dc x y (scale-path-commands lambda-path-commands (/ w 240) (/ h 240))) - (send dc set-scale sx sy)) - -(define blue-θ-start (* -45 (/ pi 180))) -(define blue-θ-end (* 110 (/ pi 180))) - -(define logo-red-color (make-object color% 255 36 32)) -(define logo-blue-color (make-object color% 32 36 255)) -(define lambda-outline-color (make-object color% 16 16 64)) -(define (lambda-pen color width) (make-object pen% color width 'solid 'projecting 'miter)) - -(define (make-arc-path x y w h start end [ccw? #t]) - (define p (new dc-path%)) - (send p arc x y w h start end ccw?) - (send p close) - p) - -(define (make-random-flomap c w h) - (build-flomap c w h (λ (k x y i) (random)))) - -(define (flomap-rough fm z-amt) - (match-define (flomap _ c w h) fm) - (fm+ fm (fm* z-amt (make-random-flomap c w h)))) - -(defproc (plt-flomap [height (and/c rational? (>=/c 0)) 256]) flomap? - (make-cached-flomap - [height] - (define scale (/ height 256)) - (define bulge-fm - (draw-icon-flomap - 256 256 (λ (dc) - (send dc set-pen logo-red-color 2 'transparent) - (send dc set-brush logo-red-color 'solid) - (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-end blue-θ-start)) - (send dc set-pen logo-blue-color 2 'transparent) - (send dc set-brush logo-blue-color 'solid) - (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-start blue-θ-end)) - (send dc set-pen (lambda-pen lambda-outline-color 10)) - (send dc set-brush lambda-outline-color 'solid) - (draw-lambda dc 8 8 240 240)) - scale)) - - (define (lambda-flomap color pen-width) - (draw-icon-flomap - 256 256 (λ (dc) - (send dc set-scale scale scale) - (send dc set-pen (lambda-pen color pen-width)) - (send dc set-brush color 'solid) - (draw-lambda dc 8 8 240 240)) - scale)) - - (let* ([bulge-dfm (flomap->deep-flomap bulge-fm)] - [bulge-dfm (deep-flomap-bulge-spheroid bulge-dfm (* 112 scale))] - [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] - [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 112 scale))] - [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] - [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] - [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] - [fm (flomap-cc-superimpose - fm - (lambda-flomap lambda-outline-color 10) - lambda-fm)] - [fm (flomap-cc-superimpose - (draw-icon-flomap - 256 256 (λ (dc) - (send dc set-pen "lightblue" 2 'solid) - (send dc set-brush "white" 'transparent) - (send dc draw-ellipse 7 7 242 242) - (send dc set-pen lambda-outline-color 4 'solid) - (send dc draw-ellipse 2 2 252 252)) - scale) - fm)]) - fm))) - -(define continents-path-commands - '((m 11.526653 18.937779) - (c 0.05278 0.724075 1.940414 1.202607 0.678885 2.296248 - 0.249172 0.918181 1.040063 1.620575 1.448285 0.308034 - 1.219485 -0.885607 3.250882 -0.938443 3.317014 -2.906655 - -1.599965 -1.033954 -4.029479 -0.431148 -5.444184 0.302373) - (M 11.53125 18.125) - (C 10.786965 18.380649 9.3917452 18.611001 9.1304904 19.245707 - 10.289001 19.269837 11.178405 18.606302 11.53125 18.125) - (M 8.1875 19.65625) - (C 7.2652998 23.370888 8.6787734 19.63772 9.9124431 20.95891 - 10.727811 21.80382 11.739516 20.92275 10.465247 20.422456 - 9.7714766 19.980166 8.3964342 19.699414 8.1875 19.65625) - (M 7.5625 21.125) - (c -0.9196331 -1.962382 -3.205955 1.390782 -4.0978229 2.41995 - -1.707808 2.289408 -2.72190385 5.078558 -2.9334271 7.9238 - 1.0237952 1.983695 5.5272247 2.76676 4.7145431 4.084262 - -0.7368064 1.151552 -0.8906555 2.601652 0.1135446 3.680893 - 2.7495495 2.364498 1.2541019 5.824595 2.5609489 6.229519 - 2.5755284 0.853846 2.7512924 -3.696022 4.1297234 -3.843434 - 0.745066 -1.051147 0.04765 -2.428466 1.056101 -3.411232) - (C 12.318556 36.222109 8.8169859 35.479018 8.6188979 33.8253 - 7.7181807 34.141675 7.0679715 33.334232 6.30372 33.30415 - 5.7220663 34.646967 3.9378253 34.122031 4.3012403 32.699798 - 3.024533 33.043038 4.3605584 31.222879 3.40625 31.28125 - 0.5 33 2.5 26.5 5.0295875 29.903027 - 5.5 30.5 6.9002733 26.371666 8.8261905 25.876953 - 9.8027554 25.533149 9.5159021 24.727855 8.5279357 25.0625 - 7.6214946 24.941384 9.6975411 24.462771 10.075856 24.483273 - 11.540792 24.233047 9.904685 23.334106 9.8601011 22.602389 - 9.0900535 22.676405 9.4028275 22.737933 9.1185443 22.100147 - 6.8948741 22.58513 7.6831847 24.739145 5.9002404 23.244912 - 4.6247757 22.264239 7.321322 21.942832 7.5625 21.125) - (m 15.15625 -0.9375) - (c -1.37421 0.06218 -2.005432 1.159129 -2.784107 1.978327 - -0.114565 1.368674 0.952693 -0.07002 1.385771 0.968032 - 0.953881 -0.129572 -0.01507 -1.993413 1.425543 -2.008859 - -0.269351 0.525838 -0.494795 1.470731 0.411144 1.15174 - -0.646943 0.90275 -1.874871 2.045333 -2.613442 0.960703 - 0.08813 0.809648 -1.042388 0.509104 -1.186702 1.40851 - -0.738698 0.338761 -1.028513 0.375271 -0.383294 1.119927 - -1.340908 -0.226887 -1.979854 2.002883 -0.346874 1.903539 - 3.128783 -3.578714 2.7333 -0.07275 3.379252 -0.61531 - -0.408321 -3.069544 0.823059 1.69915 1.30948 -0.328623 - 0.476726 0.916648 1.583858 0.757279 2.129612 1.386838 - -2.140558 2.214946 -4.171988 -1.055384 -6.363065 -0.232922 - -2.486751 0.823935 -2.418258 3.347586 -3.103635 4.864439 - 0.687061 3.597921 3.669743 1.43585 5.132502 2.724104 - -0.344691 1.08929 0.484513 1.884668 0.473244 3.022942 - -0.01352 2.068761 0.378264 6.65826 1.845318 5.542497 - 1.472489 0.175399 1.430793 -1.740909 2.30904 -2.30502 - -1.36358 -1.181833 2.025569 -1.358588 0.887958 -2.838158 - -0.499809 -1.988948 1.367195 -3.177085 1.789594 -4.928946 - 0.579613 -0.960476 -1.588234 -0.05789 -0.373062 -1.023304 - 0.927113 -0.301781 2.379761 -2.07879 0.994298 -2.428506 - -0.676988 0.933612 -1.737597 -2.080985 -0.549773 -0.651497 - 0.699549 -0.419557 1.900516 1.563553 1.759683 -0.08984 - -0.608903 -3.386912 -2.4601 -6.520148 -5.090986 -8.736865 - -0.200722 0.802307 -1.230158 0.889683 -1.228926 0.0694 - 2.155263 -0.50116 -0.789058 -0.572123 -1.208573 -0.913148) - (M 17.09375 21) - (c -1.221276 0.05745 -0.44882 1.331427 0.232503 0.449916) - (C 17.458514 21.23484 17.234278 21.104353 17.09375 21) - (m -7.5 0.125) - (c -1.2040413 0.60218 1.459244 1.052142 0.289004 0.112253) - (m 8.96875 1.5) - (c 0.38412 0.655402 -0.236077 2.74213 1.030518 1.55154 - 0.0634 -0.524592 -0.59842 -1.401743 -1.030518 -1.55154) - (m -0.21875 0.75) - (c -1.155615 0.198578 0.509999 1.388302 0.06733 0.201634) - (M 10.5 24.53125) - (c -0.117519 1.313533 1.058399 0.642504 0 0))) - -(define water-logo-material - (deep-flomap-material-value - 'cubic-zirconia 1.0 0.7 1.0 - 0.25 0.15 1.0 - 0.15 0.1 0.2 - 0.0)) - -(define logo-under-continents-color "black") -(define logo-continents-color "azure") -(define logo-water-color "lightskyblue") -(define logo-earth-outline-color logo-red-color) - -(define (continents-flomap color height) - (define scale (/ height 32)) - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen lambda-outline-color 3/8 'solid) - (send dc set-brush color 'solid) - (draw-path-commands dc 0 -17 continents-path-commands)) - scale)) - -(defproc (planet-flomap [height (and/c rational? (>=/c 0)) 256]) flomap? - (make-cached-flomap - [height] - (define scale (/ height 32)) - (define-values (earth-fm earth-z) - (let* ([indent-fm (continents-flomap logo-red-color height)] - [indent-dfm (flomap->deep-flomap indent-fm)] - [indent-dfm (deep-flomap-raise indent-dfm (* -1/8 scale))] - [indent-dfm (deep-flomap-smooth-z indent-dfm (* 1 scale))] - [earth-fm (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen logo-water-color 1/2 'solid) - (send dc set-brush logo-water-color 'solid) - (draw-ellipse/smoothed dc 0.75 0.75 30.5 30.5)) - scale)] - [earth-dfm (flomap->deep-flomap earth-fm)] - [earth-dfm (deep-flomap-bulge-spheroid earth-dfm (* 16 scale))] - [earth-dfm (deep-flomap-cc-superimpose 'add earth-dfm indent-dfm)]) - (values (deep-flomap-render-icon earth-dfm water-logo-material) - (deep-flomap-z earth-dfm)))) - - (define land-fm - (let* ([land-fm (continents-flomap logo-continents-color height)] - [land-dfm (flomap->deep-flomap land-fm)] - ;[land-dfm (deep-flomap-emboss land-dfm (* 2 scale) (* 8 scale))] - [land-dfm (deep-flomap-bulge-spheroid land-dfm (* 16 scale))] - [land-dfm (deep-flomap-smooth-z land-dfm (* 1/2 scale))]) - (deep-flomap-render-icon land-dfm metal-material))) - - (flomap-cc-superimpose - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen "lightblue" 1/2 'solid) - (send dc set-brush "white" 'transparent) - (send dc draw-ellipse 0.5 0.5 31 31) - (send dc set-pen lambda-outline-color 1/2 'solid) - (send dc draw-ellipse -0.25 -0.25 32.5 32.5)) - scale) - earth-fm - land-fm))) - -(define plt-logo (compose flomap->bitmap plt-flomap)) -(define planet-logo (compose flomap->bitmap planet-flomap)) diff --git a/collects/images/scribblings/compile-time.scrbl b/collects/images/scribblings/compile-time.scrbl index 677b1da753..cc3c4dabb9 100644 --- a/collects/images/scribblings/compile-time.scrbl +++ b/collects/images/scribblings/compile-time.scrbl @@ -9,3 +9,5 @@ @title{Embedding Bitmaps in Compiled Files} @author{@(author+email "Neil Toronto" (author-email))} + +@defmodule[images/compile-time] diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl index 383c8ee5b3..d102816c5f 100644 --- a/collects/images/scribblings/icons.scrbl +++ b/collects/images/scribblings/icons.scrbl @@ -31,6 +31,8 @@ @(define icons-eval (make-base-eval)) @interaction-eval[#:eval icons-eval (require racket/class racket/draw racket/math racket/list)] +@;==================================================================================================== + @section{What is an icon?} @margin-note*{This section describes an ideal that DrRacket and its tools are steadily approaching.} @@ -58,6 +60,8 @@ especially for new users and people with certain forms of color-blindness, and t As another example, the Check Syntax icon @(check-syntax-icon 16) connotes inspecting and passing. Note that the check mark is also the color of syntax. +@;==================================================================================================== + @section{About These Icons} The icons in this collection are designed to be composed to create new ones: they are simple, thematically consistent, and can be constructed in any size and color. @@ -80,6 +84,11 @@ See the @racket[plt-logo] and @racket[planet-logo] functions for more striking e When the rendering API is stable enough to publish, it will allow anyone who can draw a shape to turn that shape into a visually consistent icon. +As with any sort of rendering (such as @link["http://en.wikipedia.org/wiki/Scalable_Vector_Graphics"]{SVG} rendering), ray tracing takes time. +For icons, this usually happens during tool or application start up. +You can reduce the portion of start-up time taken by rendering to almost nothing by using the @racketmodname[images/compile-time] library to embed bitmaps directly into compiled modules. + +@;==================================================================================================== @section{Icon Style} @@ -139,7 +148,8 @@ It has the high refractive index of @link["http://en.wikipedia.org/wiki/Cubic_zi The ``glassy look'' cannot actually be achieved using glass. Metal reflects the most, its @link["http://en.wikipedia.org/wiki/Specular_highlight"]{specular highlight} is nearly the same color as the material (in the others, the highlight is white), -and it diffuses much more ambient light than directional. This is because, while plastic and glass mostly reflect light directly, metal mostly absorbs light and re-emits it. +and it diffuses much more ambient light than directional. +This is because, while plastic and glass mostly reflect light directly, metal mostly absorbs light and re-emits it. @examples[#:eval icons-eval (require images/icons/misc) @@ -154,6 +164,8 @@ The material used for rendering most icons and icon parts. There are exceptions; for example, the @racket[floppy-disk-icon] always renders the sliding cover in metal. } +@;==================================================================================================== + @section[#:tag "arrows"]{Arrow Icons} @defmodule[images/icons/arrow] @@ -163,6 +175,7 @@ There are exceptions; for example, the @racket[floppy-disk-icon] always renders @doc-apply[left-arrow-icon] @doc-apply[up-arrow-icon] @doc-apply[down-arrow-icon]{ +Standard directional arrows. @examples[#:eval icons-eval (list (right-arrow-icon syntax-icon-color (toolbar-icon-height)) (left-arrow-icon run-icon-color) @@ -174,6 +187,7 @@ There are exceptions; for example, the @racket[floppy-disk-icon] always renders @doc-apply[left-over-arrow-icon] @doc-apply[right-under-arrow-icon] @doc-apply[left-under-arrow-icon]{ +Standard bent arrows. @examples[#:eval icons-eval (list (right-over-arrow-icon metal-icon-color (toolbar-icon-height)) (left-over-arrow-icon dark-metal-icon-color) @@ -181,43 +195,32 @@ There are exceptions; for example, the @racket[floppy-disk-icon] always renders (left-under-arrow-icon "lightgreen" 44 glass-icon-material))] } +@;==================================================================================================== + @section[#:tag "control"]{Control Icons} @defmodule[images/icons/control] @interaction-eval[#:eval icons-eval (require images/icons/control)] -@doc-apply[play-icon] -@doc-apply[back-icon] -@doc-apply[fast-forward-icon] -@doc-apply[rewind-icon] -@doc-apply[bar-icon] -@doc-apply[stop-icon] -@doc-apply[record-icon] -@doc-apply[pause-icon] -@doc-apply[step-icon] -@doc-apply[step-back-icon] -@doc-apply[continue-icon] -@doc-apply[continue-back-icon]{ -Typical ``playback control'' icons. -For example, a colorful tape deck: -@interaction[#:eval icons-eval - (for/list ([make-icon (list rewind-icon continue-back-icon - step-back-icon back-icon - pause-icon stop-icon - play-icon step-icon - continue-icon fast-forward-icon - record-icon)] - [color (list run-icon-color halt-icon-color - syntax-icon-color metal-icon-color - dark-metal-icon-color dark-metal-icon-color - metal-icon-color syntax-icon-color - halt-icon-color run-icon-color - "red")] - [material (in-cycle (list plastic-icon-material - glass-icon-material))]) - (make-icon color 32 material))] -The remaining icon @(bar-icon "red" 16), returned by @racket[bar-icon], is used to build the others. +@doc-apply[bar-icon]{ +@examples[#:eval icons-eval (bar-icon run-icon-color 32)] +This is not a ``control'' icon @italic{per se}, but is used to make many others. } +@doc-apply[play-icon]{ @examples[#:eval icons-eval (play-icon run-icon-color 32)] } +@doc-apply[back-icon]{ @examples[#:eval icons-eval (back-icon run-icon-color 32)] } +@doc-apply[fast-forward-icon]{ @examples[#:eval icons-eval (fast-forward-icon syntax-icon-color 32)] } +@doc-apply[rewind-icon]{ @examples[#:eval icons-eval (rewind-icon syntax-icon-color 32)] } +@doc-apply[stop-icon]{ @examples[#:eval icons-eval (stop-icon halt-icon-color 32)] } +@doc-apply[record-icon]{ @examples[#:eval icons-eval (record-icon "red" 32)] } +@doc-apply[pause-icon]{ @examples[#:eval icons-eval (pause-icon halt-icon-color 32)] } +@doc-apply[step-icon]{ @examples[#:eval icons-eval (step-icon run-icon-color 32)] } +@doc-apply[step-back-icon]{ @examples[#:eval icons-eval (step-back-icon run-icon-color 32)] } +@doc-apply[continue-forward-icon]{ @examples[#:eval icons-eval (continue-forward-icon run-icon-color 32)] } +@doc-apply[continue-backward-icon]{ @examples[#:eval icons-eval (continue-backward-icon run-icon-color 32)] } +@doc-apply[search-forward-icon]{ @examples[#:eval icons-eval (search-forward-icon syntax-icon-color 32)] } +@doc-apply[search-backward-icon]{ @examples[#:eval icons-eval (search-backward-icon syntax-icon-color 32)] } + +@;==================================================================================================== @section[#:tag "file"]{File Icons} @@ -240,6 +243,8 @@ The remaining icon @(bar-icon "red" 16), returned by @racket[bar-icon], is used (make-icon syntax-icon-color color 32))] } +@;==================================================================================================== + @section[#:tag "misc"]{Miscellaneous Icons} @defmodule[images/icons/misc] @@ -316,6 +321,16 @@ Equivalent to @racket[(regular-polygon-icon 8 (/ (* 2 pi) 16) color height mater (stop-signs-icon halt-icon-color 32 plastic-icon-material)] } +@doc-apply[foot-icon]{ +@examples[#:eval icons-eval + (foot-icon "chocolate" 32 glass-icon-material)] +} + +@doc-apply[lambda-icon]{ +@examples[#:eval icons-eval + (lambda-icon light-metal-icon-color 32 metal-icon-material)] +} + @doc-apply[magnifying-glass-icon]{ @examples[#:eval icons-eval (magnifying-glass-icon light-metal-icon-color "lightblue" 32 @@ -337,6 +352,8 @@ Equivalent to @racket[(regular-polygon-icon 8 (/ (* 2 pi) 16) color height mater (left-bomb-icon metal-icon-color dark-metal-icon-color 32)] } +@;==================================================================================================== + @section[#:tag "stickman"]{Stickman Icons} @defmodule[images/icons/stickman] @@ -368,6 +385,8 @@ The stickman's joint angles are defined by continuous periodic functions, so the The cycle is modeled after the run cycle of the player's avatar in the Commodore 64 game @link["http://en.wikipedia.org/wiki/Impossible_Mission"]{Impossible Mission}. } +@;==================================================================================================== + @section[#:tag "tool"]{Tool Icons} @defmodule[images/icons/tool] diff --git a/collects/images/scribblings/logos.scrbl b/collects/images/scribblings/logos.scrbl index d3917d2b60..8701378f93 100644 --- a/collects/images/scribblings/logos.scrbl +++ b/collects/images/scribblings/logos.scrbl @@ -18,19 +18,23 @@ @doc-apply[plt-logo]{ Returns the PLT logo, rendered in tinted glass and azure metal by the ray tracer that renders icons. - @examples[#:eval logos-eval (plt-logo)] - -A 256×256 (default height) rendering is compiled into the @racketmodname[images/logos] module using @racket[compiled-bitmap], meaning that constructing the logo at that size and smaller is cheap. -In fact, constructing the logo at the default height is essentially free because it does not need to be downscaled. +The default height is the size used for DrRacket splash screen. } @doc-apply[planet-logo]{ Returns an unofficial PLaneT logo. This is used as the PLaneT icon when DrRacket downloads PLaneT packages. - @examples[#:eval logos-eval (planet-logo) (planet-logo (default-icon-height))] - -As with the @racket[plt-logo], a default-height rendering is compiled into the @racketmodname[images/logos] module for performance reasons. +} + +@doc-apply[stepper-logo]{ +An algebraic stepper logo. +@examples[#:eval logos-eval (stepper-logo)] +} + +@doc-apply[macro-stepper-logo]{ +A macro stepper logo. +@examples[#:eval logos-eval (macro-stepper-logo)] } diff --git a/collects/images/scribblings/running-stickman.gif b/collects/images/scribblings/running-stickman.gif index 79d9de52eeb7bd22649aa140242dd220d2bc0c42..3c1b9b8f1d4d513ab4cbe5871b9375a325b6972d 100644 GIT binary patch literal 44789 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 diff --git a/collects/macro-debugger/info.rkt b/collects/macro-debugger/info.rkt index 707bf67915..8af28138a0 100644 --- a/collects/macro-debugger/info.rkt +++ b/collects/macro-debugger/info.rkt @@ -2,4 +2,5 @@ (define drracket-tools '(["tool.rkt"])) (define drracket-tool-names '("Macro Stepper")) +(define drracket-tool-icons (list '("macro-stepper-32x32.png" "icons"))) (define scribblings '(("macro-debugger.scrbl" () (tool-library)))) diff --git a/collects/macro-debugger/view/stepper.rkt b/collects/macro-debugger/view/stepper.rkt index f35c65c9f1..c9e156e2ee 100644 --- a/collects/macro-debugger/view/stepper.rkt +++ b/collects/macro-debugger/view/stepper.rkt @@ -15,10 +15,33 @@ "gui-util.rkt" "../syntax-browser/util.rkt" unstable/gui/notify + images/compile-time + images/gui + (for-syntax racket/base + images/icons/arrow images/icons/control images/logos + images/icons/style) (only-in mzscheme [#%top-interaction mz-top-interaction])) (provide macro-stepper-widget% macro-stepper-widget/process-mixin) +;; Compiled-in assets (button icons) + +(define navigate-up-icon + (compiled-bitmap (up-arrow-icon syntax-icon-color (toolbar-icon-height)))) +(define navigate-to-start-icon + (compiled-bitmap (search-backward-icon syntax-icon-color (toolbar-icon-height)))) +(define navigate-previous-icon + (compiled-bitmap (step-back-icon syntax-icon-color (toolbar-icon-height)))) +(define navigate-next-icon + (compiled-bitmap (step-icon syntax-icon-color (toolbar-icon-height)))) +(define navigate-to-end-icon + (compiled-bitmap (search-forward-icon syntax-icon-color (toolbar-icon-height)))) +(define navigate-down-icon + (compiled-bitmap (down-arrow-icon syntax-icon-color (toolbar-icon-height)))) + +(define small-logo (compiled-bitmap (macro-stepper-logo 32))) +(define large-logo (compiled-bitmap (macro-stepper-logo))) + ;; Macro Stepper ;; macro-stepper-widget% @@ -112,9 +135,14 @@ (new vertical-panel% (parent superarea) (enabled #f))) - (define supernavigator + (define top-panel (new horizontal-panel% (parent area) + (horiz-margin 5) + (stretchable-height #f))) + (define supernavigator + (new horizontal-panel% + (parent top-panel) (stretchable-height #f) (alignment '(center center)))) (define navigator @@ -130,7 +158,25 @@ (stretchable-height #f) (alignment '(left center)) (style '(deleted)))) - + + (define about-dialog + (new logo-about-dialog% + (label "About the Macro Stepper") + (parent frame) + (bitmap large-logo) + (messages '("The Macro Stepper is formalized and proved correct in\n" + "\n" + " Ryan Culpepper and Matthias Felleisen\n" + " Debugging Hygienic Macros\n" + " Science of Computer Programming, July 2010\n")))) + + (define logo-canvas + (new (class bitmap-canvas% + (super-new (parent top-panel) (bitmap small-logo)) + (define/override (on-event evt) + (when (eq? (send evt get-event-type) 'left-up) + (send about-dialog show #t)))))) + (define/i sbview sb:syntax-browser<%> (new stepper-syntax-widget% (parent area) @@ -179,22 +225,22 @@ (lambda (_) (update/preserve-view))) (define nav:up - (new button% (label "Previous term") (parent navigator) + (new button% (label (list navigate-up-icon "Previous term" 'left)) (parent navigator) (callback (lambda (b e) (navigate-up))))) (define nav:start - (new button% (label "<-- Start") (parent navigator) + (new button% (label (list navigate-to-start-icon "Start" 'left)) (parent navigator) (callback (lambda (b e) (navigate-to-start))))) (define nav:previous - (new button% (label "<- Step") (parent navigator) + (new button% (label (list navigate-previous-icon "Step" 'left)) (parent navigator) (callback (lambda (b e) (navigate-previous))))) (define nav:next - (new button% (label "Step ->") (parent navigator) + (new button% (label (list navigate-next-icon "Step" 'right)) (parent navigator) (callback (lambda (b e) (navigate-next))))) (define nav:end - (new button% (label "End -->") (parent navigator) + (new button% (label (list navigate-to-end-icon "End" 'right)) (parent navigator) (callback (lambda (b e) (navigate-to-end))))) (define nav:down - (new button% (label "Next term") (parent navigator) + (new button% (label (list navigate-down-icon "Next term" 'right)) (parent navigator) (callback (lambda (b e) (navigate-down))))) (define nav:text diff --git a/collects/stepper/drracket-button.rkt b/collects/stepper/drracket-button.rkt index 0cc450fe04..cd1866fb2d 100644 --- a/collects/stepper/drracket-button.rkt +++ b/collects/stepper/drracket-button.rkt @@ -7,5 +7,5 @@ (define stepper-drracket-button (list (string-constant stepper-button-label) - x:foot-img/horizontal + x:step-img (λ (drs-frame) (send drs-frame stepper-button-callback)))) diff --git a/collects/stepper/info.rkt b/collects/stepper/info.rkt index 81668d6d12..f56ebf5feb 100644 --- a/collects/stepper/info.rkt +++ b/collects/stepper/info.rkt @@ -4,6 +4,6 @@ (define drracket-tool-names (list "The Stepper")) -(define drracket-tool-icons (list '("foot-up.png" "icons"))) +(define drracket-tool-icons (list '("stepper-32x32.png" "icons"))) (define scribblings '(("scribblings/stepper.scrbl"))) diff --git a/collects/stepper/private/mred-extensions.rkt b/collects/stepper/private/mred-extensions.rkt index ddeb5e03c4..a547b840d5 100644 --- a/collects/stepper/private/mred-extensions.rkt +++ b/collects/stepper/private/mred-extensions.rkt @@ -5,11 +5,12 @@ (prefix-in f: framework) mzlib/pretty #;"testing-shared.rkt" - "shared.rkt") + "shared.rkt" + images/compile-time + (for-syntax images/icons/control images/icons/style)) (provide - foot-img/horizontal - foot-img/vertical + step-img stepper-canvas% stepper-text% snip? @@ -516,14 +517,8 @@ (strip-regular stx)) -;; the bitmap to use in a horizontal toolbar: -(define foot-img/horizontal (make-object bitmap% (build-path (collection-path - "icons") "foot.png") 'png/mask)) - -;; the bitmap to use in a vertical toolbar: -(define foot-img/vertical (make-object bitmap% (build-path (collection-path - "icons") "foot-up.png") 'png/mask)) - +;; the bitmap to use in a horizontal or vertical toolbar: +(define step-img (compiled-bitmap (step-icon run-icon-color (toolbar-icon-height)))) ;; testing code diff --git a/collects/stepper/private/view-controller.rkt b/collects/stepper/private/view-controller.rkt index 2a91ac4aff..8c258cccdc 100644 --- a/collects/stepper/private/view-controller.rkt +++ b/collects/stepper/private/view-controller.rkt @@ -14,7 +14,10 @@ (prefix-in x: "mred-extensions.rkt") "shared.rkt" "model-settings.rkt" - "xml-sig.rkt") + "xml-sig.rkt" + images/compile-time + images/gui + (for-syntax racket/base images/icons/control images/icons/style images/logos)) (import drracket:tool^ xml^ stepper-frame^) @@ -214,20 +217,50 @@ ;; GUI ELEMENTS: (define s-frame (make-object stepper-frame% drracket-tab)) + + (define top-panel + (new horizontal-panel% [parent (send s-frame get-area-container)] [horiz-margin 5] + ;[style '(border)] ; for layout testing only + [stretchable-width #t] + [stretchable-height #f])) + (define button-panel - (make-object horizontal-panel% (send s-frame get-area-container))) - (define (add-button name fun) - (new button% - [label name] - [parent button-panel] - [callback (lambda (_1 _2) (fun))] - [enabled #f])) - (define (add-choice-box name fun) - (new choice% [label name] - [choices (map first pulldown-choices)] - [parent button-panel] - [callback fun] - [enabled #f])) + (new horizontal-panel% [parent top-panel] [alignment '(center top)] + ;[style '(border)] ; for layout testing only + [stretchable-width #t] + [stretchable-height #f])) + + (define about-dialog + (new logo-about-dialog% + [label "About the Stepper"] + [parent s-frame] + [bitmap (compiled-bitmap (stepper-logo))] + [messages '("The Algebraic Stepper is formalized and proved correct in\n" + "\n" + " John Clements, Matthew Flatt, Matthias Felleisen\n" + " Modeling an Algebraic Stepper\n" + " European Symposium on Programming, 2001\n")])) + + (define logo-canvas + (new (class bitmap-canvas% + (super-new [parent top-panel] [bitmap (compiled-bitmap (stepper-logo 32))]) + (define/override (on-event evt) + (when (eq? (send evt get-event-type) 'left-up) + (send about-dialog show #t)))))) + + (define prev-img (compiled-bitmap (step-back-icon run-icon-color (toolbar-icon-height)))) + (define previous-button (new button% + [label (list prev-img (string-constant stepper-previous) 'left)] + [parent button-panel] + [callback (λ (_1 _2) (previous))] + [enabled #f])) + + (define next-img (compiled-bitmap (step-icon run-icon-color (toolbar-icon-height)))) + (define next-button (new button% + [label (list next-img (string-constant stepper-next) 'right)] + [parent button-panel] + [callback (λ (_1 _2) (next))] + [enabled #f])) (define pulldown-choices `((,(string-constant stepper-jump-to-beginning) ,jump-to-beginning) @@ -236,10 +269,12 @@ (,(string-constant stepper-jump-to-next-application) ,jump-to-next-application) (,(string-constant stepper-jump-to-previous-application) ,jump-to-prior-application))) - (define previous-button (add-button (string-constant stepper-previous) previous)) - (define next-button (add-button (string-constant stepper-next) next)) - (define jump-button (add-choice-box (string-constant stepper-jump) jump-to)) - + (define jump-button (new choice% + [label (string-constant stepper-jump)] + [choices (map first pulldown-choices)] + [parent button-panel] + [callback jump-to] + [enabled #f])) (define canvas (make-object x:stepper-canvas% (send s-frame get-area-container))) @@ -252,6 +287,7 @@ (new editor-canvas% [parent button-panel] [editor status-text] + [stretchable-width #f] [style '(transparent no-border no-hscroll no-vscroll)] ;; some way to get the height of a line of text? [min-width 100])) @@ -332,8 +368,6 @@ ;; CONFIGURE GUI ELEMENTS (send s-frame set-printing-proc print-current-view) - (send button-panel stretchable-width #f) - (send button-panel stretchable-height #f) (send canvas stretchable-height #t) (send (send s-frame edit-menu:get-undo-item) enable #f) (send (send s-frame edit-menu:get-redo-item) enable #f) diff --git a/collects/stepper/stepper-tool.rkt b/collects/stepper/stepper-tool.rkt index 369bb6294d..85c0b3bcb8 100644 --- a/collects/stepper/stepper-tool.rkt +++ b/collects/stepper/stepper-tool.rkt @@ -182,8 +182,7 @@ (new switchable-button% [parent stepper-button-parent-panel] [label (string-constant stepper-button-label)] - [bitmap x:foot-img/horizontal] - [alternate-bitmap x:foot-img/vertical] + [bitmap x:step-img] [callback (lambda (dont-care) (send (get-current-tab) stepper-button-callback))])) diff --git a/collects/string-constants/private/danish-string-constants.rkt b/collects/string-constants/private/danish-string-constants.rkt index 342eb03c7d..e9db75e5a3 100644 --- a/collects/string-constants/private/danish-string-constants.rkt +++ b/collects/string-constants/private/danish-string-constants.rkt @@ -1125,10 +1125,10 @@ please adhere to these guidelines: (stepper-language-level-message "Sprogniveauet er sat til \"~a\". Indtil videre virker stepperen kun for sprogniveauerne fra \"~a\" til \"~a\".") (stepper-button-label "Step") - (stepper-previous-application "|< Funktionskald") - (stepper-previous "< Step") - (stepper-next "Step >") - (stepper-next-application "Funktionskald >|") + (stepper-previous-application "Funktionskald") + (stepper-previous "Step") + (stepper-next "Step") + (stepper-next-application "Funktionskald") (stepper-jump-to-beginning "Hjem") (debug-tool-button-name "Debug") diff --git a/collects/string-constants/private/english-string-constants.rkt b/collects/string-constants/private/english-string-constants.rkt index e908cd8d94..50d7194fd5 100644 --- a/collects/string-constants/private/english-string-constants.rkt +++ b/collects/string-constants/private/english-string-constants.rkt @@ -1348,8 +1348,8 @@ please adhere to these guidelines: (stepper-language-level-message "The stepper does not work for language \"~a\".") (stepper-button-label "Step") - (stepper-previous "< Step") - (stepper-next "Step >") + (stepper-previous "Step") + (stepper-next "Step") (stepper-jump "Jump...") (stepper-jump-to-beginning "to beginning") (stepper-jump-to-end "to end") diff --git a/collects/string-constants/private/french-string-constants.rkt b/collects/string-constants/private/french-string-constants.rkt index e9a5f745d1..0f9508de1b 100644 --- a/collects/string-constants/private/french-string-constants.rkt +++ b/collects/string-constants/private/french-string-constants.rkt @@ -1348,8 +1348,8 @@ (stepper-language-level-message "Le Pas à Pas n'est pas disponible pour le langage \"~a\".") (stepper-button-label "Pas") - (stepper-previous "< Pas") - (stepper-next "Pas >") + (stepper-previous "Pas") + (stepper-next "Pas") (stepper-jump "Sauter...") (stepper-jump-to-beginning "au début") (stepper-jump-to-end "à la fin") diff --git a/collects/string-constants/private/german-string-constants.rkt b/collects/string-constants/private/german-string-constants.rkt index ba9718e301..2a78808fae 100644 --- a/collects/string-constants/private/german-string-constants.rkt +++ b/collects/string-constants/private/german-string-constants.rkt @@ -1250,8 +1250,8 @@ "Der Stepper unterstützt die Sprachebene \"~a\" nicht.") (stepper-button-label "Stepper") - (stepper-previous "< Schritt") - (stepper-next "Schritt >") + (stepper-previous "Schritt") + (stepper-next "Schritt") (stepper-jump "Springen...") (stepper-jump-to-beginning "an den Anfang") (stepper-jump-to-end "ans Ende") diff --git a/collects/string-constants/private/japanese-string-constants.rkt b/collects/string-constants/private/japanese-string-constants.rkt index 8712add4f4..881b3e5786 100644 --- a/collects/string-constants/private/japanese-string-constants.rkt +++ b/collects/string-constants/private/japanese-string-constants.rkt @@ -1240,10 +1240,10 @@ please adhere to these guidelines: (stepper-name "ステッパ") (stepper-language-level-message "ステッパは \"~a\" 言語に対しては動作しません") (stepper-button-label "ステップ") - (stepper-previous-application "|< アプリケーション") - (stepper-previous "< ステップ") - (stepper-next "ステップ >") - (stepper-next-application "アプリケーション >|") + (stepper-previous-application "アプリケーション") + (stepper-previous "ステップ") + (stepper-next "ステップ") + (stepper-next-application "アプリケーション") (stepper-jump-to-beginning "ホーム") (stepper-jump-to-end "終端まで") diff --git a/collects/string-constants/private/korean-string-constants.rkt b/collects/string-constants/private/korean-string-constants.rkt index ba06c65c25..4b58fda0ac 100644 --- a/collects/string-constants/private/korean-string-constants.rkt +++ b/collects/string-constants/private/korean-string-constants.rkt @@ -1187,8 +1187,8 @@ (stepper-language-level-message "한 단계씩 실행은 \"~a\" 언어에서 지원하지 않습니다.") (stepper-button-label "한 단계씩 실행") - (stepper-previous "< 이전단계") - (stepper-next "다음단계 >") + (stepper-previous "이전단계") + (stepper-next "다음단계") (stepper-jump "건너뛰기...") (stepper-jump-to-beginning "처음으로") (stepper-jump-to-end "끝으로") diff --git a/collects/string-constants/private/portuguese-string-constants.rkt b/collects/string-constants/private/portuguese-string-constants.rkt index e6a6a46826..ee5f1bb4f6 100644 --- a/collects/string-constants/private/portuguese-string-constants.rkt +++ b/collects/string-constants/private/portuguese-string-constants.rkt @@ -1064,11 +1064,11 @@ please adhere to these guidelines: (stepper-language-level-message "The language level is set to \"~a\". Currently, the stepper works only for the \"~a\" through the \"~a\" language levels.") (stepper-button-label "Step") - (stepper-previous-application "|< Application") - (stepper-previous "< Step") - (stepper-next "Step >") + (stepper-previous-application "Application") + (stepper-previous "Step") + (stepper-next "Step") (stepper-jump-to-beginning "Home") - (stepper-next-application "Application >|") + (stepper-next-application "Application") (dialog-back "Back") diff --git a/collects/string-constants/private/russian-string-constants.rkt b/collects/string-constants/private/russian-string-constants.rkt index 5301f5cbe8..7a815c1aa2 100644 --- a/collects/string-constants/private/russian-string-constants.rkt +++ b/collects/string-constants/private/russian-string-constants.rkt @@ -1252,10 +1252,10 @@ please adhere to these guidelines: (stepper-language-level-message "Пошаговое выполнение не работает для языка \"~a\".") (stepper-button-label "Шаг") - (stepper-previous-application "|< Программа") - (stepper-previous "< Шаг") - (stepper-next "Шаг >") - (stepper-next-application "Программа >|") + (stepper-previous-application "Программа") + (stepper-previous "Шаг") + (stepper-next "Шаг") + (stepper-next-application "Программа") (stepper-jump "Перейти...") ;; this one is changed. action? (stepper-out-of-steps "Вычисления завершены ранее, чем достигнут искомый шаг.") (stepper-no-such-step/title "Шаг не найден") diff --git a/collects/string-constants/private/simplified-chinese-string-constants.rkt b/collects/string-constants/private/simplified-chinese-string-constants.rkt index f81b9244ce..1777adae93 100644 --- a/collects/string-constants/private/simplified-chinese-string-constants.rkt +++ b/collects/string-constants/private/simplified-chinese-string-constants.rkt @@ -1145,10 +1145,10 @@ (stepper-name "单步执行器") (stepper-language-level-message "单步执行不支持语言“~a”。") (stepper-button-label "单步执行") - (stepper-previous-application "|< 调用") - (stepper-previous "< 上一步") - (stepper-next "下一步 >") - (stepper-next-application "调用 >|") + (stepper-previous-application "调用") + (stepper-previous "上一步") + (stepper-next "下一步") + (stepper-next-application "调用") (stepper-jump-to-beginning "源程序") (stepper-jump-to-end "最终运行结果") diff --git a/collects/string-constants/private/spanish-string-constants.rkt b/collects/string-constants/private/spanish-string-constants.rkt index 088117114f..5d7c953035 100644 --- a/collects/string-constants/private/spanish-string-constants.rkt +++ b/collects/string-constants/private/spanish-string-constants.rkt @@ -975,8 +975,10 @@ (stepper-language-level-message "El nivel del lenguaje es \"~a\". Actualmente el Stepper funciona para los niveles \"~a\" al \"~a\".") (stepper-button-label "Paso") - (stepper-previous-application "|< Aplicación") - (stepper-previous "< Paso") + (stepper-previous-application "Aplicación") + (stepper-previous "Paso") + (stepper-next "Paso") + (stepper-next-application "Aplicación") (stepper-jump-to-beginning "Hogar") (dialog-back "Atrás") diff --git a/collects/string-constants/private/traditional-chinese-string-constants.rkt b/collects/string-constants/private/traditional-chinese-string-constants.rkt index ebb4b2db12..a3f20d3a65 100644 --- a/collects/string-constants/private/traditional-chinese-string-constants.rkt +++ b/collects/string-constants/private/traditional-chinese-string-constants.rkt @@ -1142,10 +1142,10 @@ (stepper-name "单步执行器") (stepper-language-level-message "单步执行不支持语言“~a”。") (stepper-button-label "单步执行") - (stepper-previous-application "|< 调用") - (stepper-previous "< 上一步") - (stepper-next "下一步 >") - (stepper-next-application "调用 >|") + (stepper-previous-application "调用") + (stepper-previous "上一步") + (stepper-next "下一步") + (stepper-next-application "调用") (stepper-jump-to-beginning "源程序") (stepper-jump-to-end "最终运行结果") diff --git a/collects/string-constants/private/ukrainian-string-constants.rkt b/collects/string-constants/private/ukrainian-string-constants.rkt index 2bd2247caf..3df2ce191f 100644 --- a/collects/string-constants/private/ukrainian-string-constants.rkt +++ b/collects/string-constants/private/ukrainian-string-constants.rkt @@ -1252,10 +1252,10 @@ please adhere to these guidelines: (stepper-language-level-message "Покрокове виконання не працює для мови \"~a\".") (stepper-button-label "Крок") - (stepper-previous-application "|< Програма") - (stepper-previous "< Крок") - (stepper-next "Крок >") - (stepper-next-application "Програма >|") + (stepper-previous-application "Програма") + (stepper-previous "Крок") + (stepper-next "Крок") + (stepper-next-application "Програма") (stepper-jump "Перейти...") ;; this one is changed. action? (stepper-out-of-steps "Обчислення завершено раніше, ніж досягнуто шуканий крок.") (stepper-no-such-step/title "Крок не знайдено") From 417d79ea347338e2f1fc56a3ae02f37a49615bc0 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Sun, 15 Jan 2012 22:19:17 -0700 Subject: [PATCH 486/746] Removed the animated GIF of the running stickman :( Please merge into release (cherry picked from commit f66aab8057e7a31f0bb09537311b366cc6257733) --- collects/images/scribblings/icons.scrbl | 10 +--------- .../images/scribblings/running-stickman.gif | Bin 44789 -> 0 bytes 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 collects/images/scribblings/running-stickman.gif diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl index d102816c5f..0f583bd632 100644 --- a/collects/images/scribblings/icons.scrbl +++ b/collects/images/scribblings/icons.scrbl @@ -368,18 +368,10 @@ Returns the icon displayed in DrRacket's lower-right corner when no program is r Returns a frame of the icon animated in DrRacket's lower-right corner when a program is running. The frame returned is for time @racket[t] of a run cycle with a one-second period. -It is difficult to put a code example in the API documentation that produces an animation. -However, we might use code similar to the following to sample from the run cycle: +The following example samples the run cycle at 12 Hz, or every @racket[1/12] second: @interaction[#:eval icons-eval (for/list ([t (in-range 0 1 1/12)]) (running-stickman-icon t run-icon-color "white" run-icon-color 32))] -If instead of putting the icons in a list, we call their @racket[save-file] methods and hand-assemble the files into a GIF, we get something like this: - -@centered[@image["scribblings/running-stickman.gif"]] - -Here, the run cycle is sampled and played back at 30 Hz. -The previous example samples the run cycle at 12 Hz, or every @racket[1/12] second. -DrRacket samples it at 12 Hz and plays it back at 5 Hz at the most. The stickman's joint angles are defined by continuous periodic functions, so the run cycle can be sampled at any resolution, or at any real-valued time @racket[t]. The cycle is modeled after the run cycle of the player's avatar in the Commodore 64 game @link["http://en.wikipedia.org/wiki/Impossible_Mission"]{Impossible Mission}. diff --git a/collects/images/scribblings/running-stickman.gif b/collects/images/scribblings/running-stickman.gif deleted file mode 100644 index 3c1b9b8f1d4d513ab4cbe5871b9375a325b6972d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44789 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 Date: Mon, 16 Jan 2012 01:52:36 -0500 Subject: [PATCH 487/746] Debian squeeze is back, and a typo. (The lenny build will not be back.) (cherry picked from commit 252221246d0c04123e48e2f272e2a671ff3073ed) --- collects/meta/build/build | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index a14d589b84..bde6d16d0a 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -103,7 +103,7 @@ defbuild "ccs-linux" "i386-linux-ubuntu-karmic" "moveto=/proj/racket" defbuild "osx64" "x86_64-osx-mac" # These builds are courtesy of Mason Loring Bliss # defbuild "blisses1" "x86_64-linux-debian-lenny" -# defbuild "blisses2" "x86_64-linux-debian-squeeze" +defbuild "blisses2" "x86_64-linux-debian-squeeze" # Start the main build last defbuild "$workmachine" "x86_64-linux-f14" "copytobak=$maindir" "test_gui=yes" msets "/" @@ -1484,7 +1484,7 @@ DO_WINDOWS_BUILD() { _cd "$PLTHOME"; win_build_step RKT "raco setup" $SETUP_ARGS - header -s "Windows: Building Cygwin libreries" + header -s "Windows: Building Cygwin libraries" _mcd "$PLTHOME/src/build" _run ../configure --disable-gracket _cd "racket/dynsrc" @@ -1493,7 +1493,7 @@ DO_WINDOWS_BUILD() { || exit_error "Errors when running \"make\" for Cygwin" # Borland is no longer supported: - # header -s "Windows: Building Borland libreries" + # header -s "Windows: Building Borland libraries" # _cd "$PLTHOME/src/racket/dynsrc" # _run bcc32 -I"../include" -I"g:/borland/bcc55/include" \ # -o"mzdynb.obj" -c "mzdyn.c" From 26e741940c39a0c26f31e27e1bbd486792e8c7c6 Mon Sep 17 00:00:00 2001 From: daniel watson Date: Thu, 29 Dec 2011 00:17:58 -0500 Subject: [PATCH 488/746] Guide proofread * fix content of REPL output in quote example * fix indentation on tail-recursive my-map code (cherry picked from commit 75d5b42640c8e9192dc96c11048c7517f512b911) --- collects/scribblings/guide/lists.scrbl | 2 +- collects/scribblings/guide/truth.scrbl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/scribblings/guide/lists.scrbl b/collects/scribblings/guide/lists.scrbl index c4ff2e5c0c..c7bb8f1bac 100644 --- a/collects/scribblings/guide/lists.scrbl +++ b/collects/scribblings/guide/lists.scrbl @@ -271,7 +271,7 @@ usually not worthwhile, as discussed below.} [(empty? lst) (reverse backward-result)] [else (iter (rest lst) (cons (f (first lst)) - backward-result))])) + backward-result))])) (iter lst empty)) ] diff --git a/collects/scribblings/guide/truth.scrbl b/collects/scribblings/guide/truth.scrbl index 178aac4acf..753e560e35 100644 --- a/collects/scribblings/guide/truth.scrbl +++ b/collects/scribblings/guide/truth.scrbl @@ -86,7 +86,7 @@ prints: @interaction[ (eval:alts (@#,racket[quote] ("red" "green" "blue")) '("red" "green" "blue")) -(eval:alts (@#,racket[quote] ((1) (2 3) (4))) '((1) (2 4) (4))) +(eval:alts (@#,racket[quote] ((1) (2 3) (4))) '((1) (2 3) (4))) (eval:alts (@#,racket[quote] ()) '()) ] From 3e8fd8f836ea373722f8f0586413815b6da742e9 Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Wed, 11 Jan 2012 12:23:37 -0500 Subject: [PATCH 489/746] correction for performance.scrbl (cherry picked from commit a1da6af22d40053b0498a35a6d76614304b6cc35) --- collects/scribblings/guide/performance.scrbl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/scribblings/guide/performance.scrbl b/collects/scribblings/guide/performance.scrbl index 964035d4da..26e469a932 100644 --- a/collects/scribblings/guide/performance.scrbl +++ b/collects/scribblings/guide/performance.scrbl @@ -80,10 +80,10 @@ information when compiling procedures, since the code for a given module body or @racket[lambda] abstraction is compiled only once. The @tech{JIT}'s granularity of compilation is a single procedure body, not counting the bodies of any lexically nested procedures. The -overhead for @tech{JIT}"wwxre xzr[ixzzrizzRQefewr[] compilation is normally so small that it is -difficult to detect." +overhead for @tech{JIT} compilation is normally so small that it is +difficult to detect. -@; ---------------------------------------------------------------;[]\'------- +@; ---------------------------------------------------------------------- @section[#:tag "modules-performance"]{Modules and Performance} From 53fea59312e88662628aaac929d7754b7b7ebb60 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 16 Jan 2012 08:17:56 -0500 Subject: [PATCH 490/746] XREPL fixes * Avoid using readline on windows (segfaults, and anyway mostly not useful) * Don't try to read init file if it doesn't exist. * Improve asking questions in the `install!' command. (cherry picked from commit 7fa08391a0d93d4d167e641bfcc41540b44932c9) --- collects/xrepl/xrepl.rkt | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index 47aae02321..c33ba9cd38 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -1161,7 +1161,7 @@ (define comment "The following line loads `xrepl' support") (define expr "(require xrepl)") (define dexpr "(dynamic-require 'xrepl #f)") - (define contents (file->string init-file)) + (define contents (if (file-exists? init-file) (file->string init-file) "")) (read-line) ; discard the newline for further input (define (look-for comment-rx expr) (let ([m (regexp-match-positions @@ -1172,7 +1172,18 @@ (define existing? (look-for (regexp-quote comment) expr)) (define existing-readline? (look-for "load readline support[^\r\n]*" "(require readline/rep)")) - (define (yes?) (flush-output) (regexp-match? #rx"^[yY]" (getarg 'line))) + (define (yes? question) + (define qtext (format "; ~a? " question)) + (define inp + (case (object-name (current-input-port)) + [(readline-input) + (parameterize ([(dynamic-require + (collection-file-path "pread.rkt" "readline") + 'current-prompt) + qtext]) + (read-line))] + [else (display qtext) (flush-output) (read-line)])) + (and (string? inp) (regexp-match? #px"^[[:space:]]*[yY]" inp))) (cond [existing? (printf "; already installed, nothing to do\n") @@ -1183,13 +1194,11 @@ contents)]) (and m (begin (printf "; found \"~a\", ~a\n" (car m) "looks like xrepl is already installed") - (printf "; should I continue anyway? ") - (not (yes?)))))] + (not (yes? "should I continue anyway")))))] [else (when existing-readline? (printf "; found a `readline' loading line\n") - (printf "; xrepl will already do that, ok to remove? ") - (if (yes?) + (if (yes? "xrepl will already do that, ok to remove") (set! contents (string-append (substring contents 0 (car existing-readline?)) (substring contents (cdr existing-readline?)))) @@ -1198,8 +1207,7 @@ (printf "; writing new contents, with an added \"~a\"\n" expr) (printf "; (if you want to load it conditionally, edit the file and\n") (printf "; use \"~a\" instead, which is a plain expression)\n" dexpr) - (printf "; OK to continue? ") - (if (yes?) + (if (yes? "OK to continue") (begin (call-with-output-file* init-file #:exists 'truncate (λ (o) (write-string @@ -1350,6 +1358,7 @@ (case (object-name (current-input-port)) [(stdin) (if (or (not (terminal-port? (current-input-port))) + (eq? 'windows (system-type)) (regexp-match? #rx"^dumb" (or (getenv "TERM") "")) (not RL)) plain-reader From 1fc4085ec6a258df86aaede6c52a2018393714a7 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 16 Jan 2012 08:56:16 -0600 Subject: [PATCH 491/746] adjust two 2htdp test files so they don't run in drdr (they are interactive) please merge to the release branch (cherry picked from commit 5d946329caec236d54130413524cf99d89e8b12a) --- collects/meta/props | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collects/meta/props b/collects/meta/props index 65e3c7da96..734568d116 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -560,6 +560,7 @@ path/s is either such a string or a list of them. "collects/2htdp/tests/mouse-evt.rkt" drdr:command-line #f "collects/2htdp/tests/mp.rkt" drdr:command-line #f "collects/2htdp/tests/on-release-no-key.rkt" drdr:command-line (raco "make" *) +"collects/2htdp/tests/pad1.rkt" drdr:command-line (raco "make" *) "collects/2htdp/tests/perform-record.rkt" drdr:command-line (gracket "-qt" *) "collects/2htdp/tests/perform-robby.rkt" drdr:command-line (gracket *) "collects/2htdp/tests/perform-whack.rkt" drdr:command-line #f @@ -570,6 +571,7 @@ path/s is either such a string or a list of them. "collects/2htdp/tests/stop.rkt" drdr:command-line (gracket *) "collects/2htdp/tests/test-image.rkt" responsible (robby) drdr:command-line (gracket-text "-t" *) "collects/2htdp/tests/ufo-rename.rkt" drdr:command-line (gracket *) +"collects/2htdp/tests/universe-receive.rkt" drdr:command-line (raco "make" *) "collects/2htdp/tests/world0-stops.rkt" drdr:command-line (gracket-text "-t" *) "collects/2htdp/uchat/chatter.rkt" drdr:command-line (mzc "-k" *) "collects/2htdp/uchat/server.rkt" drdr:command-line (mzc "-k" *) From 1c924f02d1931d161689cba96fac9afb6e68f8d5 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 16 Jan 2012 09:09:58 -0600 Subject: [PATCH 492/746] clear the "what was the last language?" state when moving out of the module language so that things get initialized properly when moving back into the module language. closes PR 12493 (cherry picked from commit aaeb3db534ab08e308ca1917dd0f82e6643c4b8f) --- collects/drracket/private/module-language-tools.rkt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collects/drracket/private/module-language-tools.rkt b/collects/drracket/private/module-language-tools.rkt index c0751f00e8..58725a7e16 100644 --- a/collects/drracket/private/module-language-tools.rkt +++ b/collects/drracket/private/module-language-tools.rkt @@ -140,6 +140,8 @@ [in-module-language? (move-to-new-language)] [else + (set! hash-lang-language #f) + (set! hash-lang-last-location #f) (clear-things-out)]))) (define/public (move-to-new-language) From 58b75e2e7351f9fadddb2d0d0d0eb543b85117ad Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 16 Jan 2012 11:51:27 -0500 Subject: [PATCH 493/746] added pad-handler facility (cherry picked from commit f9233bce4718bcc9dbb48fe352cada0698000dc3) --- collects/2htdp/tests/pad1-handler.rkt | 26 ++++++++++++++ collects/2htdp/tests/pad1.rkt | 4 +-- collects/2htdp/universe.rkt | 49 +++++++++++++++++++-------- collects/2htdp/xtest | 1 + 4 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 collects/2htdp/tests/pad1-handler.rkt diff --git a/collects/2htdp/tests/pad1-handler.rkt b/collects/2htdp/tests/pad1-handler.rkt new file mode 100644 index 0000000000..bb860f0a2e --- /dev/null +++ b/collects/2htdp/tests/pad1-handler.rkt @@ -0,0 +1,26 @@ +#lang racket + +(require 2htdp/universe) + +;; ----------------------------------------------------------------------------- +;; test case + +(define (i-sub1 x) (- x 0+1i)) +(define (i-add1 x) (+ x 0+1i)) + +(define handler + (pad-handler (left sub1) (right add1) + (up i-sub1) (down i-add1) + (shift (lambda (w) 0)) + (space stop-with))) + +(define-syntax-rule + (tst (=-fun (handler _1 s) _2)) + (unless (=-fun (handler _1 s) _2) (error 'test "~a failed" s))) + +(tst (= (handler 9 "left") 8)) +(tst (= (handler 8 "right") 9)) +(tst (= (handler 8 "up") 8-i)) +(tst (= (handler 8 "down") 8+i)) +(tst (= (handler 7 "shift") 0)) +(tst (equal? (handler 6 "space") (stop-with 6))) \ No newline at end of file diff --git a/collects/2htdp/tests/pad1.rkt b/collects/2htdp/tests/pad1.rkt index d0e5944e84..5f39242c19 100644 --- a/collects/2htdp/tests/pad1.rkt +++ b/collects/2htdp/tests/pad1.rkt @@ -36,7 +36,7 @@ (define transform-x (transform center-x)) (define transform-y (transform center-y)) -(define (pad-handler x k) +(define (phandler x k) (case (string->symbol k) [(up w) (- x 0+10i)] [(down s) (+ x 0+10i)] @@ -53,7 +53,7 @@ (define-syntax-rule (run txt clause ...) (begin (set! label (string-append txt label)) - (big-bang x0 (to-draw render) (on-pad pad-handler) clause ... ))) + (big-bang x0 (to-draw render) (on-pad phandler) clause ... ))) (= -10-10i (run "")) (= -10-10i (run "press l, " (on-key (key-handler 'key)))) diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index 45c206ff5c..c0d99389ed 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -41,15 +41,6 @@ launch-many-worlds/proc ) -(provide - ;; KeyEvent -> Boolean - ;; is the given key-event also a pad-event? - pad-event? - ;; PadEvent PadEvent -> Boolean - ;; are the two pad-events equal? - pad=? - ) - (provide-primitive sexp? ;; Any -> Boolean ) @@ -171,18 +162,24 @@ ; ; -(provide big-bang ;; : see below - ) +(provide + big-bang ;; : see below + pad-handler ;; : see below + ) (provide-primitives - make-package ;; World Sexp -> Package - package? ;; Any -> Boolean - run-movie ;; [r Positive] [m [Listof Image]] -> true + make-package ;; World Sexp -> Package + package? ;; Any -> Boolean + run-movie ;; [r Positive] [m [Listof Image]] -> true ;; run movie m at rate r images per second mouse-event? ;; Any -> Boolean : MOUSE-EVTS mouse=? ;; MOUSE-EVTS MOUSE-EVTS -> Boolean key-event? ;; Any -> Boolean : KEY-EVTS key=? ;; KEY-EVTS KEY-EVTS -> Boolean + pad-event? ;; KeyEvent -> Boolean + ;; is the given key-event also a pad-event? + pad=? ;; PadEvent PadEvent -> Boolean + ;; --- ;; IP : a string that points to a machine on the net ) @@ -264,6 +261,30 @@ 'stepper-skip-completely #t) 'disappeared-use (map (lambda (x) (car (syntax->list x))) dom))]))])) +(define-keywords Pad1Specs '() _init-not-needed + [up DEFAULT #'(lambda (x) x) (function-with-arity 1)] + [down DEFAULT #'(lambda (x) x) (function-with-arity 1)] + [left DEFAULT #'(lambda (x) x) (function-with-arity 1)] + [right DEFAULT #'(lambda (x) x) (function-with-arity 1)] + [space DEFAULT #'(lambda (x) x) (function-with-arity 1)] + [shift DEFAULT #'(lambda (x) x) (function-with-arity 1)]) + +(define-syntax (pad-handler stx) + (syntax-case stx () + [(pad1 clause ...) + (let* ([args (->args 'pad-one-player stx #'w #'(clause ...) Pad1Specs void)] + [keys (map (lambda (x) + (syntax-case x () [(proc> (quote s) _f _d) (symbol->string (syntax-e #'s))])) + args)] + [doms (map (lambda (x) (car (syntax->list x))) (syntax->list #'(clause ...)))]) + (syntax-property + (stepper-syntax-property + #`(let ((quasi-object (make-immutable-hash (map cons '#,keys (list #,@args))))) + (lambda (world key-event) + ((hash-ref quasi-object key-event) world))) + 'stepper-skip-completely #t) + 'disappeared-use doms))])) + (define (run-simulation f) (check-proc 'run-simulation f 1 "first" "one argument") (big-bang 0 (on-draw f) (on-tick add1))) diff --git a/collects/2htdp/xtest b/collects/2htdp/xtest index 499fc32811..ad6bcb1fec 100755 --- a/collects/2htdp/xtest +++ b/collects/2htdp/xtest @@ -40,3 +40,4 @@ run struct-universe.rkt run universe-receive.rkt run name.rkt run pad1.rkt +run pad1-handler.rkt From 17e66e196d072172071b6160f76d361fd6a33b6e Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 16 Jan 2012 12:36:46 -0500 Subject: [PATCH 494/746] added documentation for pad-handler facility (cherry picked from commit 10f8222bf4372ed64b977ef310d40ad5211e8ebe) --- .../2htdp/scribblings/universe.scrbl | 118 +++++++++++++++++- 1 file changed, 114 insertions(+), 4 deletions(-) diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index a8c8e01323..3b085b65be 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -435,10 +435,13 @@ It is one of the following: @tech{KeyEvent} for every keystroke that is also a @tech{PadEvent}. The result of the call becomes the current world. - Here is a typical pad-event handler: -@racketblock[ + Here is a typical @tech{PadEvent} handler: +@;% +@(begin +#reader scribble/comment-reader +(racketblock ;; ComplexNumber PadEvent -> ComplexNumber -(define (pad-handler x k) +(define (handle-pad-events x k) (case (string->symbol k) [(up w) (- x 0+10i)] [(down s) (+ x 0+10i)] @@ -447,7 +450,10 @@ It is one of the following: [(| |) x0] [(shift) (conjugate x)] [(rshift) (stop-with (conjugate x))])) -] + +)) +@;% + } When a @racket[big-bang] expression specifies an @racket[on-pad] clause, @@ -455,6 +461,109 @@ all @tech{PadEvent}s are sent to the @racket[on-pad] handler. All other key events are discarded, unless an @racket[on-key] and/or an @racket[on-release] clause are specified, in which case all remaining @tech{KeyEvent}s are sent there. + +To facilitate the definition of @racket[on-pad] handlers, the library +provides the @racket[pad-handler] form. + +@defform/subs[#:id pad-handler + #:literals + (up down left right space shift) + (pad-handler clause ...) + ([clause + (up up-expr) + (down down-expr) + (left left-expr) + (right right-expr) + (space space-expr) + (shift shift-expr)])]{ + Creates a function that deals with @tech{PadEvent}s. Each (optional) clause + contributes one function that consumes a @tech{World} and produces a + world. The name of the clause determines for which kind of @tech{PadEvent} + the function is called. + + Using the form is entirely optional and not required to use + @racket[on-pad]. Indeed, @racket[pad-handler] could be used to define a + plain @tech{KeyEvent} handler---if we could guarantee that players never + hit keys other than @tech{PadEvent} keys. +} + +All clauses in a @racket[pad-handler] form are optional: +@itemize[ + +@item{ +@defform[(up up-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{WorldState}) (unsyntax @tech{WorldState}))])]{ + Creates a handler for @racket["up"] and @racket["w"] events.} +} + +@item{ +@defform[(down down-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{WorldState}) (unsyntax @tech{WorldState}))])]{ + Creates a handler for @racket["down"] and @racket["s"] events.} +} + +@item{ +@defform[(left left-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{WorldState}) (unsyntax + @tech{WorldState}))])]{ + Creates a handler for @racket["left"] and @racket["a"] events.} +} + +@item{ +@defform[(right right-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{WorldState}) (unsyntax + @tech{WorldState}))])]{ + Creates a handler for @racket["right"] and @racket["d"] events.} +} + +@item{ +@defform[(space space-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{WorldState}) (unsyntax + @tech{WorldState}))])]{ + Creates a handler for space-bar events (@racket[" "]).} +} + +@item{ +@defform[(shift shift-expr) + #:contracts + ([tick-expr (-> (unsyntax @tech{WorldState}) (unsyntax + @tech{WorldState}))])]{ + Creates a handler for @racket["shift"] and @racket["rshift"] events.} +} + +] + If a clause is omitted, @racket[pad-handler] installs a default function + that maps the existing world to itself. + + Here is a @tech{PadEvent} handler defined with @racket[pad-handler]: +@;% +@(begin +#reader scribble/comment-reader +(racketblock +;; ComplexNumber -> ComplexNumber +(define (i-sub1 x) (- x 0+1i)) + +;; ComplexNumber -> ComplexNumber +(define (i-add1 x) (+ x 0+1i)) + +;; ComplexNumber -> ComplexNumber +;; deal with all @tech{PadEvent}s +(define handler + (pad-handler (left sub1) (right add1) + (up i-sub1) (down i-add1) + (shift (lambda (w) 0)) + (space stop-with))) + +;; some tests: +(check-expect (handler 9 "left") 8) +(check-expect (handler 8 "up") 8-i) +)) +@;% } @item{ A @tech{MouseEvent} represents mouse events, e.g., mouse movements @@ -620,6 +729,7 @@ a short-hand for three lines of code: Exercise: Add a condition for stopping the flight of the UFO when it reaches the bottom. + @; ----------------------------------------------------------------------------- @section[#:tag "world-example"]{A First Sample World} From f7340ead45c08ef1d1c2dcf25e1423b39a9da416 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Mon, 16 Jan 2012 12:44:40 -0700 Subject: [PATCH 495/746] Icon fixes: Split images/icons/misc into images/icons/symbol and images/icons/misc Updated tests Fixed Gtk assertion failure in Macro Stepper (came from "about" dialog being created before the stepper window was shown; fixed by creating it on demand) Changed Stepper similarly (though there was no assertion failure) Put a quote in the Macro Stepper logo Portable recycle-icon Removed recycle unicode from the docs (was causing PDF build to fail) Internal API fixes Please merge into release (cherry picked from commit ea68677d2f4ece1d0ad1df6447fb27f90e98ba3e) --- collects/icons/macro-stepper-32x32.png | Bin 2605 -> 2645 bytes collects/images/icons/arrow.rkt | 12 +- collects/images/icons/misc.rkt | 228 ++-------------- collects/images/icons/symbol.rkt | 260 +++++++++++++++++++ collects/images/icons/tool.rkt | 1 + collects/images/logos.rkt | 24 +- collects/images/private/utils.rkt | 4 +- collects/images/scribblings/icons.scrbl | 50 ++-- collects/images/tests/icon-tests.rkt | 9 +- collects/images/tests/logo-tests.rkt | 6 +- collects/macro-debugger/view/stepper.rkt | 26 +- collects/stepper/private/view-controller.rkt | 26 +- 12 files changed, 367 insertions(+), 279 deletions(-) create mode 100644 collects/images/icons/symbol.rkt diff --git a/collects/icons/macro-stepper-32x32.png b/collects/icons/macro-stepper-32x32.png index 51766e166f43661d1743915663dfeda9cb4680a4..4ed6905da57beca35bb71f32098f18770015a095 100644 GIT binary patch delta 2619 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 pd^SasXj}tQO$-14002ovPDHLkV1i!z9A*Fj diff --git a/collects/images/icons/arrow.rkt b/collects/images/icons/arrow.rkt index e894e0fd25..732c1a2489 100644 --- a/collects/images/icons/arrow.rkt +++ b/collects/images/icons/arrow.rkt @@ -40,12 +40,12 @@ 32 32 (λ (dc) (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) - (draw-path-commands - dc 0 0 '((m 0 15) - (c 9 -14 19.5 -8 24 -2) - (l 5 -7 2 20 -20 -2 7 -5) - (c -2.5 -4 -8 -8.5 -14 0) - (l -4 -4)))) + (draw-path-commands dc '((m 0 15) + (c 9 -14 19.5 -8 24 -2) + (l 5 -7 2 20 -20 -2 7 -5) + (c -2.5 -4 -8 -8.5 -14 0) + (l -4 -4)) + 0 0)) (/ height 32))) (defproc (right-arrow-flomap [color (or/c string? (is-a?/c color%))] diff --git a/collects/images/icons/misc.rkt b/collects/images/icons/misc.rkt index 344a2288f6..39dbed334b 100644 --- a/collects/images/icons/misc.rkt +++ b/collects/images/icons/misc.rkt @@ -5,55 +5,21 @@ "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" + "symbol.rkt" "style.rkt") (provide (activate-contract-out - text-icon text-flomap - recycle-icon recycle-flomap - x-icon x-flomap - check-icon check-flomap regular-polygon-icon regular-polygon-flomap octagon-icon octagon-flomap stop-sign-icon stop-sign-flomap stop-signs-icon stop-signs-flomap foot-icon foot-flomap - lambda-icon lambda-flomap magnifying-glass-icon magnifying-glass-flomap left-magnifying-glass-icon left-magnifying-glass-flomap bomb-icon bomb-flomap left-bomb-icon left-bomb-flomap) (only-doc-out (all-defined-out))) -;; =================================================================================================== -;; Unrendered flomaps - -(define (flat-x-flomap color height) - (define mn 7.5) - (define mx 23.5) - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen (make-object pen% (icon-color->outline-color color) - 12 'solid 'projecting 'miter)) - (send dc draw-line mn mn mx mx) - (send dc draw-line mn mx mx mn) - (send dc set-pen (make-object pen% color 10 'solid 'projecting 'miter)) - (send dc draw-line mn mn mx mx) - (send dc draw-line mn mx mx mn)) - (/ height 32))) - -(define (flat-check-flomap color height) - (draw-icon-flomap - 32 32 (λ (dc) - (set-icon-pen dc (icon-color->outline-color color) 1 'solid) - (send dc set-brush color 'solid) - (draw-path-commands - dc 0 0 '((m 0 19) - (c 0 0 7 4 14 12 5.5 -13.5 17 -23 17 -23) - (l -9 -8) - (c 0 0 -6.5 7.5 -9.5 16 -2.5 -4 -6 -6.5 -6 -6.5) - (l -6 9)))) - (/ height 32))) - (define (flat-regular-polygon-flomap sides start color size) (let ([start (- start)]) (draw-icon-flomap @@ -69,146 +35,6 @@ (+ 15.5 (/ (* 15.5 (sin θ)) max-frac)))))) (/ size 32)))) -;; =================================================================================================== -;; Rendered flomaps - -(defproc (text-flomap [str string?] [font (is-a?/c font%)] - [color (or/c string? (is-a?/c color%))] - [trim? boolean? #t] - [outline (or/c 'auto (and/c rational? (>=/c 0))) 'auto] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)]) flomap? - (define size (max 32 (send font get-point-size))) - (define family (send font get-family)) - (define style (send font get-style)) - (define weight (send font get-weight)) - (define underline? (send font get-underlined)) - (define smoothing (send font get-smoothing)) - - (make-cached-flomap - [height str family style weight underline? smoothing color trim? outline material] - (let ([font (make-object font% size family style weight underline? smoothing #t)] - [outline (if (equal? outline 'auto) (/ height 32) outline)]) - (define outline-color (icon-color->outline-color color)) - (define r (/ (send outline-color red) 255.0)) - (define g (/ (send outline-color green) 255.0)) - (define b (/ (send outline-color blue) 255.0)) - (define-values (w h) (get-text-size str font)) - (define ceiling-amt (inexact->exact (ceiling outline))) - (let* ([fm (draw-flomap - w h (λ (dc) - (send dc set-font font) - (send dc set-text-foreground color) - (send dc draw-text str 0 0 #t)))] - [fm (if trim? (flomap-trim fm) fm)] - [fm (flomap-resize fm #f (- height (* 2 ceiling-amt)))] - [fm (flomap-inset fm ceiling-amt)] - [fm (if (outline . > . 0) (flomap-outlined fm outline (list r g b)) fm)]) - (flomap-render-icon fm material))))) - -(defproc (recycle-flomap [color (or/c string? (is-a?/c color%))] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)]) flomap? - (define size (max 1 (min 1024 (inexact->exact (ceiling (* 2 height)))))) - (text-flomap "♻" (make-object font% size 'default) color #t (/ height 64) height material)) - -(defproc (x-flomap [color (or/c string? (is-a?/c color%))] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)]) flomap? - (make-cached-flomap - [height color material] - (define scale (/ height 32)) - (let* ([fm (flat-x-flomap color height)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* -8 scale))]) - (deep-flomap-render-icon dfm material)))) - -(defproc (check-flomap [color (or/c string? (is-a?/c color%))] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)]) flomap? - (make-cached-flomap - [height color material] - (define scale (/ height 32)) - (let* ([fm (flat-check-flomap color height)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* -12 scale))]) - (deep-flomap-render-icon dfm material)))) - -(define lambda-path-commands - '((m 8.5 1.5) - (c -1.6356765828908555 0.029546719528023596 - -3.191760877876106 0.5981878749262537 - -4.720477489085545 1.1242189706194692) - (c 0.6669351268436579 0.7142825307374631 - 0.5663221427728614 0.9399074888495575 - 0.8574087929203539 0.8856493838348083) - (c 1.1139361982300886 -0.26979469970501474 - 2.7661170029498527 -0.8976661899705014 - 3.5022074713864306 0.2920653404129794) - (c 1.604836361061947 2.027318824778761 - 2.2854387162241885 4.621830343362832 - 2.528554440117994 7.151444427138643) - (c 0.3116530407079646 1.536908007079646 - -2.857777387610619 7.039676186430679 - -3.8315742017699113 9.23609637758112) - (c -1.5828472448377582 2.792818935693215 - -2.9889992117994097 5.691217406489675 - -4.772427818289086 8.366316818879056) - (c 0.42649146902654866 0.5644402784660767 - 1.0427237946902654 0.34355411445427725 - 1.6228086182890855 0.25676724483775815) - (c 0.49529097817109147 -0.07420284601769911 - 0.9905831646017699 -0.14840448377581122 - 1.4858741427728612 -0.22260672566371684) - (c 1.5973270277286136 -3.787185161061947 - 3.3219870961651914 -7.263537085545722 - 4.820870569911505 -11.091467780530973) - (c 0.6830176660766961 -1.5775599008849557 - 1.0166688849557521 -2.445292667846608 - 1.8281710631268435 -3.4783485734513273) - (c 0.9620301781710914 0.5885710348082596 - 1.2484493215339232 2.040281637758112 - 1.77328405899705 3.0419137321533922) - (c 1.5467160542772862 3.979993184660766 - 3.0867486206489674 7.962568420058997 - 4.546565437168141 11.975105472566373) - (c 0.3820927622418879 0.13305596224188793 - 0.7742605970501475 0.5306156554572271 - 1.1366913510324481 0.14744150088495575) - (c 0.9533687693215339 -0.5878412460176992 - 2.0633098572271384 -0.9560281486725664 - 2.857080825958702 -1.7685525144542773) - (c -0.2264924884955752 -1.0982469474926253 - -0.9541940106194691 -2.1254820625368733 - -1.3975098902654866 -3.181664056637168) - (c -2.8100934230088495 -5.615961562241888 - -5.519535197640117 -11.572843233038348 - -7.278479027728613 -17.620018746902655) - (c -0.6478138147492625 -1.9033066855457228 - -1.4455158560471977 -4.19687149120944 - -3.5071903339233037 -4.948212008023599) - (c -0.46965654277286134 -0.13943394171091444 - -0.9645608778761062 -0.1662308436578171 - -1.451858010619469 -0.16614886324483774))) - -(defproc (lambda-flomap [color (or/c string? (is-a?/c color%))] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)]) flomap? - (make-cached-flomap - [height color material] - (draw-rendered-icon-flomap - 32 32 (λ (dc) - (set-icon-pen dc (icon-color->outline-color color) 4 'solid) - (send dc set-brush (icon-color->outline-color color) 'solid) - (draw-path-commands dc 4 0 lambda-path-commands) - (set-icon-pen dc color 2 'solid) - (send dc set-brush color 'solid) - (draw-path-commands dc 4 0 lambda-path-commands)) - (/ height 32) - material))) - (defproc (regular-polygon-flomap [sides exact-positive-integer?] [start real?] [color (or/c string? (is-a?/c color%))] @@ -362,17 +188,16 @@ 10 25 (λ (dc) (send dc set-pen "darkred" 1 'solid) (send dc set-brush "gold" 'solid) - (draw-path-commands - dc 0 0 - '((m 3.5 0) - (c -5 0 -3.29080284 10.4205 -3 11.5 - 1.1137011 4.1343 2 6.5 0 8.5 - -0.5711131 2.0524 1.5 4 3.5 3.5 - 2.5711131 -2.5524 3.1327042 -5.5355 2 -9.5 - -2 -7 -2 -9 -1.5 -9 - 0 1 -0.5 2 1 3.5 - 2 0.5 4 -1.5 3.5 -3.5 - -2 -2 -2 -5 -5.5 -5)))) + (draw-path-commands dc '((m 3.5 0) + (c -5 0 -3.29080284 10.4205 -3 11.5 + 1.1137011 4.1343 2 6.5 0 8.5 + -0.5711131 2.0524 1.5 4 3.5 3.5 + 2.5711131 -2.5524 3.1327042 -5.5355 2 -9.5 + -2 -7 -2 -9 -1.5 -9 + 0 1 -0.5 2 1 3.5 + 2 0.5 4 -1.5 3.5 -3.5 + -2 -2 -2 -5 -5.5 -5)) + 0 0)) scale)] [dfm (flomap->deep-flomap fm)] [dfm (deep-flomap-icon-style dfm)] @@ -384,13 +209,15 @@ 20 20 (λ (dc) (set-icon-pen dc (icon-color->outline-color color) 1 'solid) (send dc set-brush color 'solid) - (draw-path-commands dc 0 0 '((m 1.5 11.5) - (l 10 -10 2.5 2.5) - (c 4 5 -5 14 -10 10) - (l -2.5 -2.5))) - (draw-path-commands dc 0 0 '((m 1.5 11.5) - (c -2 -5 5 -12 10 -10 - 4 5 -5 14 -10 10)))) + (draw-path-commands dc '((m 1.5 11.5) + (l 10 -10 2.5 2.5) + (c 4 5 -5 14 -10 10) + (l -2.5 -2.5)) + 0 0) + (draw-path-commands dc '((m 1.5 11.5) + (c -2 -5 5 -12 10 -10 + 4 5 -5 14 -10 10)) + 0 0)) scale)) (define cap-fm @@ -427,15 +254,6 @@ ;; =================================================================================================== ;; Bitmaps (icons) -(defproc (text-icon [str string?] [font (is-a?/c font%)] - [color (or/c string? (is-a?/c color%))] - [trim? boolean? #t] - [outline (or/c 'auto (and/c rational? (>=/c 0))) 'auto] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)] - ) (is-a?/c bitmap%) - (flomap->bitmap (text-flomap str font color trim? outline height material))) - (defproc (regular-polygon-icon [sides exact-positive-integer?] [start real?] [color (or/c string? (is-a?/c color%))] @@ -448,14 +266,10 @@ ([color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0)) (default-icon-height)] [material deep-flomap-material-value? (default-icon-material)]) - [recycle-icon recycle-flomap] - [x-icon x-flomap] - [check-icon check-flomap] [octagon-icon octagon-flomap] [stop-sign-icon stop-sign-flomap] [stop-signs-icon stop-signs-flomap] - [foot-icon foot-flomap] - [lambda-icon lambda-flomap]) + [foot-icon foot-flomap]) (define-icon-wrappers ([frame-color (or/c string? (is-a?/c color%))] diff --git a/collects/images/icons/symbol.rkt b/collects/images/icons/symbol.rkt new file mode 100644 index 0000000000..aa33dd9045 --- /dev/null +++ b/collects/images/icons/symbol.rkt @@ -0,0 +1,260 @@ +#lang racket/base + +(require racket/draw racket/class racket/math racket/sequence + racket/contract unstable/latent-contract unstable/latent-contract/defthing + "../private/flomap.rkt" + "../private/deep-flomap.rkt" + "../private/utils.rkt" + "style.rkt") + +(provide flat-x-flomap + (activate-contract-out + text-icon text-flomap + recycle-icon recycle-flomap + x-icon x-flomap + check-icon check-flomap + lambda-icon lambda-flomap) + (only-doc-out (all-defined-out))) + +(define (flat-x-flomap color height) + (define mn 7.5) + (define mx 23.5) + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen (make-object pen% (icon-color->outline-color color) + 12 'solid 'projecting 'miter)) + (send dc draw-line mn mn mx mx) + (send dc draw-line mn mx mx mn) + (send dc set-pen (make-object pen% color 10 'solid 'projecting 'miter)) + (send dc draw-line mn mn mx mx) + (send dc draw-line mn mx mx mn)) + (/ height 32))) + +(define (flat-check-flomap color height) + (draw-icon-flomap + 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1 'solid) + (send dc set-brush color 'solid) + (draw-path-commands dc '((m 0 19) + (c 0 0 7 4 14 12 5.5 -13.5 17 -23 17 -23) + (l -9 -8) + (c 0 0 -6.5 7.5 -9.5 16 -2.5 -4 -6 -6.5 -6 -6.5) + (l -6 9)) + 0 0)) + (/ height 32))) + +(defproc (text-flomap [str string?] [font (is-a?/c font%)] + [color (or/c string? (is-a?/c color%))] + [trim? boolean? #t] + [outline (or/c 'auto (and/c rational? (>=/c 0))) 'auto] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (define size (max 32 (send font get-point-size))) + (define family (send font get-family)) + (define style (send font get-style)) + (define weight (send font get-weight)) + (define underline? (send font get-underlined)) + (define smoothing (send font get-smoothing)) + + (make-cached-flomap + [height str family style weight underline? smoothing color trim? outline material] + (let ([font (make-object font% size family style weight underline? smoothing #t)] + [outline (if (equal? outline 'auto) (/ height 32) outline)]) + (define outline-color (icon-color->outline-color color)) + (define r (/ (send outline-color red) 255.0)) + (define g (/ (send outline-color green) 255.0)) + (define b (/ (send outline-color blue) 255.0)) + (define-values (w h) (get-text-size str font)) + (define ceiling-amt (inexact->exact (ceiling outline))) + (let* ([fm (draw-flomap + w h (λ (dc) + (send dc set-font font) + (send dc set-text-foreground color) + (send dc draw-text str 0 0 #t)))] + [fm (if trim? (flomap-trim fm) fm)] + [fm (flomap-resize fm #f (- height (* 2 ceiling-amt)))] + [fm (flomap-inset fm ceiling-amt)] + [fm (if (outline . > . 0) (flomap-outlined fm outline (list r g b)) fm)]) + (flomap-render-icon fm material))))) + +(define recycle-path-commands + '((m 13.28125 0.65625) + (c 0.463636 0.0842975 0.965857 0.50656 1.21875 0.84375) + (l 4.09375 7.09375) + (l -2.125 1.25) + (l 7.0 0.0) + (l 3.5 -6.0625) + (l -2.15625 1.21875) + (l -2.125 -3.78125) + (c -0.210743 -0.37933886 -0.630114 -0.5625 -1.09375 -0.5625) + (l -8.3125 0.0) + (m -2.40625 0.4375) + (c -1.0747934 0.0368802 -2.119938 0.438998 -2.5625 1.21875) + (l -3.21875 5.59375) + (l 6.15625 3.59375) + (l 3.9375 -6.84375) + (l -1.5625 -2.59375) + (c -0.569008 -0.6743802 -1.675207 -1.0056302 -2.75 -0.96875) + (m 16.65625 8.65625) + (l -6.21875 3.5625) + (l 3.9375 6.6875) + (l 3.3125 0) + (c 1.34876 -0.252893 3.398916 -2.442717 2.21875 -4.71875) + (l -3.25 -5.53125) + (m -27.4375 1.5) + (l 2.21875 1.28125) + (l -1.4375 2.40625) + (c -1.2644628 2.360331 0.8605372 4.956767 2.125 5.09375) + (l 3.28125 0.0) + (l 2.21875 -3.875) + (l 2.25 1.21875) + (l -3.59375 -6.125) + (l -7.0625 0.0) + (m 20.09375 7.1875) + (l -3.59375 6.15625) + (l 3.59375 6.125) + (l 0.0 -2.59375) + (l 4.375 0.0) + (c 0.505785 0.0 0.862655 -0.28781 1.03125 -0.625) + (l 3.96875 -7.0) + (c -0.210743 0.126446 -0.355424 0.3532 -1.15625 0.4375) + (l -8.21875 0.0) + (l 0.0 -2.5) + (m -18.21875 2.15625) + (c 0.168595 0.210744 0.1346592 0.174793 3.84375 6.75) + (c 0.2528926 0.379339 0.5988637 0.8234 1.0625 0.78125) + (l 7.875 0.0) + (l 0.0 -7.1875) + (l -11.71875 0.0) + (c -0.6322314 0.0 -0.8622934 -0.175155 -1.0625 -0.34375))) + +(defproc (recycle-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (make-cached-flomap + [height color material] + (draw-short-rendered-icon-flomap + 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 1/2 'solid) + (send dc set-brush color 'solid) + (draw-path-commands dc recycle-path-commands 0 0)) + (/ height 32) + material))) + +(defproc (x-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (make-cached-flomap + [height color material] + (define scale (/ height 32)) + (let* ([fm (flat-x-flomap color height)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-raise dfm (* -8 scale))]) + (deep-flomap-render-icon dfm material)))) + +(defproc (check-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (make-cached-flomap + [height color material] + (define scale (/ height 32)) + (let* ([fm (flat-check-flomap color height)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-raise dfm (* -12 scale))]) + (deep-flomap-render-icon dfm material)))) + +(define lambda-path-commands + '((m 8.5 1.5) + (c -1.6356765828908555 0.029546719528023596 + -3.191760877876106 0.5981878749262537 + -4.720477489085545 1.1242189706194692) + (c 0.6669351268436579 0.7142825307374631 + 0.5663221427728614 0.9399074888495575 + 0.8574087929203539 0.8856493838348083) + (c 1.1139361982300886 -0.26979469970501474 + 2.7661170029498527 -0.8976661899705014 + 3.5022074713864306 0.2920653404129794) + (c 1.604836361061947 2.027318824778761 + 2.2854387162241885 4.621830343362832 + 2.528554440117994 7.151444427138643) + (c 0.3116530407079646 1.536908007079646 + -2.857777387610619 7.039676186430679 + -3.8315742017699113 9.23609637758112) + (c -1.5828472448377582 2.792818935693215 + -2.9889992117994097 5.691217406489675 + -4.772427818289086 8.366316818879056) + (c 0.42649146902654866 0.5644402784660767 + 1.0427237946902654 0.34355411445427725 + 1.6228086182890855 0.25676724483775815) + (c 0.49529097817109147 -0.07420284601769911 + 0.9905831646017699 -0.14840448377581122 + 1.4858741427728612 -0.22260672566371684) + (c 1.5973270277286136 -3.787185161061947 + 3.3219870961651914 -7.263537085545722 + 4.820870569911505 -11.091467780530973) + (c 0.6830176660766961 -1.5775599008849557 + 1.0166688849557521 -2.445292667846608 + 1.8281710631268435 -3.4783485734513273) + (c 0.9620301781710914 0.5885710348082596 + 1.2484493215339232 2.040281637758112 + 1.77328405899705 3.0419137321533922) + (c 1.5467160542772862 3.979993184660766 + 3.0867486206489674 7.962568420058997 + 4.546565437168141 11.975105472566373) + (c 0.3820927622418879 0.13305596224188793 + 0.7742605970501475 0.5306156554572271 + 1.1366913510324481 0.14744150088495575) + (c 0.9533687693215339 -0.5878412460176992 + 2.0633098572271384 -0.9560281486725664 + 2.857080825958702 -1.7685525144542773) + (c -0.2264924884955752 -1.0982469474926253 + -0.9541940106194691 -2.1254820625368733 + -1.3975098902654866 -3.181664056637168) + (c -2.8100934230088495 -5.615961562241888 + -5.519535197640117 -11.572843233038348 + -7.278479027728613 -17.620018746902655) + (c -0.6478138147492625 -1.9033066855457228 + -1.4455158560471977 -4.19687149120944 + -3.5071903339233037 -4.948212008023599) + (c -0.46965654277286134 -0.13943394171091444 + -0.9645608778761062 -0.1662308436578171 + -1.451858010619469 -0.16614886324483774))) + +(defproc (lambda-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (make-cached-flomap + [height color material] + (draw-rendered-icon-flomap + 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color color) 4 'solid) + (send dc set-brush (icon-color->outline-color color) 'solid) + (draw-path-commands dc lambda-path-commands 4 0) + (set-icon-pen dc color 2 'solid) + (send dc set-brush color 'solid) + (draw-path-commands dc lambda-path-commands 4 0)) + (/ height 32) + material))) + +;; =================================================================================================== +;; Bitmaps (icons) + +(defproc (text-icon [str string?] [font (is-a?/c font%)] + [color (or/c string? (is-a?/c color%))] + [trim? boolean? #t] + [outline (or/c 'auto (and/c rational? (>=/c 0))) 'auto] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (text-flomap str font color trim? outline height material))) + +(define-icon-wrappers + ([color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [recycle-icon recycle-flomap] + [x-icon x-flomap] + [check-icon check-flomap] + [lambda-icon lambda-flomap]) diff --git a/collects/images/icons/tool.rkt b/collects/images/icons/tool.rkt index 3b341c08d8..47534a52d1 100644 --- a/collects/images/icons/tool.rkt +++ b/collects/images/icons/tool.rkt @@ -6,6 +6,7 @@ "../private/deep-flomap.rkt" "../private/utils.rkt" "control.rkt" + "symbol.rkt" "misc.rkt" "style.rkt") diff --git a/collects/images/logos.rkt b/collects/images/logos.rkt index 7d0d2634ab..10cfe4b5ad 100644 --- a/collects/images/logos.rkt +++ b/collects/images/logos.rkt @@ -5,6 +5,7 @@ "private/flomap.rkt" "private/deep-flomap.rkt" "private/utils.rkt" + "icons/symbol.rkt" "icons/misc.rkt" "icons/style.rkt") @@ -81,7 +82,7 @@ (define (draw-lambda dc x y w h) (define-values (sx sy) (send dc get-scale)) - (draw-path-commands dc x y (scale-path-commands lambda-path-commands (/ w 240) (/ h 240))) + (draw-path-commands dc (scale-path-commands lambda-path-commands (/ w 240) (/ h 240)) x y) (send dc set-scale sx sy)) (define blue-θ-start (* -45 (/ pi 180))) @@ -246,7 +247,7 @@ 32 32 (λ (dc) (send dc set-pen lambda-outline-color 3/8 'solid) (send dc set-brush color 'solid) - (draw-path-commands dc 0 -17 continents-path-commands)) + (draw-path-commands dc continents-path-commands 0 -17)) scale)) (defproc (planet-flomap [height (and/c rational? (>=/c 0)) 256]) flomap? @@ -299,24 +300,29 @@ (defproc (macro-stepper-logo-flomap [height (and/c rational? (>=/c 0)) 96]) flomap? (define outline-color (icon-color->outline-color light-metal-icon-color)) - (define (draw-hash dc) + (define (draw-hash-quote dc) + ;; vertical lines (send dc draw-polygon '((5 . 0) (8 . 0) (6 . 19) (3 . 19))) - (send dc draw-polygon '((13 . 0) (16 . 0) (14 . 19) (11 . 19))) - (send dc draw-polygon '((1 . 4) (1 . 7) (19 . 7) (19 . 4))) - (send dc draw-polygon '((0 . 12) (0 . 15) (18 . 15) (18 . 12)))) + (send dc draw-polygon '((12 . 0) (15 . 0) (13 . 19) (10 . 19))) + ;; horizontal lines + (send dc draw-polygon '((1 . 4) (1 . 7) (18 . 7) (18 . 4))) + (send dc draw-polygon '((0 . 12) (0 . 15) (17 . 15) (17 . 12))) + ;; quote + (send dc draw-polygon '((20 . 0) (23 . 0) (22.75 . 6) (20.25 . 6))) + ) (flomap-pin* 1/2 20/32 1/2 1/2 (foot-flomap (make-object color% 34 42 160) height glass-icon-material) (draw-rendered-icon-flomap 32 32 (λ (dc) - (send dc translate 6 6) + (send dc translate 5 6) (set-icon-pen dc outline-color 2 'solid) (send dc set-brush outline-color 'solid) - (draw-hash dc) + (draw-hash-quote dc) (send dc set-pen "black" 1 'transparent) (send dc set-brush light-metal-icon-color 'solid) - (draw-hash dc)) + (draw-hash-quote dc)) (/ (* 3/4 height) 32) metal-icon-material))) diff --git a/collects/images/private/utils.rkt b/collects/images/private/utils.rkt index 167ec3aa43..be90de5744 100644 --- a/collects/images/private/utils.rkt +++ b/collects/images/private/utils.rkt @@ -128,7 +128,7 @@ [_ (error 'apply-path-commands "unknown path command ~e" cmd)])])) (void)) -(define (draw-path-commands dc x y cmds) +(define (draw-path-commands dc cmds x y) (define p (new dc-path%)) (apply-path-commands p cmds) (define t (send dc get-transformation)) @@ -166,7 +166,7 @@ [`(M ,ax ,ay ,as ...) (cons `(m ,(- ax x) ,(- ay y)) (loop ax ay (cons `(M ,@as) (rest cmds))))] [`(L ,ax ,ay ,as ...) (cons `(l ,(- ax x) ,(- ay y)) - (loop ax ay (cons '(L ,@as) (rest cmds))))] + (loop ax ay (cons `(L ,@as) (rest cmds))))] [`(C ,ax1 ,ay1 ,ax2 ,ay2 ,ax ,ay ,as ...) (cons `(c ,(- ax1 x) ,(- ay1 y) ,(- ax2 x) ,(- ay2 y) ,(- ax x) ,(- ay y)) (loop ax ay (cons `(C ,@as) (rest cmds))))] diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl index 0f583bd632..53396ec767 100644 --- a/collects/images/scribblings/icons.scrbl +++ b/collects/images/scribblings/icons.scrbl @@ -6,6 +6,7 @@ images/icons/arrow images/icons/control images/icons/file + images/icons/symbol images/icons/misc images/icons/stickman images/icons/tool @@ -19,6 +20,7 @@ images/icons/file images/icons/misc images/icons/stickman + images/icons/symbol images/icons/tool images/icons/style) @@ -227,28 +229,18 @@ This is not a ``control'' icon @italic{per se}, but is used to make many others. @defmodule[images/icons/file] @interaction-eval[#:eval icons-eval (require images/icons/file)] -@doc-apply[floppy-disk-icon]{ -@examples[#:eval icons-eval (floppy-disk-icon "crimson" 32 glass-icon-material)] -} - -@doc-apply[save-icon] -@doc-apply[small-save-icon] -@doc-apply[load-icon] -@doc-apply[small-load-icon]{ -@examples[#:eval icons-eval - (for/list ([make-icon (list save-icon small-save-icon - load-icon small-load-icon)] - [color (list run-icon-color halt-icon-color - metal-icon-color dark-metal-icon-color)]) - (make-icon syntax-icon-color color 32))] -} +@doc-apply[floppy-disk-icon]{ @examples[#:eval icons-eval (floppy-disk-icon "crimson" 32 glass-icon-material)] } +@doc-apply[save-icon]{ @examples[#:eval icons-eval (save-icon syntax-icon-color run-icon-color 32)] } +@doc-apply[load-icon]{ @examples[#:eval icons-eval (load-icon syntax-icon-color metal-icon-color 32)] } +@doc-apply[small-save-icon]{ @examples[#:eval icons-eval (small-save-icon syntax-icon-color halt-icon-color 32)] } +@doc-apply[small-load-icon]{ @examples[#:eval icons-eval (small-load-icon syntax-icon-color dark-metal-icon-color 32)] } @;==================================================================================================== -@section[#:tag "misc"]{Miscellaneous Icons} +@section[#:tag "symbol"]{Symbol and Text Icons} -@defmodule[images/icons/misc] -@interaction-eval[#:eval icons-eval (require images/icons/misc)] +@defmodule[images/icons/symbol] +@interaction-eval[#:eval icons-eval (require images/icons/symbol)] @doc-apply[text-icon]{ Renders a text string as an icon. For example, @@ -278,13 +270,12 @@ Note that both icons are @racket[(default-icon-height)] pixels tall. When @racket[outline] is @racket['auto], the outline drawn around the text is @racket[(/ height 32)] pixels wide. -Because different platforms have slightly different fonts, @racket[text-icon] cannot guarantee the icons it returns have a consistent look or width across all platforms. +Because different platforms have different fonts, @racket[text-icon] cannot guarantee the icons it returns have a consistent look or width across all platforms, or that the unicode characters will exist. } @doc-apply[recycle-icon]{ Returns the universal recycling symbol, rendered as an icon. -Its implementation calls @racket[text-icon] with the string @racket["\u267b"]. -@examples[#:eval icons-eval (recycle-icon "forestgreen" 48)] +@examples[#:eval icons-eval (recycle-icon (make-object color% 0 153 0) 48)] } @doc-apply[x-icon]{ @@ -297,6 +288,18 @@ Returns an ``x'' icon that is guaranteed to look the same on all platforms. @examples[#:eval icons-eval (check-icon "darkgreen" 32)] } +@doc-apply[lambda-icon]{ +@examples[#:eval icons-eval + (lambda-icon light-metal-icon-color 32 metal-icon-material)] +} + +@;==================================================================================================== + +@section[#:tag "misc"]{Miscellaneous Icons} + +@defmodule[images/icons/misc] +@interaction-eval[#:eval icons-eval (require images/icons/misc)] + @doc-apply[regular-polygon-icon]{ Renders the largest regular polygon with @racket[sides] sides, with the first vertex at angle @racket[start], that can be centered in a @racket[height] × @racket[height] box. @examples[#:eval icons-eval (for/list ([sides (in-range 1 9)] @@ -326,11 +329,6 @@ Equivalent to @racket[(regular-polygon-icon 8 (/ (* 2 pi) 16) color height mater (foot-icon "chocolate" 32 glass-icon-material)] } -@doc-apply[lambda-icon]{ -@examples[#:eval icons-eval - (lambda-icon light-metal-icon-color 32 metal-icon-material)] -} - @doc-apply[magnifying-glass-icon]{ @examples[#:eval icons-eval (magnifying-glass-icon light-metal-icon-color "lightblue" 32 diff --git a/collects/images/tests/icon-tests.rkt b/collects/images/tests/icon-tests.rkt index a362914aa2..2ffe7b9f01 100644 --- a/collects/images/tests/icon-tests.rkt +++ b/collects/images/tests/icon-tests.rkt @@ -4,6 +4,7 @@ images/icons/control images/icons/arrow images/icons/file + images/icons/symbol images/icons/misc images/icons/tool images/icons/style @@ -37,8 +38,9 @@ ;; Other icons, various colors (define icon-procss - (list (list rewind-icon continue-back-icon step-back-icon back-icon pause-icon - stop-icon record-icon play-icon step-icon continue-icon fast-forward-icon) + (list (list search-backward-icon rewind-icon continue-backward-icon step-back-icon back-icon + pause-icon stop-icon record-icon play-icon step-icon continue-forward-icon + fast-forward-icon search-forward-icon) (list right-arrow-icon left-arrow-icon up-arrow-icon down-arrow-icon right-over-arrow-icon left-over-arrow-icon right-under-arrow-icon left-under-arrow-icon) (list floppy-disk-icon @@ -46,7 +48,8 @@ (λ (color) (load-icon syntax-icon-color color)) (λ (color) (small-save-icon syntax-icon-color color)) (λ (color) (small-load-icon syntax-icon-color color))) - (list x-icon check-icon octagon-icon stop-sign-icon stop-signs-icon + (list x-icon check-icon recycle-icon lambda-icon) + (list octagon-icon stop-sign-icon stop-signs-icon foot-icon (λ (color) (magnifying-glass-icon metal-icon-color color)) (λ (color) (left-magnifying-glass-icon metal-icon-color color)) (λ (color) (bomb-icon metal-icon-color color)) diff --git a/collects/images/tests/logo-tests.rkt b/collects/images/tests/logo-tests.rkt index 08ceb56088..6bd257c90c 100644 --- a/collects/images/tests/logo-tests.rkt +++ b/collects/images/tests/logo-tests.rkt @@ -2,5 +2,7 @@ (require images/logos) -(time (plt-logo 256)) -(time (planet-logo 256)) +(time (plt-logo)) +(time (planet-logo)) +(time (stepper-logo)) +(time (macro-stepper-logo)) diff --git a/collects/macro-debugger/view/stepper.rkt b/collects/macro-debugger/view/stepper.rkt index c9e156e2ee..8b7c3401cd 100644 --- a/collects/macro-debugger/view/stepper.rkt +++ b/collects/macro-debugger/view/stepper.rkt @@ -42,6 +42,19 @@ (define small-logo (compiled-bitmap (macro-stepper-logo 32))) (define large-logo (compiled-bitmap (macro-stepper-logo))) +(define (show-about-dialog parent) + (define dlg + (new logo-about-dialog% + (label "About the Macro Stepper") + (parent parent) + (bitmap large-logo) + (messages '("The Macro Stepper is formalized and proved correct in\n" + "\n" + " Ryan Culpepper and Matthias Felleisen\n" + " Debugging Hygienic Macros\n" + " Science of Computer Programming, July 2010\n")))) + (send dlg show #t)) + ;; Macro Stepper ;; macro-stepper-widget% @@ -159,23 +172,12 @@ (alignment '(left center)) (style '(deleted)))) - (define about-dialog - (new logo-about-dialog% - (label "About the Macro Stepper") - (parent frame) - (bitmap large-logo) - (messages '("The Macro Stepper is formalized and proved correct in\n" - "\n" - " Ryan Culpepper and Matthias Felleisen\n" - " Debugging Hygienic Macros\n" - " Science of Computer Programming, July 2010\n")))) - (define logo-canvas (new (class bitmap-canvas% (super-new (parent top-panel) (bitmap small-logo)) (define/override (on-event evt) (when (eq? (send evt get-event-type) 'left-up) - (send about-dialog show #t)))))) + (show-about-dialog frame)))))) (define/i sbview sb:syntax-browser<%> (new stepper-syntax-widget% diff --git a/collects/stepper/private/view-controller.rkt b/collects/stepper/private/view-controller.rkt index 8c258cccdc..4b1cde3d7c 100644 --- a/collects/stepper/private/view-controller.rkt +++ b/collects/stepper/private/view-controller.rkt @@ -31,6 +31,19 @@ ;; the stored representation of a step (define-struct step (text kind posns) #:transparent) +(define (show-about-dialog parent) + (define dlg + (new logo-about-dialog% + [label "About the Stepper"] + [parent parent] + [bitmap (compiled-bitmap (stepper-logo))] + [messages '("The Algebraic Stepper is formalized and proved correct in\n" + "\n" + " John Clements, Matthew Flatt, Matthias Felleisen\n" + " Modeling an Algebraic Stepper\n" + " European Symposium on Programming, 2001\n")])) + (send dlg show #t)) + (define (go drracket-tab program-expander selection-start selection-end) ;; get the language-level: @@ -230,23 +243,12 @@ [stretchable-width #t] [stretchable-height #f])) - (define about-dialog - (new logo-about-dialog% - [label "About the Stepper"] - [parent s-frame] - [bitmap (compiled-bitmap (stepper-logo))] - [messages '("The Algebraic Stepper is formalized and proved correct in\n" - "\n" - " John Clements, Matthew Flatt, Matthias Felleisen\n" - " Modeling an Algebraic Stepper\n" - " European Symposium on Programming, 2001\n")])) - (define logo-canvas (new (class bitmap-canvas% (super-new [parent top-panel] [bitmap (compiled-bitmap (stepper-logo 32))]) (define/override (on-event evt) (when (eq? (send evt get-event-type) 'left-up) - (send about-dialog show #t)))))) + (show-about-dialog s-frame)))))) (define prev-img (compiled-bitmap (step-back-icon run-icon-color (toolbar-icon-height)))) (define previous-button (new button% From 10c271e27e4a7f8a5b53812b5428095ad32d4eb7 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 16 Jan 2012 18:15:57 -0700 Subject: [PATCH 496/746] this creates a repeatable cored dump in drracket commit restricted to collects/2htdp/universe.rkt (cherry-picked from commit 54c1f496e8eca23c550e74a972589f1c72650fd1) --- collects/2htdp/universe.rkt | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index c0d99389ed..91c9b944f6 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -266,7 +266,8 @@ [down DEFAULT #'(lambda (x) x) (function-with-arity 1)] [left DEFAULT #'(lambda (x) x) (function-with-arity 1)] [right DEFAULT #'(lambda (x) x) (function-with-arity 1)] - [space DEFAULT #'(lambda (x) x) (function-with-arity 1)] + ; [space DEFAULT #'(lambda (x) x) (function-with-arity 1)] + #; [shift DEFAULT #'(lambda (x) x) (function-with-arity 1)]) (define-syntax (pad-handler stx) @@ -279,12 +280,21 @@ [doms (map (lambda (x) (car (syntax->list x))) (syntax->list #'(clause ...)))]) (syntax-property (stepper-syntax-property - #`(let ((quasi-object (make-immutable-hash (map cons '#,keys (list #,@args))))) - (lambda (world key-event) - ((hash-ref quasi-object key-event) world))) + #`(produce-handler '#,keys (list #,@args)) 'stepper-skip-completely #t) 'disappeared-use doms))])) +;; let ((quasi-object )) +;; +;; (define-higher-order-primitive the-handler the-handler* (world key-event)) +;; the-handler + +(define (produce-handler keys args) + (define quasi-object (make-immutable-hash (map cons keys args))) + (define (the-handler* world key-event) + ((hash-ref quasi-object key-event (lambda (w) w)) world)) + the-handler*) + (define (run-simulation f) (check-proc 'run-simulation f 1 "first" "one argument") (big-bang 0 (on-draw f) (on-tick add1))) From 6fa89d8081d624be12de1b52ca41573791dc6445 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 16 Jan 2012 16:21:25 -0500 Subject: [PATCH 497/746] fixing silly mistake, plus test; please merge (cherry picked from commit f173b9977c652826970e0650c20398ea93c56059) --- collects/2htdp/tests/pad1-in-bsl.rkt | 18 ++++++++++++ collects/2htdp/universe.rkt | 41 +++++++++++++++++----------- collects/2htdp/xtest | 2 ++ 3 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 collects/2htdp/tests/pad1-in-bsl.rkt diff --git a/collects/2htdp/tests/pad1-in-bsl.rkt b/collects/2htdp/tests/pad1-in-bsl.rkt new file mode 100644 index 0000000000..55d5950293 --- /dev/null +++ b/collects/2htdp/tests/pad1-in-bsl.rkt @@ -0,0 +1,18 @@ +;; The first three lines of this file were inserted by DrRacket. They record metadata +;; about the language level of this file in a form that our tools can easily process. +#reader(lib "htdp-beginner-reader.ss" "lang")((modname pad1-in-bsl) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) +;; must stay in BSL + +(require 2htdp/universe) +(require 2htdp/image) + +(define (render x) + (place-image (circle 3 'solid 'red) (+ 150 (real-part x)) (+ 150 (imag-part x)) (empty-scene 300 300))) + +(define (sub1-i x) (- x 0+i)) +(define (add1-i x) (+ x 0+i)) + +(big-bang 0+0i + (to-draw render) + (on-tick add1-i 1/28 50) + (on-pad (pad-handler (up sub1-i) (down add1-i) (left sub1) (right add1)))) \ No newline at end of file diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index 91c9b944f6..a4dada8b48 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -262,21 +262,23 @@ 'disappeared-use (map (lambda (x) (car (syntax->list x))) dom))]))])) (define-keywords Pad1Specs '() _init-not-needed - [up DEFAULT #'(lambda (x) x) (function-with-arity 1)] - [down DEFAULT #'(lambda (x) x) (function-with-arity 1)] - [left DEFAULT #'(lambda (x) x) (function-with-arity 1)] - [right DEFAULT #'(lambda (x) x) (function-with-arity 1)] - ; [space DEFAULT #'(lambda (x) x) (function-with-arity 1)] - #; - [shift DEFAULT #'(lambda (x) x) (function-with-arity 1)]) + [up DEFAULT #'#f (function-with-arity 1)] + [down DEFAULT #'#f (function-with-arity 1)] + [left DEFAULT #'#f (function-with-arity 1)] + [right DEFAULT #'#f (function-with-arity 1)] + [space DEFAULT #'#f (function-with-arity 1)] + [shift DEFAULT #'#f (function-with-arity 1)]) (define-syntax (pad-handler stx) (syntax-case stx () [(pad1 clause ...) (let* ([args (->args 'pad-one-player stx #'w #'(clause ...) Pad1Specs void)] + ; [_ (displayln args)] [keys (map (lambda (x) - (syntax-case x () [(proc> (quote s) _f _d) (symbol->string (syntax-e #'s))])) - args)] + (syntax-case x () + [(proc> (quote s) _f _d) (symbol->string (syntax-e #'s))] + [else "not present"])) + (filter values args))] [doms (map (lambda (x) (car (syntax->list x))) (syntax->list #'(clause ...)))]) (syntax-property (stepper-syntax-property @@ -284,15 +286,22 @@ 'stepper-skip-completely #t) 'disappeared-use doms))])) -;; let ((quasi-object )) -;; -;; (define-higher-order-primitive the-handler the-handler* (world key-event)) -;; the-handler - (define (produce-handler keys args) - (define quasi-object (make-immutable-hash (map cons keys args))) + (define (check k one other) + (or (and (string=? k one) (not (member other keys))) + (and (string=? k other) (not (member one keys))))) + (define quasi-methods + (for/fold ((m '())) ((k keys) (a args)) + (cond + [(check k "w" "up") (list* (cons "w" a) (cons "up" a) m)] + [(check k "s" "down") (list* (cons "s" a) (cons "down" a) m)] + [(check k "a" "left") (list* (cons "a" a) (cons "left" a) m)] + [(check k "d" "right") (list* (cons "d" a) (cons "right" a) m)] + [(check k "shift" "rshift") (list* (cons "shift" a) (cons "rshift" a) m)] + [else (cons (cons "space" a) m)]))) + (define quasi-object (make-immutable-hash quasi-methods)) (define (the-handler* world key-event) - ((hash-ref quasi-object key-event (lambda (w) w)) world)) + ((hash-ref quasi-object key-event (lambda () values)) world)) the-handler*) (define (run-simulation f) diff --git a/collects/2htdp/xtest b/collects/2htdp/xtest index ad6bcb1fec..f98d6e4019 100755 --- a/collects/2htdp/xtest +++ b/collects/2htdp/xtest @@ -41,3 +41,5 @@ run universe-receive.rkt run name.rkt run pad1.rkt run pad1-handler.rkt +run pad1-in-bsl.rkt + From 6bb782b8c931361df10dbb96d95687402f80c3d9 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 16 Jan 2012 06:09:30 -0700 Subject: [PATCH 498/746] macro-stepper: fix relative require bug (set current-directory) related to PR 12486 (cherry picked from commit f711f3385ccfd01182ac41cea0c4b0583f5cccb4) --- collects/macro-debugger/tool.rkt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/collects/macro-debugger/tool.rkt b/collects/macro-debugger/tool.rkt index 1d392adf3c..ca292e5256 100644 --- a/collects/macro-debugger/tool.rkt +++ b/collects/macro-debugger/tool.rkt @@ -13,7 +13,8 @@ images/compile-time (for-syntax racket/base images/icons/tool) ;; FIXME: - drracket/private/syncheck/local-member-names) + drracket/private/syncheck/local-member-names + drracket/private/eval-helpers) ;; Capability name: 'macro-stepper:enabled @@ -236,7 +237,7 @@ (current-module-name-resolver the-module-name-resolver) (send the-tab set-breakables (current-thread) (current-custodian)) - ;; (set-directory definitions-text) + (set-directory definitions-text) (current-load-relative-directory #f) (current-error-port error-port) (current-output-port output-port) @@ -336,6 +337,14 @@ #t))) (void)) + ;; set-directory : text -> void + ;; sets the current-directory based on the file saved in the definitions-text + (define/private (set-directory definitions-text) + (define tmp-b (box #f)) + (define fn (send definitions-text get-filename tmp-b)) + (define dir (get-init-dir (and (not (unbox tmp-b)) fn))) + (current-directory dir)) + ;; with-lock/edit-sequence : text (-> void) -> void ;; sets and restores some state of the definitions text ;; so that edits to the definitions text work out. From 6c0afeb19f7e4382709dccc971a288567cad371b Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Mon, 16 Jan 2012 15:41:26 -0700 Subject: [PATCH 499/746] Added docs for images/compile-time Added `is-a?' and `list?' tests to `compiled-bitmap' and `compiled-bitmap-list' Please merge into release (cherry picked from commit f45843d58ea4a2b66c735a8c4c287097fa5fa1d3) --- collects/images/compile-time.rkt | 17 ++++- .../images/scribblings/compile-time.scrbl | 72 ++++++++++++++++++- collects/images/scribblings/images.scrbl | 7 ++ 3 files changed, 92 insertions(+), 4 deletions(-) diff --git a/collects/images/compile-time.rkt b/collects/images/compile-time.rkt index 819f480ce7..d9857f3903 100644 --- a/collects/images/compile-time.rkt +++ b/collects/images/compile-time.rkt @@ -15,7 +15,14 @@ (define-syntax (compiled-bitmap stx) (syntax-case stx () [(_ expr) (syntax/loc stx - (let-syntax ([maker (λ (inner-stx) (make-3d-bitmap inner-stx expr))]) + (let-syntax ([maker (λ (inner-stx) + (define bm expr) + (unless (is-a? bm bitmap%) + (raise-syntax-error + 'compiled-bitmap + (format "expected argument of type ; given ~e" bm) + #'expr)) + (make-3d-bitmap inner-stx bm))]) (maker)))])) (define-syntax (compiled-bitmap-list stx) @@ -23,7 +30,13 @@ [(_ expr) (syntax/loc stx (let-syntax ([maker (λ (inner-stx) + (define bms expr) + (unless (and (list? bms) (andmap (λ (bm) (is-a? bm bitmap%)) bms)) + (raise-syntax-error + 'compiled-bitmap-list + (format "expected argument of type ; given ~e" bms) + #'expr)) (with-syntax ([(bm (... ...)) - (map (λ (e) (make-3d-bitmap inner-stx e)) expr)]) + (map (λ (e) (make-3d-bitmap inner-stx e)) bms)]) #'(list bm (... ...))))]) (maker)))])) diff --git a/collects/images/scribblings/compile-time.scrbl b/collects/images/scribblings/compile-time.scrbl index cc3c4dabb9..aa9f6dfac2 100644 --- a/collects/images/scribblings/compile-time.scrbl +++ b/collects/images/scribblings/compile-time.scrbl @@ -2,8 +2,13 @@ @(require scribble/eval (for-label images/compile-time - racket) - images/compile-time) + images/icons/control + images/icons/style + images/logos + racket racket/draw)) + +@(define ctime-eval (make-base-eval)) +@interaction-eval[#:eval ctime-eval (require (for-syntax racket/base))] @(define (author-email) "neil.toronto@gmail.com") @@ -11,3 +16,66 @@ @author{@(author+email "Neil Toronto" (author-email))} @defmodule[images/compile-time] + +Producing computed bitmaps can take time, especially those computed by the functions in the @racketmodname[images/icons] and @racketmodname[images/logos] collections. +To reduce the startup time of programs that use computed bitmaps, use the macros exported by @racketmodname[images/compile-time] to @italic{compile} them: to embed the computed bitmaps in fully expanded, compiled modules. + +@margin-note*{This is a form of constant folding, or equivalently a form of @italic{safe} ``3D'' values.} +The macros defined here compute bitmaps at expansion time, and expand to the bitmap's @racket[bytes] and a simple wrapper that converts @racket[bytes] to a @racket[bitmap%]. +Thus, fully expanded, compiled modules contain (more or less) literal bitmap values, which do not need to be computed again when the module is @racket[require]d by another. + +The literal bitmap values are encoded in @link["http://en.wikipedia.org/wiki/Portable_Network_Graphics"]{PNG} format, so they are compressed in the compiled module. + +To get the most from compiled bitmaps during development, it is best to put them in files that are changed infrequently. +For example, for games, we suggest having a separate module called something like @tt{images.rkt} or @tt{resources.rkt} that @racket[provide]s all the game's images. + +@defform[(compiled-bitmap expr)]{ +Evaluates @racket[expr] at expansion time, which must return a @racket[bitmap%], and returns to the bitmap at run time. +Keep in mind that @racket[expr] has access only to expansion-time values, not run-time values. + +Generally, to use this macro, wrap a @racket[bitmap%]-producing expression with it and move any identifiers it depends on into the expansion phase. +For example, suppose we are computing a large PLT logo at run time: +@codeblock|{#lang racket}| +@racketblock+eval[#:eval ctime-eval +(require images/logos) + +(define the-logo (plt-logo 384)) +] +Running this takes several seconds. It produces +@interaction[#:eval ctime-eval the-logo] + +To move the cost to expansion time, we change the program to +@codeblock|{ +#lang racket + +(require images/compile-time + (for-syntax images/logos)) + +(define the-logo (compiled-bitmap (plt-logo 384))) +}| +The logo is unchanged, but now @italic{expanding} (and thus compiling) the program takes several seconds, and running it takes a few milliseconds. +Note that @racketmodname[images/logos] is now required @racket[for-syntax], so that the expansion-phase expression @racket[(plt-logo 384)] +has access to the identifier @racket[plt-logo]. +} + +@defform[(compiled-bitmap-list expr)]{ +Like @racket[compiled-bitmap], but it expects @racket[expr] to return a @racket[list] of @racket[bitmap%]s, and it returns the list at run time. + +Use this for animations. For example, +@codeblock|{#lang racket}| +@racketblock+eval[#:eval ctime-eval +(require images/compile-time + (for-syntax images/icons/stickman)) + +(begin-for-syntax + (define num-stickman-frames 12)) + +(define running-stickman-frames + (compiled-bitmap-list + (for/list ([t (in-range 0 1 (/ 1 num-stickman-frames))]) + (running-stickman-icon t "red" "white" "red" 32)))) +] +This computes +@interaction[#:eval ctime-eval running-stickman-frames] +at expansion time. +} diff --git a/collects/images/scribblings/images.scrbl b/collects/images/scribblings/images.scrbl index ec8dfd4cb9..e6d7d89cd2 100644 --- a/collects/images/scribblings/images.scrbl +++ b/collects/images/scribblings/images.scrbl @@ -5,6 +5,13 @@ @title{Images} @author{@(author+email "Neil Toronto" (author-email))} +This library contains convenient functions for constructing icons and logos, and will eventually offer the same for other @racket[bitmap%]s. +The idea is to make it easy to include such things in your own programs. + +Generally, the images in this library are computed when requested, not loaded from disk. +Most of them are drawn on a @racket[dc<%>] and then @link["http://en.wikipedia.org/wiki/Ray_tracing_%28graphics%29"]{ray traced}. +This can become computationally expensive, so this library also includes @racketmodname[images/compile-time], which makes it easy to compute images at compile time and access them at run time. + @table-of-contents[] @include-section["icons.scrbl"] From 8f30c2ebf17aea672e5a27f1da0ac4da8e680475 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Mon, 16 Jan 2012 16:38:26 -0700 Subject: [PATCH 500/746] Exposed simple rendering API (can at least render simple icons given a pict now) Please merge into release (cherry picked from commit aa0851bc45d3a999314775df9744311a8dcfbc2c) --- collects/images/icons/style.rkt | 45 ++++++++++--------- .../images/scribblings/compile-time.scrbl | 2 +- collects/images/scribblings/icons.scrbl | 39 +++++++++++++++- 3 files changed, 63 insertions(+), 23 deletions(-) diff --git a/collects/images/icons/style.rkt b/collects/images/icons/style.rkt index 94312b185a..b1f5da12a7 100644 --- a/collects/images/icons/style.rkt +++ b/collects/images/icons/style.rkt @@ -14,10 +14,12 @@ plastic-icon-material glass-icon-material metal-icon-material + bitmap-render-icon (activate-contract-out default-icon-height toolbar-icon-height - default-icon-material) + default-icon-material + icon-color->outline-color) (only-doc-out (all-defined-out))) (defthing light-metal-icon-color (or/c string? (is-a?/c color%)) #:document-value @@ -64,6 +66,23 @@ (defparam default-icon-material deep-flomap-material-value? plastic-icon-material) +(defproc (bitmap-render-icon [bitmap (is-a?/c bitmap%)] + [z-ratio (and rational? (>=/c 0)) 5/8] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (let* ([fm (bitmap->flomap bitmap)] + [dfm (flomap->deep-flomap fm)] + [dfm (deep-flomap-icon-style dfm (* 32 z-ratio))]) + (flomap->bitmap (deep-flomap-render-icon dfm material)))) + +(defproc (icon-color->outline-color [color (or/c string? (is-a?/c color%))]) (is-a?/c color%) + (cond [(string? color) (icon-color->outline-color (send the-color-database find-color color))] + [else + (define r (send color red)) + (define g (send color green)) + (define b (send color blue)) + (make-object color% (quotient r 2) (quotient g 2) (quotient b 2))])) + ;; =================================================================================================== ;; Unpublished so far @@ -76,7 +95,6 @@ draw-short-rendered-icon-flomap define-icon-wrappers (activate-contract-out - icon-color->outline-color set-icon-pen)) (defproc (set-icon-pen [dc (is-a?/c dc<%>)] @@ -85,14 +103,6 @@ [style symbol?]) void? (send dc set-pen (make-object pen% color width style 'projecting 'miter))) -(defproc (icon-color->outline-color [color (or/c string? (is-a?/c color%))]) (is-a?/c color%) - (cond [(string? color) (icon-color->outline-color (send the-color-database find-color color))] - [else - (define r (send color red)) - (define g (send color green)) - (define b (send color blue)) - (make-object color% (quotient r 2) (quotient g 2) (quotient b 2))])) - (define icon-lighting (deep-flomap-lighting-value '(0.0 -1.0 1.0) @@ -106,11 +116,11 @@ [deep-flomap-lighting icon-lighting]) (deep-flomap-render dfm))) -(define (deep-flomap-icon-style dfm) +(define (deep-flomap-icon-style dfm [height 20]) (define s (/ (deep-flomap-height dfm) 32)) (let* ([dfm (deep-flomap-emboss dfm (* s 2) (* s 2))] [dfm (deep-flomap-bulge-round dfm (* s 6))] - [dfm (deep-flomap-raise dfm (* s 20))]) + [dfm (deep-flomap-raise dfm (* s height))]) dfm)) (define (draw-icon-flomap w h draw-proc scale) @@ -131,23 +141,16 @@ [fm (flomap-render-icon fm material)]) fm)) -;; TODO: make one of the following functions unnecessary - (define (flomap-render-thin-icon fm material) (define scale (/ (flomap-height fm) 32)) (define dfm (let* ([dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* -12 scale))]) + [dfm (deep-flomap-icon-style dfm 8)]) dfm)) (deep-flomap-render-icon dfm material)) (define (draw-short-rendered-icon-flomap w h proc scale material) - (let* ([fm (draw-icon-flomap w h proc scale)] - [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-icon-style dfm)] - [dfm (deep-flomap-raise dfm (* -12 (/ (flomap-height fm) 32)))]) - (deep-flomap-render-icon dfm material))) + (flomap-render-thin-icon (draw-icon-flomap w h proc scale) material)) ;; =================================================================================================== ;; Syntax for writing icon functions diff --git a/collects/images/scribblings/compile-time.scrbl b/collects/images/scribblings/compile-time.scrbl index aa9f6dfac2..aa9f96f9af 100644 --- a/collects/images/scribblings/compile-time.scrbl +++ b/collects/images/scribblings/compile-time.scrbl @@ -17,7 +17,7 @@ @defmodule[images/compile-time] -Producing computed bitmaps can take time, especially those computed by the functions in the @racketmodname[images/icons] and @racketmodname[images/logos] collections. +Producing computed bitmaps can take time. To reduce the startup time of programs that use computed bitmaps, use the macros exported by @racketmodname[images/compile-time] to @italic{compile} them: to embed the computed bitmaps in fully expanded, compiled modules. @margin-note*{This is a form of constant folding, or equivalently a form of @italic{safe} ``3D'' values.} diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl index 53396ec767..ee9c776dc7 100644 --- a/collects/images/scribblings/icons.scrbl +++ b/collects/images/scribblings/icons.scrbl @@ -158,7 +158,8 @@ This is because, while plastic and glass mostly reflect light directly, metal mo (for/list ([material (list plastic-icon-material glass-icon-material metal-icon-material)]) - (bomb-icon light-metal-icon-color dark-metal-icon-color 32 material))] + (bomb-icon light-metal-icon-color dark-metal-icon-color 32 + material))] } @doc-apply[default-icon-material]{ @@ -166,6 +167,42 @@ The material used for rendering most icons and icon parts. There are exceptions; for example, the @racket[floppy-disk-icon] always renders the sliding cover in metal. } +@doc-apply[bitmap-render-icon]{ +Makes a 3D object out of @racket[bitmap] and renders it as an icon. + +The @racket[z-ratio] argument only makes a difference when @racket[material] is transparent, such as @racket[glass-icon-material]. +It controls what fraction of @racket[bitmap]'s height the icon is raised, which in turn affects the refracted shadow under the icon: +the higher the @racket[z-ratio], the lower the shadow. + +@examples[#:eval icons-eval + (define bitmap + (pict->bitmap (colorize (filled-ellipse 64 64) "tomato"))) + (for/list ([z-ratio (in-range 0 2 1/3)]) + (bitmap-render-icon bitmap z-ratio glass-icon-material))] + +More complex shapes than ``embossed and rounded'' are possible with the full rendering API, which will be made public in a later release. +Still, most of the simple icons (such as those in @racketmodname[images/icons/arrow] and @racketmodname[images/icons/control]) can be rendered using only @racket[bitmap-render-icon]. +} + +@doc-apply[icon-color->outline-color]{ +For a given icon color, returns the proper outline @racket[color%]. + +As an example, here is how to duplicate the @racket[record-icon] using @racketmodname[slideshow/pict]: +@interaction[#:eval icons-eval + (define outline-color (icon-color->outline-color "forestgreen")) + (define brush-pict (colorize (filled-ellipse 62 62) "forestgreen")) + (define pen-pict (linewidth 2 (colorize (ellipse 62 62) outline-color))) + (bitmap-render-icon + (pict->bitmap + (inset (cc-superimpose brush-pict pen-pict) 1)) + 5/8 glass-icon-material) + + (record-icon "forestgreen" 64 glass-icon-material)] + +The outline width is usually @racket[(/ height 32)] (in this case, @racket[2]), but not always. +(For example, @racket[recycle-icon] is an exception, as are parts of @racket[floppy-disk-icon].) +} + @;==================================================================================================== @section[#:tag "arrows"]{Arrow Icons} From 060ab396a4aa6a5d42e768eeb13b2aec28274af4 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Mon, 16 Jan 2012 22:30:52 -0700 Subject: [PATCH 501/746] Added clock icon Fixed faulty bilinear interpolation in shadow intersection, removed blurring hack Fixed caching bug (for some reason, generate-temporaries didn't create a unique symbol - note, not *identifier*; used gensym instead) Please merge into release (cherry picked from commit 695583e90bfb3bb096653d9769d8bb60ae6d3f3f) --- collects/images/icons/misc.rkt | 82 ++++++++++++++++++- collects/images/icons/style.rkt | 4 +- .../images/private/deep-flomap-render.rkt | 56 ++----------- collects/images/private/utils.rkt | 3 +- collects/images/scribblings/icons.scrbl | 9 +- 5 files changed, 100 insertions(+), 54 deletions(-) diff --git a/collects/images/icons/misc.rkt b/collects/images/icons/misc.rkt index 39dbed334b..84345699b1 100644 --- a/collects/images/icons/misc.rkt +++ b/collects/images/icons/misc.rkt @@ -17,7 +17,8 @@ magnifying-glass-icon magnifying-glass-flomap left-magnifying-glass-icon left-magnifying-glass-flomap bomb-icon bomb-flomap - left-bomb-icon left-bomb-flomap) + left-bomb-icon left-bomb-flomap + clock-icon clock-flomap) (only-doc-out (all-defined-out))) (define (flat-regular-polygon-flomap sides start color size) @@ -251,6 +252,78 @@ ) flomap? (flomap-flip-horizontal (left-bomb-flomap cap-color bomb-color height material))) +;; =================================================================================================== +;; Clock + +(define clock-shell-material + (deep-flomap-material-value + 'glass 3.0 0.75 0.0 + 0.5 0.15 1.0 + 0.1 0.1 0.6 + 0.0)) + +(defproc (clock-flomap [height (and/c rational? (>=/c 0)) (default-icon-height)] + [face-color (or/c string? (is-a?/c color%)) light-metal-icon-color] + [hand-color (or/c string? (is-a?/c color%)) "firebrick"] + [hours (integer-in 0 11) 1] + [minutes (real-in 0 60) 33]) flomap? + (make-cached-flomap + [height face-color hand-color hours minutes] + (define R 12) + (define hour-θ (* (+ (- hours 3) (/ minutes 60)) (/ (* 2 pi) 12))) + (define minute-θ (* (- minutes 15) (/ (* 2 pi) 60))) + (define 60-degrees (* 60 (/ (* 2 pi) 180))) + (define scale (/ height 32)) + + (define face-fm + (draw-icon-flomap + 32 32 (λ (dc) + ;; face + (set-icon-pen dc (icon-color->outline-color face-color) 1 'solid) + (send dc set-brush face-color 'solid) + (draw-ellipse/smoothed dc 0 0 32 32) + ;; ticks + (set-icon-pen dc "black" 1 'solid) + (for ([θ (in-range 0 (* 2 pi) (* 1/6 pi))] + [i (in-cycle (in-range 0 3))]) + (define r (if (= i 0) 2 1)) + (send dc draw-line + (+ 15.5 (* (- R r) (cos θ))) + (+ 15.5 (* (- R r) (sin θ))) + (+ 15.5 (* R (cos θ))) + (+ 15.5 (* R (sin θ))))) + (set-icon-pen dc (icon-color->outline-color hand-color) 1/2 'solid) + (send dc set-brush hand-color 'solid) + ;; minute hand + (send dc draw-polygon + (list (cons (+ 15.5 (* R (cos minute-θ))) + (+ 15.5 (* R (sin minute-θ)))) + (cons (+ 15.5 (* 1.5 (cos (+ minute-θ 60-degrees)))) + (+ 15.5 (* 1.5 (sin (+ minute-θ 60-degrees))))) + (cons (+ 15.5 (* 1.5 (cos (- minute-θ 60-degrees)))) + (+ 15.5 (* 1.5 (sin (- minute-θ 60-degrees))))))) + ;; hour hand + (send dc draw-polygon + (list (cons (+ 15.5 (* (- R 4) (cos hour-θ))) + (+ 15.5 (* (- R 4) (sin hour-θ)))) + (cons (+ 15.5 (* 1.5 (cos (+ hour-θ 60-degrees)))) + (+ 15.5 (* 1.5 (sin (+ hour-θ 60-degrees))))) + (cons (+ 15.5 (* 1.5 (cos (- hour-θ 60-degrees)))) + (+ 15.5 (* 1.5 (sin (- hour-θ 60-degrees)))))))) + scale)) + + (define shell-fm + (draw-icon-flomap + 32 32 (λ (dc) + (set-icon-pen dc (icon-color->outline-color "white") 1 'solid) + (send dc set-brush "white" 'solid) + (draw-ellipse/smoothed dc 0 0 32 32)) + scale)) + + (let* ([dfm (flomap->deep-flomap shell-fm)] + [dfm (deep-flomap-bulge-spheroid dfm (* 8 scale))]) + (deep-flomap-render-icon dfm clock-shell-material face-fm)))) + ;; =================================================================================================== ;; Bitmaps (icons) @@ -262,6 +335,13 @@ ) (is-a?/c bitmap%) (flomap->bitmap (regular-polygon-flomap sides start color height material))) +(defproc (clock-icon [height (and/c rational? (>=/c 0)) (default-icon-height)] + [face-color (or/c string? (is-a?/c color%)) light-metal-icon-color] + [hand-color (or/c string? (is-a?/c color%)) "firebrick"] + [hours (integer-in 0 11) 1] + [minutes (real-in 0 60) 33]) (is-a?/c bitmap%) + (flomap->bitmap (clock-flomap height face-color hand-color hours minutes))) + (define-icon-wrappers ([color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0)) (default-icon-height)] diff --git a/collects/images/icons/style.rkt b/collects/images/icons/style.rkt index b1f5da12a7..cbacf5bb6b 100644 --- a/collects/images/icons/style.rkt +++ b/collects/images/icons/style.rkt @@ -110,11 +110,11 @@ '(1.0 1.0 1.0) '(1.0 1.0 1.0))) -(define (deep-flomap-render-icon dfm material) +(define (deep-flomap-render-icon dfm material [background-fm #f]) ;(printf "rendering~n") (parameterize/group ([deep-flomap-material material] [deep-flomap-lighting icon-lighting]) - (deep-flomap-render dfm))) + (deep-flomap-render dfm background-fm))) (define (deep-flomap-icon-style dfm [height 20]) (define s (/ (deep-flomap-height dfm) 32)) diff --git a/collects/images/private/deep-flomap-render.rkt b/collects/images/private/deep-flomap-render.rkt index bc88565271..6d6dd3ce15 100644 --- a/collects/images/private/deep-flomap-render.rkt +++ b/collects/images/private/deep-flomap-render.rkt @@ -13,7 +13,6 @@ ;; Hacks (define specular-blur 1/2) (define diffuse-blur 1/2) -(define ideal-transmission-blur 1) (define ambient-transmission-blur-fraction 1/32) ;; =================================================================================================== @@ -353,10 +352,6 @@ (define sin-wall-tilt-θ (sin wall-tilt-θ)) (match-define (list Irr Irg Irb) (reflected-intensity)) - ;; max coords of the shadow image - ;; subtract epsilon to ensure that sx < (w - 1) so that (flfloor sx) < (w - 1) (similarly for sy) - (define sx-max (- w 1.00001)) - (define sy-max (- h 1.00001)) ;; material properties (define η2 (refractive-index)) (define η1/η2 (/ 1.0 η2)) @@ -416,46 +411,13 @@ ;; sz = z + dist * tz, so dist = (sz - z) / tz (define dist (/ (- 0.0 z) tz)) (when (and (dist . >= . 0.0) (dist . < . +inf.0)) - ;; Find the color of the point on the shadow that the ray struck - (define sx (max 0.0 (min sx-max (+ x (* dist tx))))) - (define sy (max 0.0 (min sy-max (+ y (* dist ty))))) - (define floor-sx (floor sx)) - (define floor-sy (floor sy)) - (define bx (fl->fx floor-sx)) - (define by (fl->fx floor-sy)) - ;; Bilinearly interpolate the four colors nearest the point on the shadow - (define 1-αx (- sx floor-sx)) - (define 1-αy (- sy floor-sy)) - (define αx (- 1.0 1-αx)) - (define αy (- 1.0 1-αy)) - ;; upper-left weighted values - (define j1 (fx* 3 (fx+ bx (fx* by w)))) - (define r1 (unsafe-flvector-ref shadow-vs j1)) - (define g1 (unsafe-flvector-ref shadow-vs (fx+ j1 1))) - (define b1 (unsafe-flvector-ref shadow-vs (fx+ j1 2))) - (define-values (sr1 sg1 sb1) (fl3* r1 g1 b1 (* αx αy))) - ;; upper-right weighted values - (define j2 (fx+ j1 3)) - (define r2 (unsafe-flvector-ref shadow-vs j2)) - (define g2 (unsafe-flvector-ref shadow-vs (fx+ j2 1))) - (define b2 (unsafe-flvector-ref shadow-vs (fx+ j2 2))) - (define-values (sr2 sg2 sb2) (fl3* r2 g2 b2 (* 1-αx αy))) - ;; lower-left weighted values - (define j3 (fx+ j1 (fx* 3 w))) - (define r3 (unsafe-flvector-ref shadow-vs j3)) - (define g3 (unsafe-flvector-ref shadow-vs (fx+ j3 1))) - (define b3 (unsafe-flvector-ref shadow-vs (fx+ j3 2))) - (define-values (sr3 sg3 sb3) (fl3* r3 g3 b3 (* αx 1-αy))) - ;; lower-right weighted values - (define j4 (fx+ j3 3)) - (define r4 (unsafe-flvector-ref shadow-vs j4)) - (define g4 (unsafe-flvector-ref shadow-vs (fx+ j4 1))) - (define b4 (unsafe-flvector-ref shadow-vs (fx+ j4 2))) - (define-values (sr4 sg4 sb4) (fl3* r4 g4 b4 (* 1-αx 1-αy))) - ;; final interpolated shadow color - (define sr (+ sr1 sr2 sr3 sr4)) - (define sg (+ sg1 sg2 sg3 sg4)) - (define sb (+ sb1 sb2 sb3 sb4)) + ;; Shadow intersection point + (define sx (+ x (* dist tx))) + (define sy (+ y (* dist ty))) + ;; Shadow intersection color + (define sr (flomap-bilinear-ref shadow-fm 0 sx sy)) + (define sg (flomap-bilinear-ref shadow-fm 1 sx sy)) + (define sb (flomap-bilinear-ref shadow-fm 2 sx sy)) ;; normalized distance to the surface (define norm-dist (/ dist opacity-z)) ;; intensities of each r g b by the time the light emerges from the surface @@ -471,9 +433,7 @@ (unsafe-flvector-set! transmitted-vs (fx+ j 1) g) (unsafe-flvector-set! transmitted-vs (fx+ j 2) b)))))) - ;; blur to cut down on sparklies (poor man's supersampling) - (values reflected-fm - (flomap-blur transmitted-fm ideal-transmission-blur))) + (values reflected-fm transmitted-fm)) ;; =================================================================================================== ;; Full rendering diff --git a/collects/images/private/utils.rkt b/collects/images/private/utils.rkt index be90de5744..70b5f650f4 100644 --- a/collects/images/private/utils.rkt +++ b/collects/images/private/utils.rkt @@ -72,7 +72,8 @@ (define-syntax (make-cached-flomap stx) (syntax-case stx () [(_ (size args ...) expr0 expr ...) - (with-syntax ([(name) (generate-temporaries #'(make-cached-flomap))]) + ;; for some reason, generate-temporaries doesn't work here + (with-syntax ([name (gensym)]) (syntax/loc stx (make-cached-flomap* 'name (λ (size args ...) expr0 expr ...) size args ...)))])) diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl index ee9c776dc7..811fce839b 100644 --- a/collects/images/scribblings/icons.scrbl +++ b/collects/images/scribblings/icons.scrbl @@ -193,8 +193,7 @@ As an example, here is how to duplicate the @racket[record-icon] using @racketmo (define brush-pict (colorize (filled-ellipse 62 62) "forestgreen")) (define pen-pict (linewidth 2 (colorize (ellipse 62 62) outline-color))) (bitmap-render-icon - (pict->bitmap - (inset (cc-superimpose brush-pict pen-pict) 1)) + (pict->bitmap (inset (cc-superimpose brush-pict pen-pict) 1)) 5/8 glass-icon-material) (record-icon "forestgreen" 64 glass-icon-material)] @@ -387,6 +386,12 @@ Equivalent to @racket[(regular-polygon-icon 8 (/ (* 2 pi) 16) color height mater (left-bomb-icon metal-icon-color dark-metal-icon-color 32)] } +@doc-apply[clock-icon]{ +@examples[#:eval icons-eval + (clock-icon 48) + (clock-icon 48 "lightblue" "darkblue" 3 21)] +} + @;==================================================================================================== @section[#:tag "stickman"]{Stickman Icons} From 52e609ff6ab1795b690e73ef9f49187f3bbad65f Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 17 Jan 2012 09:25:57 -0500 Subject: [PATCH 502/746] Have a default "" platform so kauai can still be used to make the dmgs. (This is just a hack, $platform should really be used only in the build functions instead of at the toplevel.) (cherry picked from commit 52382442f0d1367994ea2d8e4fa137996df70c26) --- collects/meta/build/build | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index bde6d16d0a..840919248f 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -74,7 +74,7 @@ defbuild() { # entries, with misc fields set. Machines and platforms must be unique. The # "D" first entry is for default field values (missing default makes the field # required). Warning: an `eval "foo=\"bar\""' is used to assign values. -msets "/machines/D" "workdir=/var/tmp" "moveto=" "copytobak=" \ +msets "/machines/D" "platform=" "workdir=/var/tmp" "moveto=" "copytobak=" \ "configure_args=" "LDFLAGS=" "ext_lib_paths=" "renice=" \ "more_setup_args=" "test_gui=" # defbuild "ccs-solaris" "sparc-solaris" "moveto=/proj/racket" \ @@ -2205,9 +2205,11 @@ if [[ "$1" = "--dispatch" ]]; then init_repo_vars # set the repository variables according to the env vars machineget platform # set the global platform for dependable script pieces if [[ "${machine:-$workmachine}" != "$workmachine" ]]; then - machine_suffix=" [$machine($platform)]" + if [[ "$platform" = "" ]]; then machine_suffix=" [$machine]" + else machine_suffix=" [$machine($platform)]"; fi fi - show "Working on $machine($platform)" + if [[ "$platform" = "" ]]; then show "Working on $machine" + else show "Working on $machine($platform)"; fi show "Dispatching to $go($*)" "$go" "$@" show "Done working on $machine($platform)" From 8c59a3a79263d1aa76e6722dc1dff1172cdbecf8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 16 Jan 2012 07:29:50 -0700 Subject: [PATCH 503/746] add some missing acks Merge to 5.2.1 (cherry picked from commit 2c88b129136ed8bb4fc14d5548aaf9028a948251) --- collects/drracket/acks.rkt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collects/drracket/acks.rkt b/collects/drracket/acks.rkt index 0f8745383e..245468ef1e 100644 --- a/collects/drracket/acks.rkt +++ b/collects/drracket/acks.rkt @@ -36,6 +36,7 @@ "Dave Gurnell, " "Bruce Hauman, " "Dave Herman, " + "Blake Johnson, " "Geoffrey S. Knauth, " "Mark Krentel, " "Shriram Krishnamurthi, " @@ -62,6 +63,7 @@ "David Van Horn, " "Anton van Straaten, " "Kevin Tew, " + "Neil Toronto, " "Dale Vaillancourt, " "Dimitris Vyzovitis, " "Stephanie Weirich, " From 3f51e688e57cacd878e77e9d41e28ebc5a98a19e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 17 Jan 2012 07:21:01 -0700 Subject: [PATCH 504/746] fix JIT-generated code in case of arity mismatch The generated code was checking arity after potentially copying arguments to the start of the runstack (i.e., if the arguments were not already there). If too few arguments are provided, then the copy might access past the end of the given array. The redundant arity check removed in commit f7c506471b48dbae676 had previously masked this problem. (Or the check wasn't redundant in that sense, but it's better this way.) Merge to 5.2.1 (cherry picked from commit ddd246232ee9161ce26f0bf5191edb3caba0811f) --- collects/tests/racket/basic.rktl | 1 + src/racket/src/jit.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/collects/tests/racket/basic.rktl b/collects/tests/racket/basic.rktl index 630e3c5f55..e503e0a9c8 100644 --- a/collects/tests/racket/basic.rktl +++ b/collects/tests/racket/basic.rktl @@ -2072,6 +2072,7 @@ (test #t eq? (equal-hash-code l) (equal-hash-code (list 1 2 3))) (hash-set! h1 l 'ok) (test 'ok hash-ref h1 l) + (err/rt-test (hash-ref h1 'nonesuch (lambda (x) 'bad-proc)) exn:fail:contract:arity?) (test #t hash-has-key? h1 l) (test #f hash-has-key? h1 (cdr l)) (when hash-ref! diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index c72358f6cb..2d5f0fda66 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -2996,7 +2996,7 @@ static void generate_function_prolog(mz_jit_state *jitter, void *code, int max_l static int generate_function_getarg(mz_jit_state *jitter, int has_rest, int num_params) { int i, cnt; - GC_CAN_IGNORE jit_insn *ref; + GC_CAN_IGNORE jit_insn *ref, *ref2; /* If rands == runstack, set runstack base to runstack + rands (and don't copy rands), otherwise set base to runstack and copy @@ -3011,6 +3011,16 @@ static int generate_function_getarg(mz_jit_state *jitter, int has_rest, int num_ ref = jit_beqr_p(jit_forward(), JIT_RUNSTACK, JIT_R2); __END_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100); + /* Since we're going to copy arguments, make sure argument + count is right; otherwise, the arity error can use the + arguments in the original location. */ + __START_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100); + if (!has_rest) + ref2 = jit_bnei_i(jit_forward(), JIT_R1, num_params); + else + ref2 = jit_blti_i(jit_forward(), JIT_R1, (num_params - 1)); + __END_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100); + #ifdef JIT_RUNSTACK_BASE jit_movr_p(JIT_RUNSTACK_BASE, JIT_RUNSTACK); #else @@ -3036,6 +3046,7 @@ static int generate_function_getarg(mz_jit_state *jitter, int has_rest, int num_ __START_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100); mz_patch_branch(ref); + mz_patch_branch(ref2); __END_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100); return cnt; From ae525932dd1aea7233f59bb1ef376270a2b7351b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 17 Jan 2012 08:12:30 -0700 Subject: [PATCH 505/746] fix stack unsafety for rest-arg functions If a function with a rest arg is called with argv not at the start of the runstack, then space is allocated for the rest-arg list on the runstack without clearing the allocated slot. The value in the slot could be a pointer that wasn't traversed by the most recent GC, so it could crash a GC during allocation of the rest-arg list. Also, tweak setup code for a function of no arguments, and improve comments in the code. Merge to 5.2.1 (cherry picked from commit d85f251eb277d7c4e415364305ac8dfbbdc698cd) --- src/racket/src/jit.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index 2d5f0fda66..6d8063bb30 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -2998,6 +2998,27 @@ static int generate_function_getarg(mz_jit_state *jitter, int has_rest, int num_ int i, cnt; GC_CAN_IGNORE jit_insn *ref, *ref2; + /* Normalize the argument array by making sure that it's at the + start of the runstack, and set runstack base to be at the end of + the arguments. Rest arguments to be collected into a list remain + in their original location. Note that tail calls modify the + runstack below runstack base, which is why all parts of the + runteim system that call scheme_apply() with an arrayu of + arguments on the runstack must be prepared for that array to + change during the call. */ + + if (!num_params && !has_rest) { + /* No arguments, so simply set runstack base to runstack. If it + turns out that arguments are provided, then we'll abort through + an arity exception, anyway. */ +#ifdef JIT_RUNSTACK_BASE + jit_movr_p(JIT_RUNSTACK_BASE, JIT_RUNSTACK); +#else + mz_set_local_p(JIT_RUNSTACK, JIT_RUNSTACK_BASE_LOCAL); +#endif + return 1; + } + /* If rands == runstack, set runstack base to runstack + rands (and don't copy rands), otherwise set base to runstack and copy arguments at runstack. Implement the test by optimistically @@ -3033,8 +3054,10 @@ static int generate_function_getarg(mz_jit_state *jitter, int has_rest, int num_ CHECK_LIMIT(); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(cnt)); CHECK_RUNSTACK_OVERFLOW(); - if (has_rest) + if (has_rest) { --cnt; + scheme_stack_safety(jitter, 1, cnt); + } } /* Extract arguments to runstack: */ @@ -3117,10 +3140,10 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) } else arity_code = generate_lambda_simple_arity_check(num_params, has_rest, is_method, 0); - /* A tail call starts here. Caller must ensure that the - stack is big enough, right number of arguments, closure - is in R0. If the closure has a rest arg, also ensure - argc in R1 and argv in R2. */ + /* A tail call starts here. Caller must ensure that the stack is big + enough, right number of arguments (at start of runstack), closure + is in R0. If the closure has a rest arg, also ensure argc in R1 + and argv in R2. */ tail_code = jit_get_ip().ptr; /* 0 params and has_rest => (lambda args E) where args is not in E, @@ -3136,8 +3159,11 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) __START_SHORT_JUMPS__(cnt < 100); + /* check whether argv == runstack: */ ref = jit_bner_p(jit_forward(), JIT_RUNSTACK, JIT_R2); + /* check whether we have at least one rest arg: */ ref3 = jit_bgti_p(jit_forward(), JIT_R1, cnt); + /* yes and yes: make room for the copy */ jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(cnt+1)); CHECK_RUNSTACK_OVERFLOW(); for (i = cnt; i--; ) { @@ -3204,8 +3230,10 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) /* if we get here, the rest argument isn't used */ GC_CAN_IGNORE jit_insn *ref; __START_TINY_JUMPS__(1); + /* check whether argv == runstack: */ ref = jit_bner_p(jit_forward(), JIT_RUNSTACK, JIT_R2); __END_TINY_JUMPS__(1); + /* yes, so clear rest args (for space safety): */ mz_rs_sync(); JIT_UPDATE_THREAD_RSPTR(); CHECK_LIMIT(); From 0778bfad87c72e91601746e7440888c15ad4aa42 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 17 Jan 2012 11:40:33 -0500 Subject: [PATCH 506/746] New Racket version 5.2.0.901. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index c4f30ca2a5..6d14252e7c 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 0c61323393..e4677a5ca8 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,900 - PRODUCTVERSION 5,2,0,900 + FILEVERSION 5,2,0,901 + PRODUCTVERSION 5,2,0,901 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 2, 0, 900\0" + VALUE "FileVersion", "5, 2, 0, 901\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 0, 900\0" + VALUE "ProductVersion", "5, 2, 0, 901\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 5cc7691169..356e175975 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,900 - PRODUCTVERSION 5,2,0,900 + FILEVERSION 5,2,0,901 + PRODUCTVERSION 5,2,0,901 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 2, 0, 900" + VALUE "FileVersion", "5, 2, 0, 901" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2012 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 2, 0, 900" + VALUE "ProductVersion", "5, 2, 0, 901" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index c9f9a4ffb7..3f9f36b845 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.2.0.900 = s 'MzObj Class' + MzCOM.MzObj.5.2.0.901 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.2.0.900' + CurVer = s 'MzCOM.MzObj.5.2.0.901' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.2.0.900' + ProgID = s 'MzCOM.MzObj.5.2.0.901' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 117439e38d..5bbf6e4d5e 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 311915509b..63d0c276c4 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,900 - PRODUCTVERSION 5,2,0,900 + FILEVERSION 5,2,0,901 + PRODUCTVERSION 5,2,0,901 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 2, 0, 900\0" + VALUE "FileVersion", "5, 2, 0, 901\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 0, 900\0" + VALUE "ProductVersion", "5, 2, 0, 901\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 11ebb5035c..ce689a7f8c 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,900 - PRODUCTVERSION 5,2,0,900 + FILEVERSION 5,2,0,901 + PRODUCTVERSION 5,2,0,901 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 2, 0, 900\0" + VALUE "FileVersion", "5, 2, 0, 901\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 0, 900\0" + VALUE "ProductVersion", "5, 2, 0, 901\0" END END BLOCK "VarFileInfo" From 5f17c515377747df19f4831a7fb9742d3e66047b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 17 Jan 2012 16:01:40 -0700 Subject: [PATCH 507/746] Mac OS X: work around a localtime() bug in 64-bit 10.6.8 For numbers around -67768122973228093, localtime() doesn't return in 10.6.8, while it returns NULL for 10.7.2. Work around the bug by setting a lower bound that seems to be high enough to avoid the problem (and that's lower than the lowest value that succeeds, so no results are lost, at least for now). Merge to 5.2.1 (cherry picked from commit 4e4c40ae8c1e0640412a85beea0b0cbc871752a9) --- src/racket/sconfig.h | 7 +++++++ src/racket/src/fun.c | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/racket/sconfig.h b/src/racket/sconfig.h index fc2a524c35..e101001619 100644 --- a/src/racket/sconfig.h +++ b/src/racket/sconfig.h @@ -766,6 +766,11 @@ #endif # define MZ_JIT_USE_MPROTECT +#if defined(__x86_64__) +/* work around a bug in localtime() in 10.6.8 */ +# define MIN_VALID_DATE_SECONDS -67768122973193999 +#endif + # define FLAGS_ALREADY_SET #endif @@ -1026,6 +1031,8 @@ /* TIME_TYPE_IS_UNSIGNED converts time_t values as unsigned. */ + /* MIN_VALID_DATE_SECONDS sets a minimum vald time in seconds. */ + /* PROCESS_FUNCTION adds (process ...) and (system ...) functions */ /* DIR_FUNCTION adds (current-directory ...) function */ diff --git a/src/racket/src/fun.c b/src/racket/src/fun.c index 4c15dd1ba1..12991cbe3d 100644 --- a/src/racket/src/fun.c +++ b/src/racket/src/fun.c @@ -8315,6 +8315,12 @@ static int month_offsets[12] = { 0, 31, 59, 90, 243, 273, 304, 334 }; #endif +#ifdef MIN_VALID_DATE_SECONDS +# define VALID_TIME_RANGE(x) ((x) >= MIN_VALID_DATE_SECONDS) +#else +# define VALID_TIME_RANGE(x) 1 +#endif + static Scheme_Object *seconds_to_date(int argc, Scheme_Object **argv) { UNBUNDLE_TIME_TYPE lnow; @@ -8366,7 +8372,8 @@ static Scheme_Object *seconds_to_date(int argc, Scheme_Object **argv) } if (scheme_get_time_val(secs, &lnow) - && ((UNBUNDLE_TIME_TYPE)(now = (CHECK_TIME_T)lnow)) == lnow) { + && (((UNBUNDLE_TIME_TYPE)(now = (CHECK_TIME_T)lnow)) == lnow) + && VALID_TIME_RANGE(lnow)) { int success; #ifdef USE_MACTIME From e409e918991e6d447152d025d2f3f579683ea352 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 17 Jan 2012 21:00:11 -0700 Subject: [PATCH 508/746] win64: fix `raco dist' Merge to 5.2.1 (cherry picked from commit b51b36869ed2807e34ea7cff70f7a5ca72ee5c94) --- collects/compiler/distribute.rkt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/collects/compiler/distribute.rkt b/collects/compiler/distribute.rkt index 62c66bf028..1a021032c0 100644 --- a/collects/compiler/distribute.rkt +++ b/collects/compiler/distribute.rkt @@ -147,7 +147,10 @@ (if (file-exists? f) (format template filename-version-part) (format template "xxxxxxx"))))]) - (map copy-dll '("iconv.dll")) + (map copy-dll (list + (if (equal? "win32\\x86_64" (path->string (system-library-subpath #f))) + "libiconv-2.dll" + "iconv.dll"))) (when (or (memq 'racketcgc types) (memq 'gracketcgc types)) (map copy-dll From 55a22c0891c45e4f04b7dd6e6a63dad70d689967 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 17 Jan 2012 21:40:14 -0600 Subject: [PATCH 509/746] DrRacket & Redex history updates for 5.2.1 Please merge to the release branch (cherry picked from commit 50dba410437b874122cab91076a7fb16b932ac47) --- doc/release-notes/drracket/HISTORY.txt | 6 +++--- doc/release-notes/redex/HISTORY.txt | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/release-notes/drracket/HISTORY.txt b/doc/release-notes/drracket/HISTORY.txt index 4cc27edf27..958d573552 100644 --- a/doc/release-notes/drracket/HISTORY.txt +++ b/doc/release-notes/drracket/HISTORY.txt @@ -2,6 +2,9 @@ Version 5.2.1 ------------------------------ + . The keybindings window is no longer a modal dialog (and its contents + will change to reflect where the keyboard focus currently is) + . The initial current-directory for unsaved programs in DrRacket is now the user's home directory, instead of whatever the current-directory was for the underlying OS process. @@ -11,9 +14,6 @@ . DrRacket no longer shows a stacktrace for syntax errors in the REPL. - . The keybindings window is no longer a modal dialog (and its contents - will change to reflect where the keyboard focus currently is) - . The preference that makes a single "(" keystroke insert "()" (and similarly for [ { " and |) now only takes effect in Racket mode, instead of taking effect in all of the modes, as it used to. This diff --git a/doc/release-notes/redex/HISTORY.txt b/doc/release-notes/redex/HISTORY.txt index d82df8123f..7475624241 100644 --- a/doc/release-notes/redex/HISTORY.txt +++ b/doc/release-notes/redex/HISTORY.txt @@ -12,7 +12,8 @@ v5.2.1 lambdaJS benchmark by about a factor of 25. * added support for side-conditions and where clauses to - define-relation + define-relation, also added support for side-conditions to + define-judgment-form * added the List-machine benchmark (by Appel, Dockins & Leroy) From 4808c7e18981ac6530934777444ef866b4494400 Mon Sep 17 00:00:00 2001 From: John Clements Date: Wed, 18 Jan 2012 13:08:16 -0800 Subject: [PATCH 510/746] put status bar update on stepper frame eventspace (cherry picked from commit 758523bdf36eebc38b9fc6112e80127576ccae26) --- collects/stepper/private/view-controller.rkt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/collects/stepper/private/view-controller.rkt b/collects/stepper/private/view-controller.rkt index 4b1cde3d7c..c7da560121 100644 --- a/collects/stepper/private/view-controller.rkt +++ b/collects/stepper/private/view-controller.rkt @@ -79,19 +79,20 @@ (define view #f) ;; wait for steps to show up on the channel. When they do, add them to the list. - (define (start-listener-thread) + (define (start-listener-thread stepper-frame-eventspace) (thread (lambda () (let loop () (define new-result (async-channel-get view-channel)) (define new-step (format-result new-result)) - (queue-callback - (lambda () - (set! view-history (append view-history (list new-step))) - (set! num-steps-available (length view-history)) - ;; this is only necessary the first time, but it's cheap: - (semaphore-post first-step-sema) - (update-status-bar))) + (parameterize ([current-eventspace stepper-frame-eventspace]) + (queue-callback + (lambda () + (set! view-history (append view-history (list new-step))) + (set! num-steps-available (length view-history)) + ;; this is only necessary the first time, but it's cheap: + (semaphore-post first-step-sema) + (update-status-bar)))) (loop))))) @@ -375,7 +376,7 @@ (send (send s-frame edit-menu:get-redo-item) enable #f) ;; START THE MODEL - (start-listener-thread) + (start-listener-thread (send s-frame get-eventspace)) (model:go program-expander-prime ;; what do do with the results: From 9ab43903c83961567dedf83fd888fe9be03ee770 Mon Sep 17 00:00:00 2001 From: John Clements Date: Wed, 18 Jan 2012 14:51:34 -0800 Subject: [PATCH 511/746] make sure initial update goes on eventspace thread (cherry picked from commit 481bc2f00fca5f10d3fbaa25604aecb77f1f6207) --- collects/stepper/private/view-controller.rkt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/collects/stepper/private/view-controller.rkt b/collects/stepper/private/view-controller.rkt index c7da560121..996ece769f 100644 --- a/collects/stepper/private/view-controller.rkt +++ b/collects/stepper/private/view-controller.rkt @@ -375,8 +375,9 @@ (send (send s-frame edit-menu:get-undo-item) enable #f) (send (send s-frame edit-menu:get-redo-item) enable #f) + (define stepper-frame-eventspace (send s-frame get-eventspace)) ;; START THE MODEL - (start-listener-thread (send s-frame get-eventspace)) + (start-listener-thread stepper-frame-eventspace) (model:go program-expander-prime ;; what do do with the results: @@ -393,8 +394,12 @@ (thread (lambda () (semaphore-wait first-step-sema) - (jump-to-beginning) - (enable-all-buttons))) + (parameterize + ([current-eventspace stepper-frame-eventspace]) + (queue-callback + (lambda () + (jump-to-beginning) + (enable-all-buttons)))))) s-frame) From 2310d525b45889f15895e7876e2f8548c5ac7965 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Thu, 19 Jan 2012 11:38:37 -0500 Subject: [PATCH 512/746] fixed an old wheel-event bug and added version number to history, please propagate (cherry picked from commit 0a5a949d1ae1e31650b2d84f07b336b1738fe546) --- collects/2htdp/universe.rkt | 5 ++++- collects/teachpack/2htdp/scribblings/universe.scrbl | 2 ++ doc/release-notes/teachpack/HISTORY.txt | 6 ++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index a4dada8b48..38b6910261 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -234,7 +234,10 @@ "numlock" "scroll" "wheel-up" - "wheel-down")) + "wheel-down" + "wheel-left" + "wheel-right" + )) (define-syntax (big-bang stx) (define world0 "expects an expression for the initial world and at least one clause") diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index 3b085b65be..5c3991acf9 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -358,6 +358,8 @@ Second, some keys have multiple-character string representations. Strings @item{@racket["scroll"]} @item{@racket["wheel-up"]} @item{@racket["wheel-down"]} +@item{@racket["wheel-left"]} +@item{@racket["wheel-right"]} ] @defproc[(key-event? [x any]) boolean?]{ diff --git a/doc/release-notes/teachpack/HISTORY.txt b/doc/release-notes/teachpack/HISTORY.txt index 901d51979c..6f480b0057 100644 --- a/doc/release-notes/teachpack/HISTORY.txt +++ b/doc/release-notes/teachpack/HISTORY.txt @@ -1,10 +1,12 @@ ------------------------------------------------------------------------ +Version 5.2.1 [Thu Jan 19 11:36:19 EST 2012] * added: universe.rkt now comes with a game-pad simulation option - A game-pad is a special-purpose key handler plus an icon that maps out - the legal key strokes. + A game-pad is a special-purpose key handler plus an icon that + maps out the legal key strokes. * fixed + -- wheel-left and wheel-right events work properly as key events now -- on-receive doesn't have to exist for universe/world interactions -- name clause accepts strings and symbols -- doc typos From c2d59b16e9cf609beabb40ee65c02f17cc9acb70 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 18 Jan 2012 14:14:55 -0500 Subject: [PATCH 513/746] Adjust the installer tests to the removal of libfit. (cherry picked from commit fb46b12836687d91a294fc8610fe590f8d82926c) --- collects/meta/build/unix-installer/test-installer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/meta/build/unix-installer/test-installer b/collects/meta/build/unix-installer/test-installer index 4ec65c7c9a..37c651b901 100755 --- a/collects/meta/build/unix-installer/test-installer +++ b/collects/meta/build/unix-installer/test-installer @@ -316,7 +316,7 @@ exec racket "$0" "$@" schemegc2.h, schemex.h, schemexm.h, schexn.h, schgc2obj.h, schthread.h, schvers.h, sconfig.h, stypes.h, uconfig.h sh> @i{LS lib/r*} - buildinfo, collects/, libfit.so*, mzdyn3m.o, starter* + buildinfo, collects/, mzdyn3m.o, starter* sh> @i{LS share/r* && LS share/r*/doc} doc/ README, @... xrepl/ From 15f36f18734d93108382ae30a604ae5afe581259 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 19 Jan 2012 13:19:32 -0600 Subject: [PATCH 514/746] fix a bug in check syntax where it would attempt to (as part of the coloring for blame assignment in check syntax) try to color the right-hand side of a binding that actually comes from a lambda-bound variable (and thus crash for not finding the right-hand side) (cherry picked from commit c9e4c88b7ca694b48f0c10007a71fefc2afd3452) --- .../private/syncheck/contract-traversal.rkt | 4 +-- collects/tests/drracket/syncheck-test.rkt | 25 ++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/collects/drracket/private/syncheck/contract-traversal.rkt b/collects/drracket/private/syncheck/contract-traversal.rkt index 34e8bee9e0..13b6a4e462 100644 --- a/collects/drracket/private/syncheck/contract-traversal.rkt +++ b/collects/drracket/private/syncheck/contract-traversal.rkt @@ -122,9 +122,9 @@ (if binders (begin (base-color #'id polarity boundary-contract? my-coloring-plans client-coloring-plans) - (for ((binder (in-list (module-identifier-mapping-get low-binders #'id)))) + (for ((binder (in-list binders))) (base-color binder polarity boundary-contract? my-coloring-plans client-coloring-plans) - (for ((rhs (in-list (module-identifier-mapping-get binding-inits binder)))) + (for ((rhs (in-list (module-identifier-mapping-get binding-inits binder (λ () '()))))) (ploop rhs polarity)))) (call-give-up))))] [const diff --git a/collects/tests/drracket/syncheck-test.rkt b/collects/tests/drracket/syncheck-test.rkt index 3ba8ae0eeb..e821d1f4b8 100644 --- a/collects/tests/drracket/syncheck-test.rkt +++ b/collects/tests/drracket/syncheck-test.rkt @@ -373,7 +373,6 @@ trigger runtime errors in check syntax. (list '((10 18) (20 38) (51 64)) '((39 48) (68 71)))) - (build-test "(define-for-syntax (f x) x) (define (f x) x) f (define-syntax (m x) (f x))" '(("(" default-color) ("define-for-syntax" imported) @@ -901,6 +900,30 @@ trigger runtime errors in check syntax. '((52 58) (93 99)) '((100 101) (105 106)))) + (build-test "#lang racket (provide (contract-out [f (->i ((p? any/c)) (_ (p?) p?))])) (define (f a) 1)" + '(("#lang racket (" default-color) + ("provide" imported) + (" (contract-out [" default-color) + ("f" lexically-bound) + (" (" default-color) + ("->i" imported) + (" ((p? " default-color) + ("any/c" imported) + (")) (_ (" default-color) + ("p?" lexically-bound) + (") " default-color) + ("p?" lexically-bound) + ("))])) (" default-color) + ("define" imported) + (" (" default-color) + ("f" lexically-bound) + (" " default-color) + ("a" lexically-bound) + (") 1)" default-color)) + (list '((82 83) (37 38)) + '((61 63) (65 67)) + '((6 12) (14 21) (40 43) (49 54) (74 80)))) + (rename-test "(lambda (x) x)" 9 "x" From 87254941f5d1a636b4a43f6b1f2b8c622a0437bd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jan 2012 07:31:42 -0700 Subject: [PATCH 515/746] fix `raco make -j' Closes PR 12491 Merge to 5.2.1 (cherry picked from commit 350d0b1edf76acc33e94e3d37bdb51abe2586617) --- collects/setup/parallel-build.rkt | 2 +- collects/tests/racket/parallel-build.rkt | 32 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 collects/tests/racket/parallel-build.rkt diff --git a/collects/setup/parallel-build.rkt b/collects/setup/parallel-build.rkt index 5e30d7f586..460fa35b0a 100644 --- a/collects/setup/parallel-build.rkt +++ b/collects/setup/parallel-build.rkt @@ -198,7 +198,7 @@ [(cons hd tail) (define-values (dir file b) (split-path hd)) (set! filelist tail) - (values hd (list (->bytes hd) (->bytes dir) (->bytes file)))] + (values hd (list (->bytes hd) (->bytes dir) (->bytes file) null))] [(list) null])) (define/public (has-jobs?) (not (null? filelist))) (define/public (jobs-cnt) (length filelist)) diff --git a/collects/tests/racket/parallel-build.rkt b/collects/tests/racket/parallel-build.rkt new file mode 100644 index 0000000000..c5305ee76b --- /dev/null +++ b/collects/tests/racket/parallel-build.rkt @@ -0,0 +1,32 @@ +#lang racket +(require setup/parallel-build) + +(define tmp1 (make-temporary-file)) +(define tmp2 (make-temporary-file)) + +(define (mk file) + (with-output-to-file file + #:exists 'truncate + (lambda () + (printf "#lang racket/base\n")))) + +(mk tmp1) +(mk tmp2) + +(parallel-compile-files + (list tmp1 tmp2) + #:worker-count 2 + #:handler (lambda (type work msg out err) + (match type + ['done (printf " Made ~a\n" work)] + ['output (printf " Output from: ~a\n~a~a" work out err)] + [else (eprintf " Error compiling ~a\n~a\n~a~a" work msg out err)]))) + +(define (delete-files f) + (delete-file f) + (let-values ([(base name dir?) (split-path f)]) + (delete-file (build-path base "compiled" (path-add-suffix name #".dep"))) + (delete-file (build-path base "compiled" (path-add-suffix name #".zo"))))) + +(delete-files tmp1) +(delete-files tmp2) From fd8230152d84525e673fe0ce72205705aeb8efc4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jan 2012 07:53:45 -0700 Subject: [PATCH 516/746] fix `raco ctool --c-mods' for `racket' Merge to 5.2.1 (cherry picked from commit 6c4cd0e9c249b502827398f597dd49b2f4ac8df6) --- collects/compiler/embed-unit.rkt | 11 +++++++---- collects/tests/racket/ctool.rkt | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 collects/tests/racket/ctool.rkt diff --git a/collects/compiler/embed-unit.rkt b/collects/compiler/embed-unit.rkt index eb4d7952d1..315ea20fd1 100644 --- a/collects/compiler/embed-unit.rkt +++ b/collects/compiler/embed-unit.rkt @@ -800,7 +800,10 @@ (define (do-write-module-bundle outp verbose? modules config? literal-files literal-expressions collects-dest on-extension program-name compiler expand-namespace src-filter get-extra-imports on-decls-done) - (let* ([module-paths (map cadr modules)] + (let* ([program-name-bytes (if program-name + (path->bytes program-name) + #"?")] + [module-paths (map cadr modules)] [resolve-one-path (lambda (mp) (let ([f (resolve-module-path mp #f)]) (unless f @@ -882,7 +885,7 @@ ;; The program name isn't used. It just helps ensures that ;; there's plenty of room in the executable for patching ;; the path later when making a distribution. - (path->bytes program-name)))) + program-name-bytes))) extensions))]) (for-each (lambda (pr) (current-module-declare-name (make-resolved-module-path (cadr pr))) @@ -970,7 +973,7 @@ (build-path (path-only (mod-file nc)) p)))))) ;; As for the extension table, a placeholder to save ;; room likely needed by the distribution-mangler - (bytes-append #"................." (path->bytes program-name)))) + (bytes-append #"................." program-name-bytes))) (mod-runtime-paths nc) (mod-runtime-module-syms nc))) runtimes))]) @@ -1031,7 +1034,7 @@ (do-write-module-bundle (current-output-port) verbose? modules config? literal-files literal-expressions #f ; collects-dest on-extension - "?" ; program-name + #f ; program-name compiler expand-namespace src-filter get-extra-imports void)) diff --git a/collects/tests/racket/ctool.rkt b/collects/tests/racket/ctool.rkt new file mode 100644 index 0000000000..32c2e36907 --- /dev/null +++ b/collects/tests/racket/ctool.rkt @@ -0,0 +1,19 @@ +#lang racket +(require setup/dirs) + +(define raco (build-path (find-console-bin-dir) + (if (eq? (system-type) 'windows) + "raco.exe" + "raco"))) + +(define tmp (make-temporary-file)) + +(system* raco + "ctool" + "--3m" + "--c-mods" + tmp + "++lib" + "racket") + +(delete-file tmp) From c59a7bd8b2b77b9b97deadd52642d93c6d486cbe Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jan 2012 12:33:59 -0700 Subject: [PATCH 517/746] fix position counting in `read-byte' Merge to 5.2.1 (cherry picked from commit c723aeeb6a772fc20b4a89095018459c1a123fc4) --- collects/tests/racket/port.rktl | 21 +++++++++++++++++++++ src/racket/src/port.c | 9 +++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/collects/tests/racket/port.rktl b/collects/tests/racket/port.rktl index 79be4433c6..62a9420545 100644 --- a/collects/tests/racket/port.rktl +++ b/collects/tests/racket/port.rktl @@ -717,6 +717,27 @@ (test t2 sync t2) (test oc sync/timeout 0 oc)) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; eof should not advance port position + +(let () + (define (check read-byte) + (define-values (i o) (make-pipe)) + (test 0 file-position i) + (write-byte 10 o) + (close-output-port o) + (test 0 file-position i) + (test 10 read-byte i) + (test 1 file-position i) + (test eof read-byte i) + (test 1 file-position i)) + (check read-byte) + (check (lambda (i) + (define c (read-char i)) + (if (char? c) + (char->integer c) + c)))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/src/racket/src/port.c b/src/racket/src/port.c index a26f044393..72aa99f971 100644 --- a/src/racket/src/port.c +++ b/src/racket/src/port.c @@ -3201,10 +3201,11 @@ static MZ_INLINE intptr_t get_one_byte(GC_CAN_IGNORE const char *who, if (v == SCHEME_SPECIAL) { scheme_bad_time_for_special(who, port); } - - ip = (Scheme_Input_Port *)port; /* since ignored by GC */ - if (ip->p.position >= 0) - ip->p.position++; + if (v != EOF) { + ip = (Scheme_Input_Port *)port; /* since `ip is ignored by GC */ + if (ip->p.position >= 0) + ip->p.position++; + } return v; } From 719139313abbd2f8cc1c552dcbb60f3fb38bbbfb Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jan 2012 13:12:38 -0700 Subject: [PATCH 518/746] adjust `raco ctool --c-mods' and related to work with places That is, the generated declare_modules() function registers the module-declaration code so that it is run in any new place, too. Merge to 5.2.1 (cherry picked from commit 481e0614401ec0b3269a4e258cd9966de7775dce) --- collects/compiler/commands/ctool.rkt | 14 +--- collects/compiler/zo-parse.rkt | 2 +- collects/tests/racket/embed-in-c.c | 34 +++++++++- collects/tests/racket/embed-in-c.rkt | 92 ++++++++++++++++----------- collects/tests/racket/embed-place.rkt | 7 ++ src/racket/cmdline.inc | 6 +- src/racket/include/scheme.h | 4 +- src/racket/src/eval.c | 21 ++++-- src/racket/src/place.c | 6 +- 9 files changed, 123 insertions(+), 63 deletions(-) create mode 100644 collects/tests/racket/embed-place.rkt diff --git a/collects/compiler/commands/ctool.rkt b/collects/compiler/commands/ctool.rkt index df49d2922b..1e962fae63 100644 --- a/collects/compiler/commands/ctool.rkt +++ b/collects/compiler/commands/ctool.rkt @@ -291,18 +291,10 @@ (when (zero? (modulo pos 20)) (fprintf out "\n ")) (unless (eof-object? b) (fprintf out "~a," b) (loop (add1 pos))))) (fprintf out "0\n };\n") - (fprintf out " Scheme_Object *eload = NULL, *a[3] = {NULL, NULL, NULL};\n") - (fprintf out " MZ_GC_DECL_REG(4);\n") - (fprintf out " MZ_GC_VAR_IN_REG(0, eload);\n") - (fprintf out " MZ_GC_ARRAY_VAR_IN_REG(1, a, 3);\n") - (fprintf out " MZ_GC_REG();\n") - (fprintf out " eload = scheme_builtin_value(\"embedded-load\");\n") - (fprintf out " a[0] = scheme_false;\n") - (fprintf out " a[1] = scheme_false;\n") - (fprintf out " a[2] = scheme_make_sized_byte_string((char *)data, ~a, 0);\n" + (fprintf out " scheme_register_embedded_load(~a, (const char *)data);\n" + (file-position in)) + (fprintf out " scheme_embedded_load(~a, (const char *)data, 1);\n" (file-position in)) - (fprintf out " scheme_apply(eload, 3, a);\n") - (fprintf out " MZ_GC_UNREG();\n") (fprintf out "}\n") (fprintf out "#ifdef MZ_XFORM\n") (fprintf out "XFORM_END_SKIP;\n") diff --git a/collects/compiler/zo-parse.rkt b/collects/compiler/zo-parse.rkt index 0f8ecde12e..9a61c7f2af 100644 --- a/collects/compiler/zo-parse.rkt +++ b/collects/compiler/zo-parse.rkt @@ -1061,7 +1061,7 @@ (define rst-start (file-position port)) (file-position port (+ rst-start size*)) - + (unless (eof-object? (read-byte port)) (error 'zo-parse "File too big")) diff --git a/collects/tests/racket/embed-in-c.c b/collects/tests/racket/embed-in-c.c index a65ba8bae9..b98571a845 100644 --- a/collects/tests/racket/embed-in-c.c +++ b/collects/tests/racket/embed-in-c.c @@ -1,24 +1,33 @@ #include "scheme.h" +#ifdef USE_DECLARED_MODULE +# include "embed-base.c" +#endif + static int run(Scheme_Env *e, int argc, char *argv[]) { - Scheme_Object *curout = NULL, *v = NULL, *a[2] = {NULL, NULL}; + Scheme_Object *curout = NULL, *v = NULL, *pl = NULL, *a[2] = {NULL, NULL}; Scheme_Config *config = NULL; int i; mz_jmp_buf * volatile save = NULL, fresh; - MZ_GC_DECL_REG(8); + MZ_GC_DECL_REG(9); MZ_GC_VAR_IN_REG(0, e); MZ_GC_VAR_IN_REG(1, curout); MZ_GC_VAR_IN_REG(2, save); MZ_GC_VAR_IN_REG(3, config); MZ_GC_VAR_IN_REG(4, v); MZ_GC_ARRAY_VAR_IN_REG(5, a, 2); + MZ_GC_VAR_IN_REG(8, pl); MZ_GC_REG(); +#ifdef USE_DECLARED_MODULE + declare_modules(e); +#else scheme_set_collects_path(scheme_make_path(MZ_COLLECTION_PATH)); scheme_init_collection_paths(e, scheme_null); +#endif v = scheme_intern_symbol("racket/base"); scheme_namespace_require(v); @@ -40,9 +49,30 @@ static int run(Scheme_Env *e, int argc, char *argv[]) } } + /* Try in a place: */ + a[0] = scheme_intern_symbol("racket/place"); + a[1] = scheme_intern_symbol("dynamic-place"); + v = scheme_dynamic_require(2, a); + a[0] = scheme_intern_symbol("tests/racket/embed-place"); + a[1] = scheme_intern_symbol("go"); + pl = scheme_apply(v, 2, a); + a[0] = scheme_intern_symbol("racket/place"); + a[1] = scheme_intern_symbol("place-channel-get"); + v = scheme_dynamic_require(2, a); + a[0] = pl; + v = scheme_apply(v, 1, a); + if (v != scheme_make_integer(42)) { + printf("place failed\n"); + return 1; + } + /* RESET: */ e = scheme_basic_env(); +#ifdef USE_DECLARED_MODULE + declare_modules(e); +#else scheme_init_collection_paths(e, scheme_null); +#endif v = scheme_intern_symbol("racket/base"); scheme_namespace_require(v); diff --git a/collects/tests/racket/embed-in-c.rkt b/collects/tests/racket/embed-in-c.rkt index 7af37c63e8..7d3d037419 100644 --- a/collects/tests/racket/embed-in-c.rkt +++ b/collects/tests/racket/embed-in-c.rkt @@ -24,43 +24,63 @@ (and m (cadr m)))) "")) -(parameterize ([current-directory dir]) - (unless (system (format "cc -c -o embed-in-c.o -DMZ_COLLECTION_PATH='\"~a\"' -I\"~a\" -DMZ_PRECISE_GC ~a embed-in-c.c" - (find-collects-dir) - (find-include-dir) - (buildinfo "CFLAGS"))) - (error "compile failed")) +(define (go use-declare?) + (parameterize ([current-directory dir]) + (when use-declare? + (system* (build-path (find-console-bin-dir) "raco") + "ctool" + "--3m" + "--c-mods" + (path->string (build-path (find-system-path 'temp-dir) "embed-base.c")) + "++lib" + "racket/base" + "++lib" + "racket/place" + "++lib" + "tests/racket/embed-place")) + (unless (system (format "cc -c -o embed-in-c.o ~a-DMZ_COLLECTION_PATH='\"~a\"' -I\"~a\" -DMZ_PRECISE_GC ~a embed-in-c.c" + (if use-declare? + (format "-DUSE_DECLARED_MODULE -I\"~a\" " (find-system-path 'temp-dir)) + "") + (find-collects-dir) + (find-include-dir) + (buildinfo "CFLAGS"))) + (error "compile failed")) + + (unless (system (format "cc -o embed-in-c embed-in-c.o -lm -ldl -pthread ~a" + (case (system-type 'link) + [(framework) + (format "-F\"~a\" -framework Racket" lib-dir)] + [(static shared) + (format "-L\"~a\" -lracket3m ~a ~a" lib-dir + (buildinfo "LDFLAGS") (buildinfo "LIBS"))] + [else + (error "unsupported")]))) + (error "link failed")) + + (let ([o (open-output-bytes)] + [e (open-output-bytes)]) + (unless (parameterize ([current-input-port (open-input-bytes #"5\n(log-error \"ouch!\")")] + [current-output-port o] + [current-error-port e]) + (system + (format "~a./embed-in-c 1 2 3" + (case (system-type 'link) + [(framework) + (format "env DYLD_FRAMEWORK_PATH=\"~a\" " lib-dir)] + [else ""])))) + (error 'run "failed: ~s" (get-output-bytes e))) + (test #"ouch!\n" (get-output-bytes e)) + (test #"1\n2\n3\n> 5\n> > " (get-output-bytes o))) + + (let ([maybe-delete-file + (lambda (f) (when (file-exists? f) (delete-file f)))]) + (maybe-delete-file "embed-in-c.o") + (maybe-delete-file "embed-in-c"))) - (unless (system (format "cc -o embed-in-c embed-in-c.o -lm -ldl -pthread ~a" - (case (system-type 'link) - [(framework) - (format "-F\"~a\" -framework Racket" lib-dir)] - [(static shared) - (format "-L\"~a\" -lracket3m ~a ~a" lib-dir - (buildinfo "LDFLAGS") (buildinfo "LIBS"))] - [else - (error "unsupported")]))) - (error "link failed")) - - (let ([o (open-output-bytes)] - [e (open-output-bytes)]) - (unless (parameterize ([current-input-port (open-input-bytes #"5\n(log-error \"ouch!\")")] - [current-output-port o] - [current-error-port e]) - (system - (format "~a./embed-in-c 1 2 3" - (case (system-type 'link) - [(framework) - (format "env DYLD_FRAMEWORK_PATH=\"~a\" " lib-dir)] - [else ""])))) - (error 'run "failed: ~s" (get-output-bytes e))) - (test #"ouch!\n" (get-output-bytes e)) - (test #"1\n2\n3\n> 5\n> > " (get-output-bytes o))) + (printf "passed ~a declare\n" (if use-declare? "with" "without"))) - (let ([maybe-delete-file - (lambda (f) (when (file-exists? f) (delete-file f)))]) - (maybe-delete-file "embed-in-c.o") - (maybe-delete-file "embed-in-c"))) +(go #f) +(go #t) -(printf "passed\n") diff --git a/collects/tests/racket/embed-place.rkt b/collects/tests/racket/embed-place.rkt new file mode 100644 index 0000000000..46e33a7483 --- /dev/null +++ b/collects/tests/racket/embed-place.rkt @@ -0,0 +1,7 @@ +#lang racket/base +(require racket/place) + +(provide go) + +(define (go ch) + (place-channel-put ch 42)) diff --git a/src/racket/cmdline.inc b/src/racket/cmdline.inc index aa746a891b..13284350ac 100644 --- a/src/racket/cmdline.inc +++ b/src/racket/cmdline.inc @@ -298,10 +298,10 @@ static int finish_cmd_line_run(FinishArgs *fa, Repl_Proc repl) /* eval from stdin */ scheme_eval_all_with_prompt(NULL, fa->global_env, 2); } else if (fa->eval_kind[i] == mzcmd_EMBEDDED_REG) { - scheme_register_embedded_load(fa->evals_and_loads[i]); - scheme_embedded_load(fa->evals_and_loads[i], 1); + scheme_register_embedded_load(-1, fa->evals_and_loads[i]); + scheme_embedded_load(-1, fa->evals_and_loads[i], 1); } else if (fa->eval_kind[i] == mzcmd_EMBEDDED) { - scheme_embedded_load(fa->evals_and_loads[i], 0); + scheme_embedded_load(-1, fa->evals_and_loads[i], 0); } else { Scheme_Object *a[1], *nsreq; char *name; diff --git a/src/racket/include/scheme.h b/src/racket/include/scheme.h index 64fd793df0..e90062c32f 100644 --- a/src/racket/include/scheme.h +++ b/src/racket/include/scheme.h @@ -1770,8 +1770,8 @@ XFORM_NONGCING MZ_EXTERN intptr_t scheme_get_multiple_count(); XFORM_NONGCING MZ_EXTERN Scheme_Object **scheme_get_multiple_array(); XFORM_NONGCING MZ_EXTERN void scheme_set_current_thread_ran_some(); -MZ_EXTERN void scheme_embedded_load(const char *s, int predefined); -MZ_EXTERN void scheme_register_embedded_load(const char *s); +MZ_EXTERN void scheme_embedded_load(intptr_t len, const char *s, int predefined); +MZ_EXTERN void scheme_register_embedded_load(intptr_t len, const char *s); /* Set these global hooks (optionally): */ typedef void (*Scheme_Exit_Proc)(int v); diff --git a/src/racket/src/eval.c b/src/racket/src/eval.c index 43d8a8d7ef..af1247a707 100644 --- a/src/racket/src/eval.c +++ b/src/racket/src/eval.c @@ -5108,15 +5108,24 @@ Scheme_Object *scheme_eval_string_multi_with_prompt(const char *str, Scheme_Env return do_eval_string_all(NULL, str, env, 0, 1); } -void scheme_embedded_load(const char *desc, int predefined) +void scheme_embedded_load(intptr_t len, const char *desc, int predefined) { Scheme_Object *s, *e, *a[3], *eload; eload = scheme_builtin_value("embedded-load"); - s = scheme_make_utf8_string(desc); - e = scheme_make_utf8_string(desc XFORM_OK_PLUS strlen(desc) XFORM_OK_PLUS 1); - a[0] = s; - a[1] = e; - a[2] = scheme_false; + if (len < 0) { + /* description mode */ + s = scheme_make_utf8_string(desc); + e = scheme_make_utf8_string(desc XFORM_OK_PLUS strlen(desc) XFORM_OK_PLUS 1); + a[0] = s; + a[1] = e; + a[2] = scheme_false; + } else { + /* content mode */ + a[0] = scheme_false; + a[1] = scheme_false; + s = scheme_make_sized_byte_string((char *)desc, len, 0); + a[2] = s; + } if (predefined) scheme_starting_up = 1; (void)scheme_apply(eload, 3, a); diff --git a/src/racket/src/place.c b/src/racket/src/place.c index e5c4441fad..e13ab0bcd3 100644 --- a/src/racket/src/place.c +++ b/src/racket/src/place.c @@ -25,6 +25,7 @@ static Scheme_Object* scheme_place_shared(int argc, Scheme_Object *args[]); THREAD_LOCAL_DECL(int scheme_current_place_id); +SHARED_OK static intptr_t embedded_load_len; SHARED_OK static const char *embedded_load; #ifdef MZ_USE_PLACES @@ -176,8 +177,9 @@ int scheme_get_place_id(void) #endif } -void scheme_register_embedded_load(const char *s) +void scheme_register_embedded_load(intptr_t len, const char *s) { + embedded_load_len = len; embedded_load = s; } @@ -2224,7 +2226,7 @@ static int do_embedded_load() p->error_buf = &newbuf; if (!scheme_setjmp(newbuf)) { - scheme_embedded_load(embedded_load, 1); + scheme_embedded_load(embedded_load_len, embedded_load, 1); rc = 1; } else { rc = 0; From 5686f0e758417c4a7126e6049f0a0289d474255d Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Thu, 19 Jan 2012 17:59:25 -0500 Subject: [PATCH 519/746] re-added rshift to KEYEVTS, no clue how they got lost; Closes PR12500; please merge into 5.2.1 (cherry picked from commit 2a34cbfb85d208a495ca21d08073fb1bd7a1f34c) --- collects/2htdp/universe.rkt | 1 + collects/teachpack/2htdp/scribblings/universe.scrbl | 1 + 2 files changed, 2 insertions(+) diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index 38b6910261..7a2858b993 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -211,6 +211,7 @@ "cancel" "clear" "shift" + "rshift" "control" "menu" "pause" diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index 5c3991acf9..8c2cc448f1 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -298,6 +298,7 @@ Second, some keys have multiple-character string representations. Strings @item{@racket["cancel"]} @item{@racket["clear"]} @item{@racket["shift"]} +@item{@racket["rshift"]} @item{@racket["control"]} @item{@racket["menu"]} @item{@racket["pause"]} From b05bfd0acf67a701d72b232ff154a585331ee641 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jan 2012 16:19:38 -0700 Subject: [PATCH 520/746] gtk: fix problem wth window freeze & thaw Closes PR 12496 Merge to 5.2.1 (cherry picked from commit 484803a896eb8d1eb3ea46dcb1223fb21af24110) --- collects/mred/private/wx/gtk/window.rkt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/collects/mred/private/wx/gtk/window.rkt b/collects/mred/private/wx/gtk/window.rkt index 589b3530cf..42ba4b1465 100644 --- a/collects/mred/private/wx/gtk/window.rkt +++ b/collects/mred/private/wx/gtk/window.rkt @@ -716,6 +716,7 @@ (define-gdk gdk_window_thaw_updates (_fun _GdkWindow -> _void)) (define-gdk gdk_window_invalidate_rect (_fun _GdkWindow _pointer _gboolean -> _void)) (define-gdk gdk_window_process_all_updates (_fun -> _void)) +(define-gdk gdk_window_ensure_native (_fun _GdkWindow -> _gboolean)) (define (win-box-valid? win-box) (mcar win-box)) @@ -734,6 +735,11 @@ (lambda (win-box) (let ([win (mcar win-box)]) (and win + ;; The freeze/thaw state is actually with the window's + ;; implementation, so force a native implementation of the + ;; window to try to avoid it changing out from underneath + ;; us between the freeze and thaw actions. + (gdk_window_ensure_native win) (begin (gdk_window_freeze_updates win) (set-mcdr! win-box (add1 (mcdr win-box))) From 220b3fbee4a68ac78ba2d0969ab39af5f822b7c0 Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Fri, 20 Jan 2012 12:29:52 -0700 Subject: [PATCH 521/746] Added portable hash-quote-icon, updated and recolored macro stepper toolbar icon Closes PR 12422 Please merge into release (cherry picked from commit f1add6929b104a04c5e70f0a7b06d3c9a7c617ae) --- collects/icons/macro-stepper-32x32.png | Bin 2645 -> 2589 bytes collects/images/icons/symbol.rkt | 35 ++++++++++++++++++++++-- collects/images/icons/tool.rkt | 12 ++++---- collects/images/logos.rkt | 27 ++---------------- collects/images/scribblings/icons.scrbl | 14 +++++++--- collects/images/scribblings/logos.scrbl | 4 +-- collects/images/tests/icon-tests.rkt | 2 +- 7 files changed, 54 insertions(+), 40 deletions(-) diff --git a/collects/icons/macro-stepper-32x32.png b/collects/icons/macro-stepper-32x32.png index 4ed6905da57beca35bb71f32098f18770015a095..c6c9a6e661330c4548e08be2668171c57a0a55f0 100644 GIT binary patch delta 2562 zcmV+d3jOuf6rB{1HGc`xNklZYm8l2b;o~upL6cHuemdGXU6mJ*ui!@wv*WL zIPps;gh@;sFpiSOC}~mh4?|J*)J9E#y=bU>Ud+&aj1n{HSAG$sst-aPy|NUR$w{_Yu!jvuDpIQpIz``HaGvv>So*NIiEz62j?pMm27WsZp!8d9?ld7mlksawJ;p_ZWKTivb{fd z-JbRLZ+S8+M1Om(K0CU~^5{t7saIUL_eUM&74!c2U;dR3+`W=)wvWSyk2*vHqQ_F8uCNyqITv821%p#IFw4o^T^P464Fw{Crq#fu-~ z(MLX>pPqc{ap3b>CxgZaPMo+vu~@=!ETnWXCLNs9IDh$f*PXZQz7PMY<2PF}R(Vgc2bnuA66ideT

" #"Please go to here instead." #"

")) ] From 214aeb4810f61a94d54930b2a452166ade71aa64 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 23 Jul 2012 21:09:29 -0500 Subject: [PATCH 625/746] fix `subprocess' test Merge to v5.3 (cherry picked from commit 22960b9c7579d4ef2a3715652edc955fc9a03fc4) --- collects/tests/racket/mzlib-tests.rktl | 1 + collects/tests/racket/subprocess.rktl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/tests/racket/mzlib-tests.rktl b/collects/tests/racket/mzlib-tests.rktl index b0a35143e2..78f46d3118 100644 --- a/collects/tests/racket/mzlib-tests.rktl +++ b/collects/tests/racket/mzlib-tests.rktl @@ -32,5 +32,6 @@ (load-in-sandbox "macrolib.rktl") (load-in-sandbox "resource.rktl") (load-in-sandbox "syntaxlibs.rktl") +(load-in-sandbox "subprocess.rktl") (report-errs) diff --git a/collects/tests/racket/subprocess.rktl b/collects/tests/racket/subprocess.rktl index 94e182b4be..49685c3069 100644 --- a/collects/tests/racket/subprocess.rktl +++ b/collects/tests/racket/subprocess.rktl @@ -342,7 +342,7 @@ (let ([no-nuls (lambda (thunk) (err/rt-test (thunk) (lambda (exn) - (regexp-match? #rx"without nuls" (exn-message exn)))))]) + (regexp-match? #rx"bytes-no-nuls[?]" (exn-message exn)))))]) (no-nuls (lambda () (subprocess #f #f #f cat "\0"))) (no-nuls (lambda () (subprocess #f #f #f cat #"\0"))) (no-nuls (lambda () (process "\0"))) From 07dd4500f57d131580a4e5f2efe1157b64f10761 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 24 Jul 2012 04:03:49 -0500 Subject: [PATCH 626/746] fix debugger for the case when it decides not to annotate a file related to PR 12937 This doesn't seem to fix the PR since the debugger is currently ignoring the TR programs (not annotating them) but at least it does not crash now Please merge to 5.3 (cherry picked from commit fadd1d97142c041d3ea44e32f97755e5a25043ba) --- collects/gui-debugger/debug-tool.rkt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/collects/gui-debugger/debug-tool.rkt b/collects/gui-debugger/debug-tool.rkt index 1a034af1b4..c70714085d 100644 --- a/collects/gui-debugger/debug-tool.rkt +++ b/collects/gui-debugger/debug-tool.rkt @@ -634,9 +634,12 @@ (let ([src (syntax-source orig-exp)]) (and (path? src) src)))) - (when (or (eq? (filename->defs fn) (send (get-tab) get-defs)) - (annotate-this-module? fn)) - (parameterize ([current-eval oe]) + (cond + [(or (eq? (filename->defs (and (syntax? orig-exp) + (syntax-source orig-exp))) + (send (get-tab) get-defs)) + (annotate-this-module? fn)) + (parameterize ([current-eval oe]) (eval/annotations top-e ; annotate-module? @@ -688,7 +691,8 @@ (hash-set! breakpoints posn (hash-ref breakpoints posn (lambda () #f)))) - annotated))))]))) + annotated)))] + [else (oe top-e)])]))) (define/private (annotate-this-module? fn) (cond From 7b32c83cbd5b3542864c888a7957b497f969f3b9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 24 Jul 2012 07:07:38 -0500 Subject: [PATCH 627/746] normalize module rename info to vector in ".zo" format This is related to the receent repairs for submodules and `variable-reference->namespace'. Merge to v5.3 (cherry picked from commit 5a1bc5ad4001b1ac0203aee3852d8a5694b818d1) --- collects/compiler/zo-structs.rkt | 2 +- collects/scribblings/raco/zo-struct.scrbl | 2 +- src/racket/src/marshal.c | 12 ++++++------ src/racket/src/module.c | 5 ++++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/collects/compiler/zo-structs.rkt b/collects/compiler/zo-structs.rkt index d16b9fbd66..1065cf265c 100644 --- a/collects/compiler/zo-structs.rkt +++ b/collects/compiler/zo-structs.rkt @@ -124,7 +124,7 @@ [max-let-depth exact-nonnegative-integer?] [dummy toplevel?] [lang-info (or/c #f (vector/c module-path? symbol? any/c))] - [internal-context (or/c #f #t stx? (listof stx?))] + [internal-context (or/c #f #t stx? (vectorof stx?))] [pre-submodules (listof mod?)] [post-submodules (listof mod?)])) diff --git a/collects/scribblings/raco/zo-struct.scrbl b/collects/scribblings/raco/zo-struct.scrbl index 330fdd7438..d6355a72c2 100644 --- a/collects/scribblings/raco/zo-struct.scrbl +++ b/collects/scribblings/raco/zo-struct.scrbl @@ -173,7 +173,7 @@ structures that are produced by @racket[zo-parse] and consumed by [max-let-depth exact-nonnegative-integer?] [dummy toplevel?] [lang-info (or/c #f (vector/c module-path? symbol? any/c))] - [internal-context (or/c #f #t stx? (listof stx?))] + [internal-context (or/c #f #t stx? (vectorof stx?))] [pre-submodules (listof mod?)] [post-submodules (listof mod?)])]{ Represents a @racket[module] declaration. diff --git a/src/racket/src/marshal.c b/src/racket/src/marshal.c index c7c2faac19..4b6b2a5734 100644 --- a/src/racket/src/marshal.c +++ b/src/racket/src/marshal.c @@ -1173,11 +1173,6 @@ static Scheme_Object *read_resolve_prefix(Scheme_Object *obj) return (Scheme_Object *)rp; } -XFORM_NONGCING static Scheme_Object *wrap_mod_stx(Scheme_Object *stx) -{ - return (stx ? stx : scheme_false); -} - static Scheme_Object *write_module(Scheme_Object *obj) { Scheme_Module *m = (Scheme_Module *)obj; @@ -1323,7 +1318,12 @@ static Scheme_Object *write_module(Scheme_Object *obj) l = cons(scheme_make_integer(m->max_let_depth), l); - l = cons(wrap_mod_stx(m->rn_stx), l); + v = m->rn_stx; + if (!v) + v = scheme_false; + else if (SCHEME_PAIRP(v)) + v = scheme_list_to_vector(v); + l = cons(v, l); /* previously recorded "functional?" info: */ l = cons(scheme_false, l); diff --git a/src/racket/src/module.c b/src/racket/src/module.c index 8f02fd1873..d055775e98 100644 --- a/src/racket/src/module.c +++ b/src/racket/src/module.c @@ -6196,7 +6196,10 @@ static Scheme_Object *do_module_execute(Scheme_Object *data, Scheme_Env *genv, if (m->rn_stx && !SAME_OBJ(scheme_true, m->rn_stx)) { /* Delay the shift: */ Scheme_Object *v; - v = scheme_make_pair(m->rn_stx, (Scheme_Object *)midx); + v = m->rn_stx; + if (SCHEME_PAIRP(v)) + v = scheme_list_to_vector(v); + v = scheme_make_pair(v, (Scheme_Object *)midx); m->rn_stx = v; } } From f68f5f6fdb0290b88b487c469a0e8e1ea80d78b4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 24 Jul 2012 10:17:58 -0500 Subject: [PATCH 628/746] finish removing the check-expect dock/undock menu items (cherry picked from commit be2c7d7ada39f3ae53a42c2ca177dc235b7db68e) --- collects/test-engine/test-tool.scm | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/collects/test-engine/test-tool.scm b/collects/test-engine/test-tool.scm index 8ce34a8013..5967e5dfb6 100644 --- a/collects/test-engine/test-tool.scm +++ b/collects/test-engine/test-tool.scm @@ -91,12 +91,10 @@ (define/public (dock-tests) (for ([t test-windows]) (send t show #f)) (let ([ed (send (get-current-tab) get-test-editor)]) - (when ed (display-test-panel ed))) - (send dock-menu-item swap-labels)) + (when ed (display-test-panel ed)))) (define/public (undock-tests) (when (send test-panel is-shown?) (send test-panel remove)) - (for ([t test-windows]) (send t show #t)) - (send dock-menu-item swap-labels)) + (for ([t test-windows]) (send t show #t))) (define/override (make-root-area-container cls parent) (let* ([outer-p (super make-root-area-container @@ -124,26 +122,8 @@ (inherit get-menu-bar get-menu% register-capability-menu-item get-definitions-text get-insert-menu) - (define dock-menu-item 'not-init) (define dock-label (string-constant test-engine-dock-report)) (define undock-label (string-constant test-engine-undock-report)) - - (define dock-menu-item% - (class menu:can-restore-menu-item% - (inherit set-label) - (define docked? #t) - (define/public (is-report-docked?) docked?) - (define/public (set-docked?! d) (set! docked? d)) - (define/public (swap-labels) - (if docked? - (send this set-label dock-label) - (send this set-label undock-label)) - (set! docked? (not docked?))) - (define/public (dock-report) - (unless docked? (dock-tests) (preferences:set 'test-engine:test-window:docked? #t))) - (define/public (undock-report) - (when docked? (undock-tests) (preferences:set 'test-engine:test-window:docked? #f))) - (super-instantiate ()))) (define/private (test-menu-init) (let ([language-menu (send this get-language-menu)] From 350c8045d70713c010c58f990e72b20f692dbe01 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 24 Jul 2012 11:47:07 -0400 Subject: [PATCH 629/746] Update with new "scribble" flag. (cherry picked from commit bc0e46227f62d24c96ed6243da263924c4d27765) --- collects/meta/contrib/completion/racket-completion.zsh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/meta/contrib/completion/racket-completion.zsh b/collects/meta/contrib/completion/racket-completion.zsh index 44e3b13d88..acefd3bc4b 100644 --- a/collects/meta/contrib/completion/racket-completion.zsh +++ b/collects/meta/contrib/completion/racket-completion.zsh @@ -235,7 +235,7 @@ _raco_cmd_setup() { _racket_do_state } -_racket_self_test 'raco scribble:3754386648' +_racket_self_test 'raco scribble:4149265431' _raco_cmd_scribble() { _arguments "$RACKET_COMMON[@]" \ '(--html --htmls --latex --pdf --latex-section --text)'--html'[Generate HTML-format output file (default)]' \ @@ -246,6 +246,7 @@ _raco_cmd_scribble() { '(--html --htmls --latex --pdf --latex-section --text)'--text'[Generate text-format output]' \ '(--dest)'--dest'+[Write output in directory]:directory:_files -/' \ '(--dest-name)'--dest-name'+[Write output as name]:name: ' \ + '(--dest-base)'--dest-base'+[Start support-file names with prefix]:prefix: ' \ '*'++style'+[Add given .css/.tex file after others]:style-file:_files -g \*.\(css\|tex\)' \ '*'--style'+[Use given base .css/.tex file]:style-file:_files -g \*.\(css\|tex\)' \ '*'--prefix'+[Use given .html/.tex prefix (for doctype/documentclass)]:prefix-file:_files -g \*.\(html\|htm\|tex\)' \ From 9c25910c8b9bfc5dc306a428a8bb4b41578cd9b7 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 24 Jul 2012 11:47:39 -0400 Subject: [PATCH 630/746] tex2page is gone, update installer tests. (cherry picked from commit d7f0314c748abc66b5733e7cc1957ed282091668) --- collects/meta/build/unix-installer/test-installer | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/collects/meta/build/unix-installer/test-installer b/collects/meta/build/unix-installer/test-installer index a46b83c643..7014ecd1b0 100755 --- a/collects/meta/build/unix-installer/test-installer +++ b/collects/meta/build/unix-installer/test-installer @@ -173,7 +173,7 @@ exec racket "$0" "$@" drracket, gracket skipped (non-link exists), gracket-text, mred, @; mred-text, mzc, mzpp, mzscheme, mztext, pdf-slatex, planet, plt-games, @; plt-help, plt-r5rs, plt-r6rs, plt-web-server, racket, raco, scribble, @; - setup-plt, slatex, slideshow, swindle, tex2page + setup-plt, slatex, slideshow, swindle done. "@|testdir|/share/man/man1" does not exist, skipping. @|| @@ -186,7 +186,7 @@ exec racket "$0" "$@" @s|{drracket@, gracket, gracket-text@, mred@, mred-text@, mzc@, mzpp@, mzscheme@, mztext@, pdf-slatex@, planet@, plt-games@, plt-help@, plt-r5rs@, plt-r6rs@, plt-web-server@, racket@, raco@, scribble@, - setup-plt@, slatex@, slideshow@, swindle@, tex2page@}| + setup-plt@, slatex@, slideshow@, swindle@}| sh> @i{LS -l bin/ra*} lrwxrwxrwx. @... bin/racket -> @|testdir|/R/bin/racket* lrwxrwxrwx. @... bin/raco -> @|testdir|/R/bin/raco* @@ -306,7 +306,7 @@ exec racket "$0" "$@" drracket*, gracket*, gracket-text*, mred*, mred-text*, mzc*, mzpp*, mzscheme*, mztext*, pdf-slatex*, planet*, plt-games*, plt-help*, plt-r5rs*, plt-r6rs*, plt-web-server*, racket*, racket-uninstall*, - raco*, scribble*, setup-plt*, slatex*, slideshow*, swindle*, tex2page* + raco*, scribble*, setup-plt*, slatex*, slideshow*, swindle* sh> @i{LS include && LS lib && LS share} racket@|N|/ racket@|N|/ @@ -323,7 +323,7 @@ exec racket "$0" "$@" sh> @i{LS share/man && LS share/man/man1} man1/ drracket.1, gracket.1, mred.1, mzc.1, mzscheme.1, plt-help.1, racket.1, - raco.1, setup-plt.1, tex2page.1 + raco.1, setup-plt.1 sh> @i{sh @installer} @... Enter yes/no (default: no) > @i{y} From c9d0319a11cb2aae6d1e81d0c6465b4241a4ecff Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 24 Jul 2012 11:10:35 -0500 Subject: [PATCH 631/746] add missing `super-new' from class100 conversion Also, move relevant tests to a better place. Merge to v5.3 (cherry picked from commit 289ae98c8e278fdcf4c33d4c7a4b3470ffaa3747) --- collects/graphics/graphics-posn-less-unit.rkt | 1 + collects/{tests/gracket => graphics/tests}/sixlib.rktl | 0 collects/meta/props | 2 +- 3 files changed, 2 insertions(+), 1 deletion(-) rename collects/{tests/gracket => graphics/tests}/sixlib.rktl (100%) diff --git a/collects/graphics/graphics-posn-less-unit.rkt b/collects/graphics/graphics-posn-less-unit.rkt index d83258fd9e..7a04ac8a97 100644 --- a/collects/graphics/graphics-posn-less-unit.rkt +++ b/collects/graphics/graphics-posn-less-unit.rkt @@ -67,6 +67,7 @@ (define sixlib-canvas% (class mred:canvas% + (super-new) (inherit get-parent min-client-width min-client-height stretchable-width stretchable-height) diff --git a/collects/tests/gracket/sixlib.rktl b/collects/graphics/tests/sixlib.rktl similarity index 100% rename from collects/tests/gracket/sixlib.rktl rename to collects/graphics/tests/sixlib.rktl diff --git a/collects/meta/props b/collects/meta/props index 35edcd648c..510d4fe2f3 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -760,6 +760,7 @@ path/s is either such a string or a list of them. "collects/games/paint-by-numbers/raw-problems/size-calculation.rkt" drdr:command-line (mzc *) "collects/games/parcheesi/make-bitmap.rkt" drdr:command-line (mzc *) "collects/graphics" responsible (mflatt robby) +"collects/graphics/tests/sixlib.rktl" drdr:command-line #f "collects/graphics/turtle-test.rkt" drdr:command-line (mzc "-k" *) "collects/graphics/value-turtles-test.rkt" drdr:command-line (mzc *) "collects/gui-debugger" responsible (gmarceau mflatt) @@ -1071,7 +1072,6 @@ path/s is either such a string or a list of them. "collects/tests/gracket/paramz.rktl" drdr:command-line (gracket "-f" *) "collects/tests/gracket/png.rktl" drdr:command-line #f "collects/tests/gracket/showkey.rkt" drdr:command-line #f -"collects/tests/gracket/sixlib.rktl" drdr:command-line #f "collects/tests/gracket/text-scale.rktl" drdr:command-line #f "collects/tests/gracket/unflushed-circle.rkt" drdr:command-line #f "collects/tests/gracket/windowing.rktl" drdr:command-line (gracket "-f" *) From 6e7afe454bbaf30a2ea3eabbff08f9cbbbe4a9c4 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 22 Jul 2012 12:38:09 -0400 Subject: [PATCH 632/746] Use `string-no-nuls?' and `bytes-no-nuls?' in more docs & error messages. Also use `byte?' instead of (integer-in 0 255). (This commit will most likely require some proof-reading.) (cherry picked from commit a6b20f01da4a43911a33df77854d36b77f97c459) --- .../scribblings/reference/subprocess.scrbl | 46 ++++++++++++------- src/racket/src/port.c | 7 +-- src/racket/src/schpriv.h | 2 +- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/collects/scribblings/reference/subprocess.scrbl b/collects/scribblings/reference/subprocess.scrbl index 6f06dd399c..1d7e789bab 100644 --- a/collects/scribblings/reference/subprocess.scrbl +++ b/collects/scribblings/reference/subprocess.scrbl @@ -7,7 +7,7 @@ [stdin (or/c (and/c input-port? file-stream-port?) #f)] [stderr (or/c (and/c output-port? file-stream-port?) #f 'stdout)] [command path-string?] - [arg (or/c path? string? bytes?)] ...) + [arg (or/c path? string-no-nuls? bytes-no-nuls?)] ...) (values subprocess? (or/c (and/c input-port? file-stream-port?) #f) (or/c (and/c output-port? file-stream-port?) #f) @@ -217,7 +217,7 @@ interactive shell, since job control is based on process groups.} [target string?] [parameters string?] [dir path-string?] - [show-mode symbol?]) + [show-mode symbol?]) #f]{ @index['("ShellExecute")]{Performs} the action specified by @racket[verb] @@ -318,7 +318,7 @@ real process ID).} @note-lib[racket/system] -@defproc[(system [command (or/c string? bytes?)]) boolean?]{ +@defproc[(system [command (or/c string-no-nuls? bytes-no-nuls?)]) boolean?]{ Executes a Unix, Mac OS X, or Windows shell command synchronously (i.e., the call to @racket[system] does not return until the @@ -342,8 +342,11 @@ function: ]} -@defproc*[([(system* [command path-string?] [arg (or/c path? string? bytes?)] ...) boolean?] - [(system* [command path-string?] [exact 'exact] [arg string?]) boolean?])]{ +@defproc*[([(system* [command path-string?] + [arg (or/c path? string-no-nuls? bytes-no-nuls?)] ...) + boolean?] + [(system* [command path-string?] [exact 'exact] [arg string?]) + boolean?])]{ Like @racket[system], except that @racket[command] is a filename that is executed directly (instead of through a shell command; see @@ -358,20 +361,25 @@ On Windows, the first argument after @racket[command] can be line. See @racket[subprocess] for details.} -@defproc[(system/exit-code [command (or/c string? bytes?)]) (integer-in 0 255)]{ +@defproc[(system/exit-code [command (or/c string-no-nuls? bytes-no-nuls?)]) + byte?]{ Like @racket[system], except that the result is the exit code returned by the subprocess. A @racket[0] result normally indicates success.} -@defproc*[([(system*/exit-code [command path-string?] [arg (or/c path? string? bytes?)] ...) (integer-in 0 255)] - [(system*/exit-code [command path-string?] [exact 'exact] [arg string?]) (integer-in 0 255)])]{ +@defproc*[([(system*/exit-code [command path-string?] + [arg (or/c path? string-no-nuls? bytes-no-nuls?)] ...) + byte?] + [(system*/exit-code [command path-string?] + [exact 'exact] [arg string?]) + byte?])]{ Like @racket[system*], but returns the exit code like @racket[system/exit-code].} - -@defproc[(process [command string?]) + +@defproc[(process [command (or/c string-no-nuls? bytes-no-nuls?)]) (list input-port? output-port? exact-nonnegative-integer? @@ -438,10 +446,13 @@ implement @racket[process]. In particular, the @racket['interrupt] and @racket['kill] process-control messages are implemented via @racket[subprocess-kill], so they can affect a process group instead of a single process.} - -@defproc*[([(process* [command path-string?] [arg (or/c path? string? bytes?)] ...) list?] - [(process* [command path-string?] [exact 'exact] [arg string?]) list?])]{ + +@defproc*[([(process* [command path-string?] + [arg (or/c path? string-no-nuls? bytes-no-nuls?)] ...) + list?] + [(process* [command path-string?] [exact 'exact] [arg string?]) + list?])]{ Like @racket[process], except that @racket[command] is a filename that is executed directly like @racket[system*], and the @racket[arg]s are the arguments. On @@ -452,7 +463,7 @@ replaced with @racket['exact].} @defproc[(process/ports [out (or/c #f output-port?)] [in (or/c #f input-port?)] [error-out (or/c #f output-port? 'stdout)] - [command string?]) + [command (or/c path? string-no-nuls? bytes-no-nuls?)]) list?]{ Like @racket[process], except that @racket[out] is used for the @@ -469,7 +480,8 @@ returned list is @racket[#f].} [in (or/c #f input-port?)] [error-out (or/c #f output-port? 'stdout)] [command path-string?] - [arg (or/c path? string? bytes?)] ...) + [arg (or/c path? string-no-nuls? bytes-no-nuls?)] + ...) list?] [(process*/ports [out (or/c #f output-port?)] [in (or/c #f input-port?)] @@ -489,10 +501,10 @@ Like @racket[process*], but with the port handling of @;note-lib[racket/system] The contracts of @racket[system] and related functions may signal a -contract error with references to the following functions. +contract error with references to the following functions. @defproc[(string-no-nuls? [x any/c]) boolean?]{ Ensures that @racket[x] is a string and does not contain @racket["\0"].} @defproc[(bytes-no-nuls? [x any/c]) boolean?]{ -Ensures that @racket[x] is a byte-string and does not contain @racket["\0"].} +Ensures that @racket[x] is a byte-string and does not contain @racket[#"\0"].} diff --git a/src/racket/src/port.c b/src/racket/src/port.c index a31d8472fe..890e9dbd89 100644 --- a/src/racket/src/port.c +++ b/src/racket/src/port.c @@ -8937,12 +8937,9 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[]) if (((!SCHEME_CHAR_STRINGP(args[i]) && !SCHEME_BYTE_STRINGP(args[i])) || scheme_any_string_has_null(args[i])) && !SCHEME_PATHP(args[i])) - scheme_wrong_contract(name, - ("(or/c path?\n" - " (and/c string? (lambda (s) (not (memv #\\nul (string->list s)))))\n" - " (and/c bytes? (lambda (bs) (not (memv 0 (bytes->list bs))))))"), + scheme_wrong_contract(name, + "(or/c path? string-no-nuls? bytes-no-nuls?)", i, c, args); - { Scheme_Object *bs; bs = args[i]; diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index 22f8932ca6..c68ed47462 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -3377,7 +3377,7 @@ const char *scheme_hostname_error(int err); int scheme_byte_string_has_null(Scheme_Object *o); int scheme_any_string_has_null(Scheme_Object *o); -#define CHAR_STRING_W_NO_NULLS "(and/c string? (lambda (s) (not (memv #\\nul (string->list s)))))" +#define CHAR_STRING_W_NO_NULLS "string-no-nuls?" Scheme_Object *scheme_do_exit(int argc, Scheme_Object *argv[]); From 2e8cc1510d22aba30497692a01d9692a89a95867 Mon Sep 17 00:00:00 2001 From: John Clements Date: Tue, 24 Jul 2012 06:42:00 -0400 Subject: [PATCH 633/746] repair hack for beginner-proc names (cherry picked from commit 4e47c669ca6cfce3be266f5f61214b15b7b5791c) --- collects/stepper/private/reconstruct.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/stepper/private/reconstruct.rkt b/collects/stepper/private/reconstruct.rkt index 1d03b6ad58..bc927487a2 100644 --- a/collects/stepper/private/reconstruct.rkt +++ b/collects/stepper/private/reconstruct.rkt @@ -655,7 +655,7 @@ (if m (datum->syntax s (string->symbol (cadr m)) s s) s))) -(define re:beginner: (regexp "^beginner:(.*)$")) +(define re:beginner: (regexp "^beginner-(.*)$")) ;; eval-quoted : take a syntax that is an application of quote, and evaluate it (for display) From 70b114b45cf75e4bb0b29f8c6708c782b12af22d Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 24 Jul 2012 13:47:31 -0400 Subject: [PATCH 634/746] Update TR history. (cherry picked from commit c5b49066a86ea07fbf142af253f2c38f9bb8564c) --- doc/release-notes/typed-racket/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes/typed-racket/HISTORY.txt b/doc/release-notes/typed-racket/HISTORY.txt index 3e66e3aa08..42577848d0 100644 --- a/doc/release-notes/typed-racket/HISTORY.txt +++ b/doc/release-notes/typed-racket/HISTORY.txt @@ -1,3 +1,7 @@ +5.3 +- Keyword and optional arguments +- Faster startup +- Random testing of the numeric tower 5.2.1 - Inference of functions with keyword arguments - `typecheck-fail' for explicit creation of type errors From 20b741538af5d20167ef3e91262be7a9a6bf97cf Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 24 Jul 2012 23:28:29 -0500 Subject: [PATCH 635/746] brought up to date with version number merge to release branch, please (cherry picked from commit aa645e9650a03c2e9fba1bc7cf4f3576d870ae5f) --- doc/release-notes/redex/HISTORY.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes/redex/HISTORY.txt b/doc/release-notes/redex/HISTORY.txt index e52c2539e8..75db8643b5 100644 --- a/doc/release-notes/redex/HISTORY.txt +++ b/doc/release-notes/redex/HISTORY.txt @@ -1,4 +1,4 @@ -v5.2.2 +v5.3 * added the amb tutorial. From 798ee0a3c5c00edd7ec9af90d66193d6331ee9a3 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 24 Jul 2012 23:33:24 -0500 Subject: [PATCH 636/746] bring drracket history file up to date merge to the release branch, please (cherry picked from commit fe9cdc0756e7999d3f4ade4984d16aa7b8623fc1) --- doc/release-notes/drracket/HISTORY.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/release-notes/drracket/HISTORY.txt b/doc/release-notes/drracket/HISTORY.txt index f092d88d52..e39eedf2bb 100644 --- a/doc/release-notes/drracket/HISTORY.txt +++ b/doc/release-notes/drracket/HISTORY.txt @@ -1,14 +1,23 @@ ------------------------------ - Version 5.2.2 + Version 5.3 ------------------------------ + . Added the Optimization Coach (see the 'View' menu) + + . Adjusted Check Syntax so that set!'d variables and + contract obligations are now in tooltips + . DrRacket's toolbar buttons now have numbers associated with them to control what order they appear in. + . Ditto for the View menu items; also, cleaned up the View menu + . The framework's color:text%'s token-sym->style init argument (also the same as the color:text%'s start-colorer method's argument of the same name) is a function that now might be passed 'white-space. + . record errors coming from user language implementations via log-debug + ------------------------------ Version 5.2.1 ------------------------------ From b3d6a4f3afe753a8ab9f2db0dc83c6d574d5b071 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 25 Jul 2012 12:52:46 -0600 Subject: [PATCH 637/746] Note `require' of a `main' submodule for `-t', `-l', and `-p' In the output of `racket -h' and in the command-line docs. Merge to v5.3 (cherry picked from commit 7d894bfb639a4c37e5b60898c0c495cb176833da) --- collects/scribblings/reference/startup.scrbl | 23 ++++++++++++-------- src/racket/cmdline.inc | 7 +++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/collects/scribblings/reference/startup.scrbl b/collects/scribblings/reference/startup.scrbl index 236e961b8b..7132eba387 100644 --- a/collects/scribblings/reference/startup.scrbl +++ b/collects/scribblings/reference/startup.scrbl @@ -139,22 +139,27 @@ flags: evaluated from standard input.} @item{@FlagFirst{t} @nonterm{file} or @DFlagFirst{require} - @nonterm{file} : @racket[require]s @nonterm{file}.} + @nonterm{file} : @racket[require]s @nonterm{file}, and then + @racket[require]s @racket[(submod (file @#,nontermstr{file}) + main)] if available.} @item{@FlagFirst{l} @nonterm{path} or @DFlagFirst{lib} @nonterm{path} : @racket[require]s @racket[(lib - @#,nontermstr{path})].} + @#,nontermstr{path})], and then @racket[require]s + @racket[(submod (lib @#,nontermstr{path}) main)] if available.} @item{@FlagFirst{p} @nonterm{package} : - @racket[require]s @racket[(planet @#,nontermstr{package})]. - - @margin-note{Despite its name, @DFlag{script} is not usually - used for Unix scripts. See @guidesecref["scripts"] for more - information on scripts.}} + @racket[require]s @racket[(planet @#,nontermstr{package})], + and then + @racket[require]s @racket[(submod (planet @#,nontermstr{package}) + main)] if available.} @item{@FlagFirst{r} @nonterm{file} or @DFlagFirst{script} - @nonterm{file} : @racket[load]s @nonterm{file} as a - script. This flag is like @Flag{t} @nonterm{file} plus + @nonterm{file} : @racket[load]s @nonterm{file} + @margin-note*{Despite its name, @DFlag{script} is not usually + used for Unix scripts. See @guidesecref["scripts"] for more + information on scripts.} + as a script. This flag is like @Flag{t} @nonterm{file} plus @Flag{N} @nonterm{file} to set the program name and @Flag{-} to cause all further command-line elements to be treated as non-flag arguments.} diff --git a/src/racket/cmdline.inc b/src/racket/cmdline.inc index 1d935e061b..8c9adf0f74 100644 --- a/src/racket/cmdline.inc +++ b/src/racket/cmdline.inc @@ -1430,13 +1430,14 @@ static int run_from_cmd_line(int argc, char *_argv[], " File and expression options:\n" " -e , --eval : Evaluate , prints results\n" " -f , --load : Like -e '(load \"\")' without printing\n" - " -t , --require : Like -e '(require (file \"\"))'\n" - " -l , --lib : Like -e '(require (lib \"\"))'\n" - " -p : Like -e '(require (planet \"\")'\n" + " -t , --require : Like -e '(require (file \"\"))' [*]\n" + " -l , --lib : Like -e '(require (lib \"\"))' [*]\n" + " -p : Like -e '(require (planet \"\")' [*]\n" " -r , --script : Same as -f -N --\n" " -u , --require-script : Same as -t -N --\n" " -k

: Load executable-embedded code from offset to

\n" " -m, --main : Call `main' with command-line arguments, print results\n" + " [*] Also `require's a `main' submodule, if any\n" " Interaction options:\n" " -i, --repl : Run interactive read-eval-print loop; implies -v\n" " -n, --no-lib : Skip `(require (lib \"\"))' for -i/-e/-f/-r\n" From e209e9c671c10b0fc40642582933eb7256a0361e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 25 Jul 2012 20:27:00 -0600 Subject: [PATCH 638/746] windows: fix `subprocess' for an empty argument An empty argument must be quoted at the CreateProcess() level. Merge to v5.3 (cherry picked from commit df4fed7011b9e9315deb76773be1b34e15f5bf1e) --- collects/compiler/private/xform.rkt | 2 +- src/racket/src/port.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/collects/compiler/private/xform.rkt b/collects/compiler/private/xform.rkt index 86059f77b3..bae88fcf5a 100644 --- a/collects/compiler/private/xform.rkt +++ b/collects/compiler/private/xform.rkt @@ -423,7 +423,7 @@ (if (eq? (system-type) 'windows) (lambda (s) (let ([split (let loop ([s s]) - (let ([m (regexp-match #rx"([^ ]*) (.*)" s)]) + (let ([m (regexp-match #rx"([^ ]*) +(.*)" s)]) (if m (cons (cadr m) (loop (caddr m))) (list s))))]) diff --git a/src/racket/src/port.c b/src/racket/src/port.c index 890e9dbd89..2107b8aac4 100644 --- a/src/racket/src/port.c +++ b/src/racket/src/port.c @@ -8622,6 +8622,8 @@ static char *cmdline_protect(char *s) int ds; int has_space = 0, has_quote = 0, was_slash = 0; + if (!*s) return "\"\""; /* quote an empty argument */ + for (ds = 0; s[ds]; ds++) { if (isspace(s[ds]) || (s[ds] == '\'')) { has_space = 1; From d44480001883f7681331404e2bea340f1fc0c865 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 25 Jul 2012 20:45:52 -0600 Subject: [PATCH 639/746] fix `current-subprocess-custodian-mode' An 'interrupt setting was treated as a 'kill setting. Merge to v5.3 (cherry picked from commit d8461837f91b800621bf2c4673071f8edbc5f505) --- src/racket/src/port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racket/src/port.c b/src/racket/src/port.c index 2107b8aac4..8008d1efc9 100644 --- a/src/racket/src/port.c +++ b/src/racket/src/port.c @@ -8532,7 +8532,7 @@ static void kill_subproc(Scheme_Object *o, void *data) static void interrupt_subproc(Scheme_Object *o, void *data) { - (void)do_subprocess_kill(o, scheme_true, 0); + (void)do_subprocess_kill(o, scheme_false, 0); } #endif From 662ffe7b02c05ba7821c66544ea3f491b6d95ef1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 25 Jul 2012 21:37:58 -0600 Subject: [PATCH 640/746] racket/port: fix `make-limited-input-port' handling of progress evts Merge to v5.3 (cherry picked from commit ca3272bd45941ac77e8bfb45bb4741a8076b371b) Conflicts: collects/racket/port.rkt --- collects/mzlib/port.rkt | 5 +- collects/tests/racket/portlib.rktl | 74 ++++++++++++++++-------------- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/collects/mzlib/port.rkt b/collects/mzlib/port.rkt index e331742109..89a690f71c 100644 --- a/collects/mzlib/port.rkt +++ b/collects/mzlib/port.rkt @@ -852,7 +852,10 @@ (define (do-peek str skip progress-evt) (let ([count (max 0 (min (- limit got skip) (bytes-length str)))]) (if (zero? count) - eof + (if (and progress-evt + (sync/timeout 0 progress-evt)) + #f + eof) (let ([n (peek-bytes-avail!* str skip progress-evt port 0 count)]) (if (eq? n 0) (wrap-evt port (lambda (x) 0)) diff --git a/collects/tests/racket/portlib.rktl b/collects/tests/racket/portlib.rktl index c5078319ab..7f0e3548ff 100644 --- a/collects/tests/racket/portlib.rktl +++ b/collects/tests/racket/portlib.rktl @@ -840,42 +840,46 @@ ;; -------------------------------------------------- -;; check that commit-based reading counts against a port limit: -(let* ([p (make-limited-input-port - (open-input-string "A\nB\nC\nD\n") - 4)] - [N 6] - [chs (for/list ([i N]) - (let ([ch (make-channel)]) - (thread - (lambda () - (channel-put ch (list (sync (read-bytes-line-evt p)) - (file-position p))))) - ch))] - [r (for/list ([ch chs]) - (channel-get ch))]) - r) +;; check that commit-based reading counts against a port limit; +;; this test also checks an interaction of `make-limited-input-port' +;; and progress evts, so run it several times +(for ([i 100]) + (let* ([p (make-limited-input-port + (open-input-string "A\nB\nC\nD\n") + 4)] + [N 6] + [chs (for/list ([i N]) + (let ([ch (make-channel)]) + (thread + (lambda () + (channel-put ch (list (sync (read-bytes-line-evt p)) + (file-position p))))) + ch))] + [r (for/list ([ch chs]) + (channel-get ch))]) + (test #t list? r))) -;; check proper locking for concurrent access: -(let* ([p (make-limited-input-port - (open-input-string "A\nB\nC\nD\n") - 4)] - [N 6] - [chs (for/list ([i N]) - (let ([ch (make-channel)]) - (thread - (lambda () - (when (even? i) (sleep)) - (channel-put ch (list (sync (read-bytes-line-evt p)) - (file-position p))))) - ch))] - [rs (for/list ([ch chs]) - (channel-get ch))]) - (test 2 apply + (for/list ([r rs]) (if (bytes? (car r)) 1 0))) - (test #t values (for/and ([r rs]) - (if (eof-object? (car r)) - (eq? (cadr r) 4) - (memq (cadr r) '(2 4)))))) +;; check proper locking for concurrent access: +(for ([i 100]) + (let* ([p (make-limited-input-port + (open-input-string "A\nB\nC\nD\n") + 4)] + [N 6] + [chs (for/list ([i N]) + (let ([ch (make-channel)]) + (thread + (lambda () + (when (even? i) (sleep)) + (channel-put ch (list (sync (read-bytes-line-evt p)) + (file-position p))))) + ch))] + [rs (for/list ([ch chs]) + (channel-get ch))]) + (test 2 apply + (for/list ([r rs]) (if (bytes? (car r)) 1 0))) + (test #t values (for/and ([r rs]) + (if (eof-object? (car r)) + (eq? (cadr r) 4) + (and (memq (cadr r) '(2 4)) #t)))))) (let-values ([(in out) (make-pipe-with-specials)]) From 76306744bac27a2ee78c769ff8ffdb2fd138e70a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 26 Jul 2012 08:39:58 -0600 Subject: [PATCH 641/746] racket/port: possible repair for `read-bytes-evt' Also restore and add some tests. Merge to v5.3 (cherry picked from commit 70ef4e6e57f9eccedf13f58816e02ce3f57b4745) Conflicts: collects/racket/port.rkt --- collects/mzlib/port.rkt | 6 ++++-- collects/tests/racket/portlib.rktl | 23 +++++++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/collects/mzlib/port.rkt b/collects/mzlib/port.rkt index 89a690f71c..8bfc84b2aa 100644 --- a/collects/mzlib/port.rkt +++ b/collects/mzlib/port.rkt @@ -962,6 +962,7 @@ ;; go is the main reading function, either called directly for ;; a poll, or called in a thread for a non-poll read (define (go nack ch poll?) + ;; FIXME - what if the input port is closed? (let try-again ([pos 0] [bstr orig-bstr] [progress-evt #f]) (let* ([progress-evt ;; if no progress event is given, get one to ensure that @@ -1004,10 +1005,11 @@ (channel-put-evt ch result)) input-port) result] - [(and (eof-object? eof) + + [(and (eof-object? v) (zero? pos) (not (sync/timeout 0 progress-evt))) - ;; Must be a true end-of-file + ;; Must be a true end-of-file, since commit failed (let ([result (combo bstr eof)]) (if poll? result (channel-put ch result)))] [poll? #f] diff --git a/collects/tests/racket/portlib.rktl b/collects/tests/racket/portlib.rktl index 7f0e3548ff..15bbd2a7b7 100644 --- a/collects/tests/racket/portlib.rktl +++ b/collects/tests/racket/portlib.rktl @@ -286,7 +286,7 @@ (go-stream #t #t #t #t))) ;; make-input-port/read-to-peek -(define (make-list-port . l) +(define (make-list-port #:eof-as-special? [eof-as-special? #f] . l) (make-input-port/read-to-peek 'list-port (lambda (bytes) @@ -301,6 +301,10 @@ (bytes-set! bytes 0 (char->integer (car l))) (set! l (cdr l)) 1] + [(and (not eof-as-special?) + (eof-object? (car l))) + (set! l (cdr l)) + eof] [else (let ([v (car l)]) (set! l (cdr l)) @@ -345,11 +349,23 @@ (test 'lo read p) (test eof read p) (test eof read p)) +(let ([p (make-list-port #:eof-as-special? #t #\h #\e #\l eof #\l #\o)]) + (test 'hel read p) + (test eof read p) + (test 'lo read p) + (test eof read p) + (test eof read p)) (let ([p (make-list-port #\h #\e #\l #\u7238 #\l #\o)]) (test 'hel read p) (test #\u7238 read p) (test 'lo read p)) +(let ([p (make-list-port 65 eof 66 67)]) + (test 65 peek-byte p 0) + (test eof peek-byte p 1) + (test #t port-commit-peeked 2 (port-progress-evt p) always-evt p) + (test 66 peek-byte p 0)) + ;; Check that make-input-port/read-to-peek isn't trying ;; to use chars when it should use bytes: (let-values ([(pipe-r pipe-w) (make-pipe)]) @@ -964,13 +980,13 @@ (define-values (i o) (tcp-connect "localhost" PORT)) (write-bytes s o) (close-output-port o) - (test s read-bytes M i))) + (test s read-bytes M i) + (close-input-port i))) (sync server) (tcp-close listener)) (let ([integer->byte (lambda (s) (bitwise-and s #xFF))]) - #; (check-can-reuse read-bytes-evt read-bytes write-bytes integer->byte list->bytes bytes?) ;; the following should work because we use the same evt only after ;; success or to start at the same point in the input stream: @@ -979,7 +995,6 @@ (wrap-evt (read-bytes!-evt bstr in) (lambda (v) (if (eof-object? v) v bstr)))) read-bytes write-bytes integer->byte list->bytes bytes?)) - #; (check-can-reuse read-string-evt read-string write-string integer->char list->string string?)) ;; -------------------------------------------------- From 06439ad77f700f17b60bf9a9e125bdcec06d0699 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 26 Jul 2012 08:40:43 -0600 Subject: [PATCH 642/746] fix bug in `sync' When `guard-evt' or `nack-guard-evt' is used, `sync' didn't account for the possibility that a channel or semaphore action might complete during the call to the guard, in which case it might fail to select the event that has already completed. Merge to v5.3 (cherry picked from commit 880f84b24fb415d118fca09f506626a196199d9b) --- src/racket/src/thread.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/racket/src/thread.c b/src/racket/src/thread.c index 7ea82100d6..8313dc2f4b 100644 --- a/src/racket/src/thread.c +++ b/src/racket/src/thread.c @@ -6136,6 +6136,13 @@ static int syncing_ready(Scheme_Object *s, Scheme_Schedule_Info *sinfo) sleep_end = r_sinfo.sleep_end; + /* Calling a guard can allow thread swap, which might choose a + semaphore or a channel, so check for a result: */ + if (syncing->result) { + result = 1; + goto set_sleep_end_and_return; + } + if ((i > r_sinfo.w_i) && sinfo->false_positive_ok) { /* There was a redirection. Assert: !yep. Give up if we've chained too much. */ @@ -6181,6 +6188,9 @@ static int syncing_ready(Scheme_Object *s, Scheme_Schedule_Info *sinfo) set_sync_target(syncing, i, sema, o, NULL, repost, 1, NULL); j--; /* try again with this sema */ } + + if (syncing->result) + scheme_signal_error("internal error: sync result set unexpectedly"); } if (syncing->timeout >= 0.0) { From 09a51a9b358ee6218467d3c3ab55b224c3bc046a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 26 Jul 2012 08:47:06 -0600 Subject: [PATCH 643/746] fix a `subprocess' test Merge to v5.3 (cherry picked from commit 8c10dc15792112ef7c60be56376e6b473ae12d89) --- collects/tests/racket/subprocess.rktl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/collects/tests/racket/subprocess.rktl b/collects/tests/racket/subprocess.rktl index 49685c3069..5661042d0f 100644 --- a/collects/tests/racket/subprocess.rktl +++ b/collects/tests/racket/subprocess.rktl @@ -388,7 +388,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (let ([try - (lambda (post-shutdown) + (lambda (post-shutdown wait?) (let ([c (make-custodian)]) (let ([l (parameterize ([current-custodian c]) (process* self @@ -397,13 +397,16 @@ (test 'running (list-ref l 4) 'status) (custodian-shutdown-all c) (sleep 0.1) + (when (and wait? + (eq? post-shutdown 'done-error)) + ((list-ref l 4) 'wait)) (test post-shutdown (list-ref l 4) 'status) ((list-ref l 4) 'kill))))]) - (try 'running) + (try 'running #f) (parameterize ([current-subprocess-custodian-mode 'kill]) - (try 'done-error)) + (try 'done-error #f)) (parameterize ([current-subprocess-custodian-mode 'interrupt]) - (try (if (eq? 'windows (system-type)) 'running 'done-error)))) + (try (if (eq? 'windows (system-type)) 'running 'done-error) #t))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; process groups From eb5f4bb6df8ab9e4b48c95d686328dda0bc9bb53 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 26 Jul 2012 12:16:19 -0400 Subject: [PATCH 644/746] Revert "revert use of `lazy-require' in `racket/match' implementation" This reverts commit 949d12e2c6de4c2720c7445638ebf91dc40c3505. --- collects/racket/match/define-forms.rkt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/collects/racket/match/define-forms.rkt b/collects/racket/match/define-forms.rkt index dab3e38e23..61359627dc 100644 --- a/collects/racket/match/define-forms.rkt +++ b/collects/racket/match/define-forms.rkt @@ -5,8 +5,11 @@ (only-in racket/list append* remove-duplicates) unstable/sequence syntax/parse - (only-in racket/match/patterns bound-vars) - (only-in racket/match/gen-match go go/one))) + unstable/lazy-require)) + +(begin-for-syntax + (lazy-require [racket/match/patterns (bound-vars)] + [racket/match/gen-match (go parse-id go/one)])) (provide define-forms) From 808ef6e2863216f58e584323731dbfefd1409b87 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 26 Jul 2012 12:16:25 -0400 Subject: [PATCH 645/746] Revert "Use `unstable/lazy-require` to dynamically-load the compile-time of `match`." This reverts commit 8358420fccb78f4f2aa20117fcbdccd73e4afb3a. --- collects/racket/match/define-forms.rkt | 7 +--- collects/racket/match/match-expander.rkt | 20 +--------- collects/racket/match/match.rkt | 15 +++----- collects/racket/match/patterns.rkt | 49 ++++++++++++++++++++++-- collects/racket/match/struct.rkt | 17 ++++---- collects/racket/match/stxtime.rkt | 29 -------------- 6 files changed, 63 insertions(+), 74 deletions(-) delete mode 100644 collects/racket/match/stxtime.rkt diff --git a/collects/racket/match/define-forms.rkt b/collects/racket/match/define-forms.rkt index 61359627dc..0cdbd0c7b7 100644 --- a/collects/racket/match/define-forms.rkt +++ b/collects/racket/match/define-forms.rkt @@ -5,11 +5,8 @@ (only-in racket/list append* remove-duplicates) unstable/sequence syntax/parse - unstable/lazy-require)) - -(begin-for-syntax - (lazy-require [racket/match/patterns (bound-vars)] - [racket/match/gen-match (go parse-id go/one)])) + "patterns.rkt" + "gen-match.rkt")) (provide define-forms) diff --git a/collects/racket/match/match-expander.rkt b/collects/racket/match/match-expander.rkt index c40632dd9a..4cfee9aafc 100644 --- a/collects/racket/match/match-expander.rkt +++ b/collects/racket/match/match-expander.rkt @@ -1,26 +1,10 @@ #lang racket/base -(require (for-syntax racket/base "stxtime.rkt")) +(require (for-syntax racket/base + "patterns.rkt")) (provide define-match-expander) -(begin-for-syntax - (define make-match-expander - (let () - (define-struct match-expander (match-xform legacy-xform macro-xform) - #:property prop:set!-transformer - (λ (me stx) - (define xf (match-expander-macro-xform me)) - (if (set!-transformer? xf) - ((set!-transformer-procedure xf) stx) - (syntax-case stx (set!) - [(set! . _) - (raise-syntax-error #f "cannot mutate syntax identifier" stx)] - [_ (xf stx)]))) - #:property prop:match-expander (struct-field-index match-xform) - #:property prop:legacy-match-expander (struct-field-index legacy-xform)) - (values make-match-expander)))) - (define-syntax (define-match-expander stx) (define (lookup v alist) (cond [(assoc v alist) => cadr] diff --git a/collects/racket/match/match.rkt b/collects/racket/match/match.rkt index e16d9d236c..d619b62347 100644 --- a/collects/racket/match/match.rkt +++ b/collects/racket/match/match.rkt @@ -6,15 +6,11 @@ (only-in "match-expander.rkt" define-match-expander) "define-forms.rkt" - "struct.rkt" - (for-syntax unstable/lazy-require - (only-in "stxtime.rkt" + "struct.rkt" + (for-syntax "parse.rkt" + (only-in "patterns.rkt" match-...-nesting - prop:match-expander - prop:legacy-match-expander))) - -(begin-for-syntax - (lazy-require [racket/match/parse (parse)])) + prop:match-expander prop:legacy-match-expander))) (provide (for-syntax match-...-nesting prop:match-expander prop:legacy-match-expander) @@ -26,5 +22,4 @@ (define-forms parse match match* match-lambda match-lambda* match-lambda** match-let match-let* match-let-values match-let*-values - match-define match-define-values match-letrec match/values - match/derived match*/derived) + match-define match-define-values match-letrec match/values match/derived match*/derived) diff --git a/collects/racket/match/patterns.rkt b/collects/racket/match/patterns.rkt index 3763f6812e..d259986f1a 100644 --- a/collects/racket/match/patterns.rkt +++ b/collects/racket/match/patterns.rkt @@ -2,12 +2,9 @@ (require syntax/boundmap racket/contract - "stxtime.rkt" (for-syntax racket/base)) -(provide (except-out (combine-out - (all-defined-out) - (all-from-out "stxtime.rkt")) +(provide (except-out (all-defined-out) struct-key-ht get-key (struct-out Row))) @@ -179,6 +176,8 @@ [(Exact? p) null] [else (error 'match "bad pattern: ~a" p)])) +(define match-...-nesting (make-parameter 0)) + (define current-renaming (make-parameter (make-free-identifier-mapping))) (define (copy-mapping ht) @@ -209,3 +208,45 @@ [vars-seen (listof (cons/c identifier? identifier?))]))) + +(struct acc-prop (n acc)) +(define (make-struct-type-property/accessor name [guard #f] [supers null]) + (define-values (p pred? acc) + (make-struct-type-property name + (λ (pval sinfo) + (cond [(exact-nonnegative-integer? pval) + (acc-prop pval (cadddr sinfo))] + [else (if (procedure? guard) + (guard pval sinfo) + pval)])) + supers)) + (values p pred? (lambda (v) + (define v* (acc v)) + (if (acc-prop? v*) + ((acc-prop-acc v*) v (acc-prop-n v*)) + v*)))) + +(define-values (prop:match-expander match-expander? match-expander-proc) + (make-struct-type-property/accessor 'prop:match-expander)) + +(define-values (prop:legacy-match-expander legacy-match-expander? legacy-match-expander-proc) + (make-struct-type-property/accessor 'prop:legacy-match-expander )) + +(define make-match-expander + (let () + (define-struct match-expander (match-xform legacy-xform macro-xform) + #:property prop:set!-transformer (lambda (me stx) + (define xf (match-expander-macro-xform me)) + (if (set!-transformer? xf) + ((set!-transformer-procedure xf) stx) + (syntax-case stx (set!) + [(set! . _) + (raise-syntax-error #f "cannot mutate syntax identifier" stx)] + [_ (xf stx)]))) + #:property prop:match-expander (struct-field-index match-xform) + #:property prop:legacy-match-expander (struct-field-index legacy-xform)) + (values make-match-expander))) + +(provide match-expander? legacy-match-expander? + match-expander-proc legacy-match-expander-proc + prop:match-expander prop:legacy-match-expander) diff --git a/collects/racket/match/struct.rkt b/collects/racket/match/struct.rkt index 8b34d24cc3..5266e51c3f 100644 --- a/collects/racket/match/struct.rkt +++ b/collects/racket/match/struct.rkt @@ -2,7 +2,7 @@ (require racket/match/match-expander (for-syntax racket/base racket/struct-info - syntax/id-table + syntax/boundmap racket/list)) (define-match-expander @@ -17,7 +17,7 @@ [v (if (identifier? #'struct-name) (syntax-local-value #'struct-name fail) (fail))] - [field-acc->pattern (make-free-id-table)]) + [field-acc->pattern (make-free-identifier-mapping)]) (unless (struct-info? v) (fail)) ; Check each pattern and capture the field-accessor name (for-each (lambda (an) @@ -34,9 +34,9 @@ (syntax-e #'struct-name) (syntax-e #'field))) #'field)]) - (when (free-id-table-ref field-acc->pattern field-acc #f) + (when (free-identifier-mapping-get field-acc->pattern field-acc (lambda () #f)) (raise-syntax-error 'struct* "Field name appears twice" stx #'field)) - (free-id-table-set! field-acc->pattern field-acc #'pat))] + (free-identifier-mapping-put! field-acc->pattern field-acc #'pat))] [_ (raise-syntax-error 'struct* "expected a field pattern of the form ( )" @@ -54,13 +54,14 @@ [pats-in-order (for/list ([field-acc (in-list acc)]) (begin0 - (free-id-table-ref + (free-identifier-mapping-get field-acc->pattern field-acc - (syntax/loc stx _)) + (lambda () (syntax/loc stx _))) ; Use up pattern - (free-id-table-remove! field-acc->pattern field-acc)))]) + (free-identifier-mapping-put! + field-acc->pattern field-acc #f)))]) ; Check that all patterns were used - (free-id-table-for-each + (free-identifier-mapping-for-each field-acc->pattern (lambda (field-acc pat) (when pat diff --git a/collects/racket/match/stxtime.rkt b/collects/racket/match/stxtime.rkt deleted file mode 100644 index 9c2a5e3fe2..0000000000 --- a/collects/racket/match/stxtime.rkt +++ /dev/null @@ -1,29 +0,0 @@ -#lang racket/base - -(provide (all-defined-out)) - -(define match-...-nesting (make-parameter 0)) - -(struct acc-prop (n acc)) - -(define (make-struct-type-property/accessor name [guard #f] [supers null]) - (define-values (p pred? acc) - (make-struct-type-property name - (λ (pval sinfo) - (cond [(exact-nonnegative-integer? pval) - (acc-prop pval (cadddr sinfo))] - [else (if (procedure? guard) - (guard pval sinfo) - pval)])) - supers)) - (values p pred? (lambda (v) - (define v* (acc v)) - (if (acc-prop? v*) - ((acc-prop-acc v*) v (acc-prop-n v*)) - v*)))) - -(define-values (prop:match-expander match-expander? match-expander-proc) - (make-struct-type-property/accessor 'prop:match-expander)) - -(define-values (prop:legacy-match-expander legacy-match-expander? legacy-match-expander-proc) - (make-struct-type-property/accessor 'prop:legacy-match-expander )) From 2827a3e28045c0c90b3a4164adfc1a274b1d1eaf Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 26 Jul 2012 10:53:56 -0600 Subject: [PATCH 646/746] another repair to `subprocess' test Merge to v5.3 (cherry picked from commit 100212cd53189f27efb0bde8b7fb47e1e86a04aa) --- collects/tests/racket/subprocess.rktl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collects/tests/racket/subprocess.rktl b/collects/tests/racket/subprocess.rktl index 5661042d0f..f60af9af4e 100644 --- a/collects/tests/racket/subprocess.rktl +++ b/collects/tests/racket/subprocess.rktl @@ -392,9 +392,11 @@ (let ([c (make-custodian)]) (let ([l (parameterize ([current-custodian c]) (process* self + "-e" "0" "-e" "(let loop () (loop))"))]) (test 'running (list-ref l 4) 'status) + (read-line (car l)) ; wait until running (custodian-shutdown-all c) (sleep 0.1) (when (and wait? From 19acbbf4bc39aaeb77c6f398d7162c0f84ea20c8 Mon Sep 17 00:00:00 2001 From: John Clements Date: Thu, 26 Jul 2012 14:50:14 -0400 Subject: [PATCH 647/746] release notes update for stepper. please merge to 5.3 release. (cherry picked from commit 8ba976c0351701db0f45a92f9f5fdc1ce4ec01e6) --- doc/release-notes/stepper/HISTORY.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes/stepper/HISTORY.txt b/doc/release-notes/stepper/HISTORY.txt index b8565b54a9..af9cc453b1 100644 --- a/doc/release-notes/stepper/HISTORY.txt +++ b/doc/release-notes/stepper/HISTORY.txt @@ -3,7 +3,7 @@ Stepper Changes for 5.3: -None. +At least one bug fix. Changes for v5.2.1: From 7a49919608d4e9ebb1dd548d5b2361d5a24c262c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 26 Jul 2012 16:31:17 -0600 Subject: [PATCH 648/746] fix for bytecode validator Fix tchecking for a rest argument to a function that is lifted by closure conversion so that one of its arguments is a mutable local variable's location. Also reject bytecode that would pass too many arguments to a lifted function, since that would trigger an arity error that might try to use a location as a value. Merge to v5.3 (cherry picked from commit 9d6f0e96ba3fca6c611f463e7172f00a32b61a06) --- collects/tests/racket/optimize.rktl | 20 ++++++++++++++++++++ src/racket/src/validate.c | 9 +++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/collects/tests/racket/optimize.rktl b/collects/tests/racket/optimize.rktl index 4bd46570cc..d7d367a58e 100644 --- a/collects/tests/racket/optimize.rktl +++ b/collects/tests/racket/optimize.rktl @@ -2108,6 +2108,26 @@ (parse-string "()")) (err/rt-test (do-test-of-lift-fixpoint) exn:fail?) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; generate byecode with a lifted function that has +;; a boxed argument and rest args, to test that case +;; of the validator + +(parameterize ([current-namespace (make-base-namespace)]) + (define o (open-output-bytes)) + (write + (compile + '(lambda (x) + (define (g . y) (if (zero? (random 1)) + (reverse (cons x y)) + (g y y y y y y y y y))) + (set! x x) + (g 12 13))) + o) + (test '(13 12 10) + (parameterize ([read-accept-compiled #t]) + (eval (read (open-input-bytes (get-output-bytes o))))) + 10)) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/racket/src/validate.c b/src/racket/src/validate.c index 7d006d2edb..18d0372fc3 100644 --- a/src/racket/src/validate.c +++ b/src/racket/src/validate.c @@ -242,8 +242,9 @@ static void define_values_validate(Scheme_Object *data, Mz_CPort *port, if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_TYPED_ARGS) { int sz; sz = data->num_params; - new_a = MALLOC_N_ATOMIC(mzshort, (sz + 1)); + new_a = MALLOC_N_ATOMIC(mzshort, (sz + 2)); new_a[0] = -sz; + new_a[sz+1] = !!(SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST); for (i = 0; i < sz; i++) { int bit = ((mzshort)1 << ((2 * i) & (BITS_PER_MZSHORT - 1))); if (data->closure_map[data->closure_size + ((2 * i) / BITS_PER_MZSHORT)] & bit) @@ -623,7 +624,11 @@ int scheme_validate_rator_wants_box(Scheme_Object *app_rator, int pos, /* try again */ p = a[1]; } else { - return a[pos + 1]; + if (pos >= -a[0]) { + /* last slot indicates whether rest args are allowed */ + return (a[-a[0]+1] ? hope : !hope); + } else + return a[pos + 1]; } } else return 0; From 98282ae667af09deb9a15321155a853a7c6474f2 Mon Sep 17 00:00:00 2001 From: John Clements Date: Thu, 26 Jul 2012 23:21:04 -0400 Subject: [PATCH 649/746] rewording of release notes message. Merge to 5.3. (cherry picked from commit a5ebf8181b99e152028c8e59a31b641f56ad5560) --- doc/release-notes/stepper/HISTORY.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes/stepper/HISTORY.txt b/doc/release-notes/stepper/HISTORY.txt index af9cc453b1..cc7534f783 100644 --- a/doc/release-notes/stepper/HISTORY.txt +++ b/doc/release-notes/stepper/HISTORY.txt @@ -3,7 +3,7 @@ Stepper Changes for 5.3: -At least one bug fix. +Minor bug fixes. Changes for v5.2.1: From 135aba7dbc8ce9b4ed3151a9b67197d6bd5f4c14 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 27 Jul 2012 10:31:46 -0400 Subject: [PATCH 650/746] Update self-test checksup for revized "racket -h" text. (cherry picked from commit 7e4e37391932cae59fc6326c843cb56613818fc5) --- collects/meta/contrib/completion/racket-completion.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/meta/contrib/completion/racket-completion.zsh b/collects/meta/contrib/completion/racket-completion.zsh index acefd3bc4b..06088a55ea 100644 --- a/collects/meta/contrib/completion/racket-completion.zsh +++ b/collects/meta/contrib/completion/racket-completion.zsh @@ -115,7 +115,7 @@ _racket_self_test() { ############################################################################### -_racket_self_test 'racket:1847339606:grep -v "Welcome to Racket"' +_racket_self_test 'racket:1580018499:grep -v "Welcome to Racket"' RACKET_COMMON=( -C -s -w -S : '(- : *)'{-h,--help}'[Display help]' ) RACKET_ARGS=( "$RACKET_COMMON[@]" ) From 12349ed6e221a38e7b07cfc09935b063e61f13e4 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 27 Jul 2012 10:35:00 -0400 Subject: [PATCH 651/746] Put the main work in a `main' sub-module. This should avoid re-checking the zo file at the end, leading to an error when it's not there if it moved. (cherry picked from commit c408dfb03b7f4b4901c3429389c4ed7cd3e5d6bc) --- collects/setup/unixstyle-install.rkt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/collects/setup/unixstyle-install.rkt b/collects/setup/unixstyle-install.rkt index fed79ba1ce..2fb201398e 100644 --- a/collects/setup/unixstyle-install.rkt +++ b/collects/setup/unixstyle-install.rkt @@ -450,9 +450,10 @@ ;; -------------------------------------------------------------------------- -(case op - [(move) (move/copy-distribution #t)] - [(copy) (move/copy-distribution #f)] - [(make-install-copytree) (make-install-copytree)] - [(make-install-destdir-fix) (make-install-destdir-fix)] - [else (error (format "unknown operation: ~e" op))]) +(module+ main + (case op + [(move) (move/copy-distribution #t)] + [(copy) (move/copy-distribution #f)] + [(make-install-copytree) (make-install-copytree)] + [(make-install-destdir-fix) (make-install-destdir-fix)] + [else (error (format "unknown operation: ~e" op))])) From c909785f6d568949f07b69cba4036ba04554fcf8 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 28 Jul 2012 00:20:20 -0500 Subject: [PATCH 652/746] add some simpler exercises to start and link to existing introductory Racket tutorials (cherry picked from commit 63dc75145081b284346448a891e63fe483b74c54) --- collects/redex/scribblings/tut.scrbl | 33 +++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/collects/redex/scribblings/tut.scrbl b/collects/redex/scribblings/tut.scrbl index 14a10b3d16..183aecdad8 100644 --- a/collects/redex/scribblings/tut.scrbl +++ b/collects/redex/scribblings/tut.scrbl @@ -89,11 +89,15 @@ @title[#:tag "tutorial"]{Amb: A Redex Tutorial} This tutorial is designed for those familiar with the call-by-value -λ-calculus (and evaluation contexts), but not Redex or Racket. +λ-calculus (and evaluation contexts), but not Redex. The tutorial works though a model of the λ-calculus extended with a variation on McCarthy's @racket[amb] operator for ambiguous choice@~cite[amb1 amb2]. +If you are not familiar with Racket, first try +@other-doc['(lib "quick.scrbl" "scribblings/quick")] or +@other-doc['(lib "more.scrbl" "scribblings/more")]. + The model includes a standard evaluation reduction relation and a type system. Along the way, the tutorial demonstrates Redex's support for unit testing, random testing, typesetting, metafunctions, reduction relations, @@ -212,6 +216,20 @@ elements of the sequence in different ways: (+ 5 6)))) (list/c match? match? match?)] +@exercise[] + +Use @racket[redex-match] to extract the body of the +function from this object-language program: +@racketblock[((λ (x) (+ x 1)) + 17)] + +@exercise[] + +Use @racket[redex-match] to extract the range portion +of the type +@racket[(→ num (→ num num))]. + + @exercise[] Redex's pattern language supports ambiguity through non-terminals, @@ -223,6 +241,19 @@ then you'd expect one match for 1 & 2, one match for 2 & 3, and one match for 3 In general, this pattern should produce n matches when there are n+1 expressions in the sequence. +To test your solution use @racket[redex-match] like this: +@racketblock[(redex-match + L + (code:comment @#,t{your solution goes here}) + (term (1 2 3 4)))] +where you expect a result like this +@racketblock[(list + (match (list (bind 'e_1 1) (bind 'e_2 2))) + (match (list (bind 'e_1 2) (bind 'e_2 3))) + (match (list (bind 'e_1 3) (bind 'e_2 4))))] +but possibly with more pattern variables in the resulting +match. + @amb/test[(redex-match L (e_1 ... e_2 e_3 e_4 ...) From ac75555ecb5913dc4b155d75654e1d91319765ac Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 27 Jul 2012 22:50:56 -0400 Subject: [PATCH 653/746] Minor fix for the installer tests. The last "xrepl" might be at the BOL, with no preceding space. (cherry picked from commit 5b501da1316e2612a37003aea3e2d0f9076486ab) --- collects/meta/build/unix-installer/test-installer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/meta/build/unix-installer/test-installer b/collects/meta/build/unix-installer/test-installer index 7014ecd1b0..4f753167d9 100755 --- a/collects/meta/build/unix-installer/test-installer +++ b/collects/meta/build/unix-installer/test-installer @@ -319,7 +319,7 @@ exec racket "$0" "$@" buildinfo, collects/, mzdyn3m.o, starter* sh> @i{LS share/r* && LS share/r*/doc} doc/ - README, @... xrepl/ + README, @|...|xrepl/ sh> @i{LS share/man && LS share/man/man1} man1/ drracket.1, gracket.1, mred.1, mzc.1, mzscheme.1, plt-help.1, racket.1, From 751e20b3ea64f5251cc7b455e2a5d38236cbf0fb Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 28 Jul 2012 05:04:55 -0400 Subject: [PATCH 654/746] Adjust for new error mesage style. (This is in part a temporary solution since the ",bt" command is now used to show a backtrace as well as any "foo...:" hidden fields.) (cherry picked from commit c2bea19d1beacd514eb313bfbf7603c69099bffd) --- collects/tests/xrepl/xrepl.rkt | 31 ++++++++++++++++++++++++------- collects/xrepl/xrepl.rkt | 14 +++++++++++--- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/collects/tests/xrepl/xrepl.rkt b/collects/tests/xrepl/xrepl.rkt index a9e6e92b68..9d832d0e50 100644 --- a/collects/tests/xrepl/xrepl.rkt +++ b/collects/tests/xrepl/xrepl.rkt @@ -1,5 +1,12 @@ #lang at-exp racket/base +;; General note for anyone who tries to run these tests: since the tests check +;; interactions it can be hard to find the problem, and sometimes it's best to +;; just comment a suffix of the tests to find it. In addition, when it fails +;; it tries to provide information that helps finding the problem, but +;; sometimes there's very little help, and it might also fail by just getting +;; stuck. + (define verbose? (make-parameter #f)) (define global-ns (current-namespace)) @@ -102,11 +109,15 @@ 'foo> «,top» -> «(define enter! 123)» -> «(enter! 'foo)» - ; procedure application: expected procedure, given: 123; arguments were: 'foo - ; [,bt for context] + ; application: not a procedure; + ; expected a procedure that can be applied to arguments + ; given: 123 + ; [,bt for context] -> «(enter! 'fooo)» - ; procedure application: expected procedure, given: 123; arguments were: - ; 'fooo [,bt for context] + ; application: not a procedure; + ; expected a procedure that can be applied to arguments + ; given: 123 + ; [,bt for context] -> «,en foo» ⇒ but this still works 'foo> «,top» -> «,switch foo» @@ -121,7 +132,9 @@ typed/racket::-> «,switch *» ; *** Switching to the `*' namespace *** -> «bleh» - ; reference to undefined identifier: bleh [,bt for context] + ; bleh: undefined; + ; cannot reference undefined identifier + ; [,bt for context] -> «,ap BLEH» ; No matches found. -> «,ap path->» @@ -157,12 +170,16 @@ 123 ⇒ ...but we still got in 'broken> «,top» -> «string->jsexpr» - ; reference to undefined identifier: string->jsexpr [,bt for context] + ; string->jsexpr: undefined; + ; cannot reference undefined identifier + ; [,bt for context] -> «,r (only-in json string->jsexpr)» ⇒ works with an expression -> «string->jsexpr» #jsexpr> -> «jsexpr->string» ⇒ didn't get this - ; reference to undefined identifier: jsexpr->string [,bt for context] + ; jsexpr->string: undefined; + ; cannot reference undefined identifier + ; [,bt for context] -> «,en json» json/main> «,sh echo $F» @|collects|/json/main.rkt diff --git a/collects/xrepl/xrepl.rkt b/collects/xrepl/xrepl.rkt index 6c7d30ad33..4b79ea18c5 100644 --- a/collects/xrepl/xrepl.rkt +++ b/collects/xrepl/xrepl.rkt @@ -1459,12 +1459,20 @@ (let* ([s (get-output-string (current-error-port))] [s (regexp-replace* #rx"^\n+|\n+$" s "")] [s (regexp-replace* #rx"\n\n+" s "\n")]) - (and (not (equal? str s)) + ;; temporary hack: this is always on since it shows all fields, + ;; so ",bt" is now really a generic "more info" + (and ; (not (equal? str s)) (begin (set! last-backtrace s) #t))))) (define msg "[,bt for context]") (parameterize ([current-output-port (current-error-port)]) - (with-wrapped-output - (if backtrace? (printf "; ~a ~a\n" str msg) (printf "; ~a\n" str))))) + (let* ([s (regexp-replace* #rx"^\n+|\n+$" str "")] + [s (regexp-replace* #rx"\n\n+" s "\n")] + [s (regexp-replace* #rx"\n [^\n]+\\.\\.\\.:(?:[^\n]+|\n )+" s "")] + [s (regexp-replace* #rx"\n" s "\n; ")] + [s (if backtrace? + (string-append s (if (regexp-match? #rx"\n" s) "\n; " " ") msg) + s)]) + (with-wrapped-output (printf "; ~a\n" s))))) ;; ---------------------------------------------------------------------------- ;; set up the xrepl environment From e475d9291063a6edec1d8e23bbd35f4e13644149 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Jul 2012 11:06:25 -0600 Subject: [PATCH 655/746] fix interaction of place-channel receive and GC Avoid holding onto a pointer into a place-message page beyond receipt of the message. Merge to v5.3 (cherry picked from commit 8fc008c5694a4dbea6d6c6065d5050458e59b07b) --- src/racket/src/place.c | 44 +++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/racket/src/place.c b/src/racket/src/place.c index fd092c1164..b7c79468d6 100644 --- a/src/racket/src/place.c +++ b/src/racket/src/place.c @@ -2589,7 +2589,11 @@ static Scheme_Object *places_serialize(Scheme_Object *so, void **msg_memory, Sch #endif } -Scheme_Object *scheme_places_deserialize(Scheme_Object *so, void *msg_memory) { +Scheme_Object *scheme_places_deserialize(Scheme_Object *so, void *msg_memory) +/* The caller must immediately drop any reference to `so' and + `msg_memory' after this function returns; otherwise, since the + `msg_memory' page may be deallocated, a GC could crash. */ +{ #if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) Scheme_Object *new_so = so; @@ -2600,6 +2604,8 @@ Scheme_Object *scheme_places_deserialize(Scheme_Object *so, void *msg_memory) { if (GC_message_objects_size(msg_memory) < 1024) { new_so = do_places_deep_copy(so, mzPDC_UNCOPY, 1, NULL, NULL); GC_dispose_short_message_allocator(msg_memory); + /* from this point, we must return immediately, so that any + reference to `so' can be dropped before GC. */ msg_memory = NULL; } else { @@ -3096,7 +3102,9 @@ static void register_place_object_with_channel(Scheme_Place_Async_Channel *ch, S } } -static Scheme_Object *scheme_place_async_try_receive_raw(Scheme_Place_Async_Channel *ch, void **msg_memory_ptr) { +static Scheme_Object *scheme_place_async_try_receive_raw(Scheme_Place_Async_Channel *ch, void **msg_memory_ptr) +/* The result must not be retained past extraction from `*msg_memory_ptr'! */ +{ Scheme_Object *msg = NULL; void *msg_memory = NULL; intptr_t sz; @@ -3160,18 +3168,19 @@ static int scheme_place_async_ch_ready(Scheme_Place_Async_Channel *ch) { mzrt_mutex_unlock(ch->lock); return ready; } -static Scheme_Object *place_channel_finish_ready(void *d, int argc, struct Scheme_Object *argv[]) { + +static Scheme_Object *place_channel_finish_ready(void *d, int argc, struct Scheme_Object *argv[]) +{ Scheme_Object *msg; + Scheme_Thread *p = scheme_current_thread; - msg = argv[0]; + msg = *(Scheme_Object **)d; + + BEGIN_ESCAPEABLE(cleanup_msg_memmory, p); + msg = scheme_places_deserialize(msg, p->place_channel_msg_in_flight); + p->place_channel_msg_in_flight = NULL; + END_ESCAPEABLE(); - if (msg) { - Scheme_Thread *p = scheme_current_thread; - BEGIN_ESCAPEABLE(cleanup_msg_memmory, p); - msg = scheme_places_deserialize(msg, p->place_channel_msg_in_flight); - p->place_channel_msg_in_flight = NULL; - END_ESCAPEABLE(); - } return msg; } @@ -3189,10 +3198,19 @@ static int place_channel_ready(Scheme_Object *so, Scheme_Schedule_Info *sinfo) { msg = scheme_place_async_try_receive_raw((Scheme_Place_Async_Channel *) ch->recvch, &msg_memory); if (msg != NULL) { + Scheme_Object **msg_holder; Scheme_Thread *p = ((Syncing *)(sinfo->current_syncing))->thread; + + /* Hold `msg' in atomic memory, because we're not allowed to hold onto + it beyond release of msg_memory, and `wrapper' and the result + flow into the evt system in general. */ + msg_holder = (Scheme_Object **)scheme_malloc_atomic(sizeof(Scheme_Object*)); + *msg_holder = msg; + p->place_channel_msg_in_flight = msg_memory; - wrapper = scheme_make_closed_prim(place_channel_finish_ready, NULL); - scheme_set_sync_target(sinfo, msg, wrapper, NULL, 0, 0, NULL); + wrapper = scheme_make_closed_prim(place_channel_finish_ready, msg_holder); + scheme_set_sync_target(sinfo, scheme_void, wrapper, NULL, 0, 0, NULL); + return 1; } return 0; From c0b1c96850a10848d86a0768210d37515b1b1bc2 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sat, 28 Jul 2012 16:40:38 -0400 Subject: [PATCH 656/746] fix name of function in docs Closes PR 12950 (cherry picked from commit d19137c998f077f762a462a634536090d14a5841) --- collects/scribblings/reference/syntax-util.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/reference/syntax-util.scrbl b/collects/scribblings/reference/syntax-util.scrbl index 925ec67a72..083721748e 100644 --- a/collects/scribblings/reference/syntax-util.scrbl +++ b/collects/scribblings/reference/syntax-util.scrbl @@ -144,7 +144,7 @@ forms like @racket[with-disappeared-uses]. #:contracts ([stx-expr syntax?])]{ Evaluates the @racket[stx-expr], catching identifiers looked up using -@racket[syntax-local-value/catch]. Adds the caught identifiers to the +@racket[syntax-local-value/record]. Adds the caught identifiers to the @racket['disappeared-uses] syntax property of the resulting syntax object. } From 98a4002c64e8f103f0919d71ce7353591bf05f03 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sat, 28 Jul 2012 17:34:11 -0400 Subject: [PATCH 657/746] syntax/parse: fix bug in specialized code for ellipsis patterns The result of 'stx->list' is not always either a list or #f. Merge to 5.3. (cherry picked from commit e10951024f0944dfa60b3ed10b0fcc058115275b) --- .../syntax/parse/experimental/private/substitute.rkt | 2 +- collects/syntax/parse/private/residual.rkt | 2 +- collects/tests/stxparse/test.rkt | 11 +++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/collects/syntax/parse/experimental/private/substitute.rkt b/collects/syntax/parse/experimental/private/substitute.rkt index 013fe908c4..b05447c6b3 100644 --- a/collects/syntax/parse/experimental/private/substitute.rkt +++ b/collects/syntax/parse/experimental/private/substitute.rkt @@ -222,7 +222,7 @@ A HeadGuide (HG) is one of: (lambda (env lenv) (let* ([v (f1 env lenv)] [v* (stx->list v)]) - (unless v* + (unless (list? v*) (raise-syntax-error 'template "splicing template did not produce a syntax list" stx)) diff --git a/collects/syntax/parse/private/residual.rkt b/collects/syntax/parse/private/residual.rkt index f0ffd4456e..b9ef9bc0a3 100644 --- a/collects/syntax/parse/private/residual.rkt +++ b/collects/syntax/parse/private/residual.rkt @@ -205,7 +205,7 @@ (define (predicate-ellipsis-parser x cx pr es pred? desc rl) (let ([elems (stx->list x)]) - (if (and elems (andmap pred? elems)) + (if (and elems (list? elems) (andmap pred? elems)) (values 'ok elems) (let loop ([x x] [cx cx] [i 0]) (cond [(syntax? x) diff --git a/collects/tests/stxparse/test.rkt b/collects/tests/stxparse/test.rkt index 717c77026e..2aeecb5fa2 100644 --- a/collects/tests/stxparse/test.rkt +++ b/collects/tests/stxparse/test.rkt @@ -459,3 +459,14 @@ (not #rx"expected foo") ;; y:nat was incorrectly considered part of opaque region #rx"expected exact-nonnegative-integer") ) + +;; from Neil Van Dyke (7/28/2012) +(test-case "specialized predicate-ellipsis-parser" + ;; test that it works on improper lists + ;; ... when input is syntax + (check-eq? (syntax-parse #'(a b c . d) [(x:id ...) #t] [_ #f]) #f) + ;; ... and when input is stx pair (but not syntax) + (check-eq? (syntax-parse #'(a b c . d) [(_ x:id ...) #t] [_ #f]) #f) + ;; test that it works on proper lists w/ embedded stxpairs + (check-eq? (syntax-parse #'(a b . (c d)) [(x:id ...) #t] [_ #f]) #t) + (check-eq? (syntax-parse #'(a b . (c d)) [(_ x:id ...) #t] [_ #f]) #t)) From e6b30307974c37d285b8d9e2f76bac52ae3db67a Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 29 Jul 2012 08:27:10 -0400 Subject: [PATCH 658/746] Add "download-libs.rkt" to the core sources. (cherry picked from commit a0e6892d3e8450732f8f96815d1838b41f839f0b) --- collects/meta/dist-specs.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/meta/dist-specs.rkt b/collects/meta/dist-specs.rkt index 44beb41e4f..567160f147 100644 --- a/collects/meta/dist-specs.rkt +++ b/collects/meta/dist-specs.rkt @@ -391,7 +391,7 @@ mz-tests := (tests: "info.rkt" "racket/" "utils/" "match/" ;; Source definitions mz-src := (+ (- (src: "README" "configure" "Makefile.in" "lt/" "racket/" - "get-libs.rkt" "utils/" + "get-libs.rkt" "download-libs.rkt" "utils/" (cond win => "worksp/{README|mzconfig.h}" "worksp/{build.bat|rbuildmode.c}" "worksp/{racket|libracket}/" From 5590615edbdb98c2a51fd343f00fb075f2d91617 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 29 Jul 2012 09:02:58 -0400 Subject: [PATCH 659/746] Fix parametric require/typed in typed/racket/base. Closes PR12951. Please merge to release. (cherry picked from commit dd02f5eedaaea8077e36e38511e0af1998b5f94f) --- .../tests/typed-racket/succeed/parametric-require-tr-base.rkt | 4 ++++ collects/typed-racket/typed-racket.rkt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 collects/tests/typed-racket/succeed/parametric-require-tr-base.rkt diff --git a/collects/tests/typed-racket/succeed/parametric-require-tr-base.rkt b/collects/tests/typed-racket/succeed/parametric-require-tr-base.rkt new file mode 100644 index 0000000000..e27eb677d9 --- /dev/null +++ b/collects/tests/typed-racket/succeed/parametric-require-tr-base.rkt @@ -0,0 +1,4 @@ +#lang typed/racket/base + +(require/typed racket/base + (values (All (a) (a -> a)))) diff --git a/collects/typed-racket/typed-racket.rkt b/collects/typed-racket/typed-racket.rkt index 6476ddd8f0..40f8d49b6a 100644 --- a/collects/typed-racket/typed-racket.rkt +++ b/collects/typed-racket/typed-racket.rkt @@ -7,7 +7,7 @@ ;; that may appear in the residual program "utils/utils.rkt" (for-syntax "utils/utils.rkt") - "utils/any-wrap.rkt" unstable/contract) + "utils/any-wrap.rkt" unstable/contract racket/contract/parametric) (provide (rename-out [module-begin #%module-begin] [top-interaction #%top-interaction]) From c9b834353a0b3abb5fdf023a6fa41dc5f589f51c Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 24 Jul 2012 16:21:39 -0400 Subject: [PATCH 660/746] Fix type for add-between. (cherry picked from commit b1577bd307ac1c8136630a3949755f833a8073d2) --- collects/tests/typed-racket/unit-tests/typecheck-tests.rkt | 2 +- collects/typed-racket/base-env/base-env.rkt | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/collects/tests/typed-racket/unit-tests/typecheck-tests.rkt b/collects/tests/typed-racket/unit-tests/typecheck-tests.rkt index a462f91c67..1974ce03a8 100644 --- a/collects/tests/typed-racket/unit-tests/typecheck-tests.rkt +++ b/collects/tests/typed-racket/unit-tests/typecheck-tests.rkt @@ -368,7 +368,7 @@ [tc-e (string-join '("hello" "world") #:before-first "a") -String] [tc-e (add-between '(1 2 3) 0) (-lst -Byte)] [tc-e (add-between '(1 2 3) 'a) (-lst (t:Un -PosByte (-val 'a)))] - [tc-e ((inst add-between Positive-Byte Symbol) '(1 2 3) 'a #:before-first 'b) (-lst (t:Un -PosByte -Symbol))] + [tc-e ((inst add-between Positive-Byte Symbol) '(1 2 3) 'a #:splice? #t #:before-first '(b)) (-lst (t:Un -PosByte -Symbol))] [tc-e (apply (plambda: (a) [x : a *] x) '(5)) (-lst -PosByte)] [tc-e (apply append (list '(1 2 3) '(4 5 6))) (-lst -PosByte)] diff --git a/collects/typed-racket/base-env/base-env.rkt b/collects/typed-racket/base-env/base-env.rkt index 3da407c37e..f32a2346a4 100644 --- a/collects/typed-racket/base-env/base-env.rkt +++ b/collects/typed-racket/base-env/base-env.rkt @@ -1426,10 +1426,9 @@ [last (-poly (a) ((-lst a) . -> . a))] [add-between (-poly (a b) ((-lst a) b #:splice? -Boolean #f - #:nothing Univ #f ; default is gensym - #:before-first b #f + #:before-first (-lst b) #f #:before-last b #f - #:after-last b #f + #:after-last (-lst b) #f . ->key . (-lst (Un a b))))] [last-pair (-poly (a) ((-mu x (Un a (-val '()) (-pair a x))) From d68afc364d3e49cc3486470d6802d4a4f39a7952 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 29 Jul 2012 06:52:47 -0600 Subject: [PATCH 661/746] ffi/com: fix clean-up of type descriptors Merge to v5.3 (cherry picked from commit 9b1db143283a96c548c33e04260e3379a2fbcebd) --- collects/ffi/unsafe/com.rkt | 57 ++++++++++++++++++++++------------- collects/tests/racket/com.rkt | 4 +++ 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index 5fa6b43a22..190ed51e23 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -247,12 +247,21 @@ [(_ (#:release-with-method name) expr obj arg ...) (let ([self obj]) (((allocator (lambda (v) (name self v))) - expr) + (let ([f expr]) + (lambda args + (AddRef self) + (apply f args)))) self arg ...))] - [(_ (#:releases) expr arg ...) - (((deallocator cadr) expr) arg ...)])) - + [(_ (#:releases) expr obj arg ...) + (let ([self obj]) + (((deallocator cadr) + (let ([f expr]) + (lambda args + (Release self) + (apply f args)))) + self arg ...))])) + (define (check-com-type who id id? obj) (unless (id? obj) (raise-type-error who (symbol->string id) obj))) @@ -630,9 +639,27 @@ set-com-object-connection-point!) (bye! com-object-sink set-com-object-sink!) - (when (hash-count (com-object-types obj)) + (when (positive? (hash-count (com-object-types obj))) + (for ([td (in-hash-values (com-object-types obj))]) + '(release-type-desc td)) (set-com-object-types! obj (make-hash)))))) +(define (release-type-desc td) + ;; call in atomic mode + (define type-info (mx-com-type-desc-type-info td)) + (define type-info-impl (mx-com-type-desc-type-info-impl td)) + (define tdd (mx-com-type-desc-desc td)) + (cond + [(list? tdd) + (ReleaseFuncDesc type-info (car tdd)) + (when type-info-impl + (ReleaseFuncDesc type-info-impl (cadr tdd)))] + [else + (ReleaseVarDesc type-info tdd)]) + (Release type-info) + (when type-info-impl + (Release type-info-impl))) + (define (gen->clsid who name) (cond [(clsid? name) name] @@ -876,12 +903,9 @@ string-ci () string) (com-get-property-type doc "title")) (test '(-> (string) void) (com-set-property-type doc "title")) + (test (void) (com-set-property! ie "Visible" #t)) + (test (void) (com-invoke ie "Quit")) + + (test (void) (com-release doc)) (test (void) (com-release ie)) (test #t (type-description? 'int)) From fc9da78f41ce965ec02f4ae2471e08cd05d46b6c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 30 Jul 2012 04:17:22 -0500 Subject: [PATCH 662/746] adjust check-expect so it rewrites the error messages like they are rewritten in the repl closes PR 12943 (cherry picked from commit 87a8f7014881eab93c0d8685e61d53f9457e7d27) --- collects/test-engine/racket-tests.rkt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/collects/test-engine/racket-tests.rkt b/collects/test-engine/racket-tests.rkt index a40e80b36f..54ea14abe0 100644 --- a/collects/test-engine/racket-tests.rkt +++ b/collects/test-engine/racket-tests.rkt @@ -4,11 +4,11 @@ (for-syntax lang/private/rewrite-error-message) scheme/class scheme/match - lang/private/continuation-mark-key + lang/private/continuation-mark-key + lang/private/rewrite-error-message (only-in scheme/base for memf findf) "test-engine.rkt" - "test-info.scm" - ) + "test-info.scm") (require (for-syntax stepper/private/syntax-property)) @@ -291,7 +291,7 @@ (lambda (e) (let ([display (error-display-handler)]) (list (make-unexpected-error src (test-format) expect - (exn-message e) + (get-rewriten-error-message e) e) 'error e)))]) From f64438371fe9cd1e8e4e7c671a3bc842a4550fed Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 31 Jul 2012 22:24:45 -0500 Subject: [PATCH 663/746] add a test case for check-expect expressions where the first position has an error test case for commit 87a8f7014881eab93c0d8685e61d53f9457e7d27 related to PR 12943 (cherry picked from commit 2032aaf341d0c047daf8a51905d1267311c91f1a) --- collects/tests/drracket/test-engine-test.rkt | 87 ++++++++++++-------- 1 file changed, 54 insertions(+), 33 deletions(-) diff --git a/collects/tests/drracket/test-engine-test.rkt b/collects/tests/drracket/test-engine-test.rkt index 4d7442efd0..9d3cb1d06e 100644 --- a/collects/tests/drracket/test-engine-test.rkt +++ b/collects/tests/drracket/test-engine-test.rkt @@ -12,21 +12,29 @@ (define (set-language close-dialog?) (set-language-level! (language) close-dialog?)) -(define (common-test-engine) - (test-expression "(check-expect 1 1)" - "The test passed!" - #:repl-expected "Both tests passed!") - - (test-expression "(check-within 1 1.1 0.5)" - "The test passed!" - #:repl-expected "Both tests passed!") - - (test-expression "(check-expect 1 2)" - "" - #:check-failures-expected - (list (make-check-expect-failure "1" "2" 1 0)) - #:repl-check-failures-expected - (list (make-check-expect-failure "1" "2" 3 2)))) +(define (common-test-engine dmda?) + (test-expression "(check-expect 1 1)" + "The test passed!" + #:repl-expected "Both tests passed!") + + (test-expression "(check-within 1 1.1 0.5)" + "The test passed!" + #:repl-expected "Both tests passed!") + + (test-expression "(check-expect 1 2)" + "" + #:check-failures-expected + (list (make-check-expect-failure "1" "2" 1 0)) + #:repl-check-failures-expected + (list (make-check-expect-failure "1" "2" 3 2))) + + (unless dmda? + (test-expression "(check-expect (car 0) 2)" + "car: expects a pair, given 0" + #:check-failures-expected + (list (make-check-expect-error "2." ":: car: expects a pair, given 0" 1 0)) + #:repl-check-failures-expected + (list (make-check-expect-error "2." ":: car: expects a pair, given 0" 4 2))))) (define (common-signatures-*sl) (test-expression "(: foo Integer) (define foo 5)" @@ -94,7 +102,7 @@ (define (beginner) (parameterize ([language (list "How to Design Programs" #rx"Beginning Student(;|$)")]) (prepare-for-test-expression) - (common-test-engine))) + (common-test-engine #f))) ; @@ -117,7 +125,7 @@ (parameterize ([language (list "How to Design Programs" #rx"Beginning Student with List Abbreviations(;|$)")]) (prepare-for-test-expression) - (common-test-engine))) + (common-test-engine #f))) ; @@ -139,7 +147,7 @@ (define (intermediate) (parameterize ([language (list "How to Design Programs" #rx"Intermediate Student(;|$)")]) (prepare-for-test-expression) - (common-test-engine))) + (common-test-engine #f))) ; ; @@ -162,7 +170,7 @@ (parameterize ([language (list "How to Design Programs" #rx"Intermediate Student with lambda(;|$)")]) (prepare-for-test-expression) - (common-test-engine))) + (common-test-engine #f))) ; @@ -185,32 +193,32 @@ (define (advanced) (parameterize ([language (list "How to Design Programs" #rx"Advanced Student(;|$)")]) (prepare-for-test-expression) - (common-test-engine) + (common-test-engine #f) (common-signatures-*sl))) (define (DMdA-beginner) (parameterize ([language (list "DeinProgramm" #rx"Die Macht der Abstraktion - Anfänger(;|$)")]) (prepare-for-test-expression) - (common-test-engine) + (common-test-engine #t) (common-signatures-DMdA))) (define (DMdA-vanilla) (parameterize ([language (list "DeinProgramm" #rx"Die Macht der Abstraktion(;|$)")]) (prepare-for-test-expression) - (common-test-engine) + (common-test-engine #t) (common-signatures-DMdA))) (define (DMdA-assignments) (parameterize ([language (list "DeinProgramm" #rx"Die Macht der Abstraktion mit Zuweisungen(;|$)")]) (prepare-for-test-expression) - (common-test-engine) + (common-test-engine #t) (common-signatures-DMdA))) (define (DMdA-advanced) (parameterize ([language (list "DeinProgramm" #rx"Die Macht der Abstraktion - fortgeschritten(;|$)")]) (prepare-for-test-expression) - (common-test-engine) + (common-test-engine #t) (common-signatures-DMdA))) (define (prepare-for-test-expression) @@ -301,6 +309,8 @@ (actual expected line column) #:transparent) +(define-struct check-expect-error (value message line column) #:transparent) + (define (parse-check-failures txt) (cond ((string=? txt "") '()) @@ -309,7 +319,7 @@ ((regexp-match #rx"^[ \t]*\n(.*)" txt) => (lambda (match) (parse-check-failures (cadr match)))) - ((regexp-match "^[ \t]+Actual value ([^\n]+) differs from ([^\n]+), the expected value.\nat line ([0-9]+), column ([0-9]+)(.*)" + ((regexp-match #rx"^[ \t]+Actual value ([^\n]+) differs from ([^\n]+), the expected value.\nat line ([0-9]+), column ([0-9]+)(.*)" txt) => (lambda (match) (let-values (((_ actual expected line-text col-text rest) (apply values match))) @@ -318,6 +328,16 @@ (string->number line-text) (string->number col-text)) (parse-check-failures rest))))) + ((regexp-match #rx"^[ \t]+check-expect encountered the following error instead of the expected value, ([^\n]*). *\n[ \t]*([^\n]*)\n[^\n]*line ([0-9]+), column ([0-9]+)[ ]*\n(.*)$" + txt) + => (lambda (match) + (define-values (_ value message line-text col-text rest) (apply values match)) + (cons + (make-check-expect-error value + message + (string->number line-text) + (string->number col-text)) + (parse-check-failures rest)))) (else (error "unknown check failure" txt (string-ref txt 0))))) @@ -347,7 +367,7 @@ ;; types an expression in the REPL and tests the output from the REPL. (define (test-expression expression defs-expected #:repl-expression (repl-expression expression) - #:repl-expected (repl-expected defs-expected) + #:repl-expected (repl-expected defs-expected) #:check-failures-expected (check-failures-expected '()) #:signature-violations-expected (signature-violations-expected '()) #:repl-check-failures-expected (repl-check-failures-expected '()) @@ -371,7 +391,7 @@ [(procedure? expected) (expected got)]))] [check-failures - (lambda (signature-violations-expected check-failures-expected) + (lambda (where signature-violations-expected check-failures-expected) (let ((text (cond ((send (send definitions-text get-tab) get-test-editor) @@ -387,16 +407,16 @@ (null? check-failures-expected)) (when text (eprintf "FAILED: ~s ~s expected ~s to produce no check failures or signature violations:\ngot:\n~a\ninstead\n" - 'definitions (language) expression text))) + where (language) expression text))) (text (let-values (((test-count test-passed-count signature-violation-count check-failures signature-violations) (parse-test-failures text))) (when (not (equal? check-failures check-failures-expected)) (eprintf "FAILED: ~s ~s expected ~s to produce check failures:\n~s\ngot:\n~s\ninstead\n" - 'definitions (language) expression check-failures-expected check-failures)) + where (language) expression check-failures-expected check-failures)) (when (not (equal? signature-violations signature-violations-expected)) (eprintf "FAILED: ~s ~s expected ~s to produce signature violations:\n~s\ngot:\n~s\ninstead\n" - 'definitions (language) expression signature-violations-expected signature-violations)))) + where (language) expression signature-violations-expected signature-violations)))) (else (eprintf "expected ~a check failures and ~a signature violations but got none" (length check-failures-expected) (length signature-violations-expected))))))] @@ -429,8 +449,8 @@ (unless (check-expectation defs-expected got) (eprintf (make-err-msg defs-expected) 'definitions (language) expression defs-expected got))) - - (check-failures signature-violations-expected check-failures-expected) + + (check-failures 'definitions signature-violations-expected check-failures-expected) (cond [(pair? repl-expression) (for-each handle-interaction-insertion repl-expression)] @@ -455,7 +475,8 @@ (eprintf (make-err-msg repl-expected) 'interactions (language) expression repl-expected got)))) ;; the failures from the definition window stick around - (check-failures (append signature-violations-expected repl-signature-violations-expected) + (check-failures 'interactions + (append signature-violations-expected repl-signature-violations-expected) (append check-failures-expected repl-check-failures-expected)))) (define (test-disabling-tests) From bf8072cb1f523c7a87f009d4b12bf5628523ae54 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 1 Aug 2012 06:00:20 -0600 Subject: [PATCH 664/746] ffi/com: remove stray quote Merge to v5.3 (cherry picked from commit 38167dd4fa83d3b942260ec75673c73f72f2062a) --- collects/ffi/unsafe/com.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index 190ed51e23..b5769a3e0c 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -641,7 +641,7 @@ set-com-object-sink!) (when (positive? (hash-count (com-object-types obj))) (for ([td (in-hash-values (com-object-types obj))]) - '(release-type-desc td)) + (release-type-desc td)) (set-com-object-types! obj (make-hash)))))) (define (release-type-desc td) From 7cb2bfa0f8a77200f4b2555a377117f78226b5c8 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 1 Aug 2012 18:19:07 -0500 Subject: [PATCH 665/746] adjust DMdA languages so they do the same error rewriting that the HtDP languages are doing. This seems to make the error messages in DMdA behave like they did in 5.2.1 (and so I'm pushing this to see how DrDr reacts) (cherry picked from commit 44161d73c8bdce0374718d1ab0bc20fbebc1fec2) --- collects/deinprogramm/deinprogramm-langs.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/deinprogramm/deinprogramm-langs.rkt b/collects/deinprogramm/deinprogramm-langs.rkt index 87cb5f7b08..976840b6da 100644 --- a/collects/deinprogramm/deinprogramm-langs.rkt +++ b/collects/deinprogramm/deinprogramm-langs.rkt @@ -25,6 +25,7 @@ lang/debugger-language-interface lang/run-teaching-program lang/private/continuation-mark-key + lang/private/rewrite-error-message (only-in test-engine/scheme-gui make-formatter) test-engine/scheme-tests @@ -1187,7 +1188,7 @@ (define (teaching-languages-error-display-handler msg exn) (if (exn? exn) - (display (exn-message exn) (current-error-port)) + (display (get-rewriten-error-message exn) (current-error-port)) (eprintf "uncaught exception: ~e" exn)) (eprintf "\n") From 9313bfde319e98a2615d28c801b8596b125036c8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 2 Aug 2012 07:52:27 -0600 Subject: [PATCH 666/746] ffi/com: adjust order in object release Release type descriptors before type infos, and release type infos before objects. (This reordering shouldn't matter if referencing counting does its usual job, but maybe it's better to use the obvious order.) Merge to v5.3 (cherry picked from commit 286efface02f86cee744ae360cd896856c55d480) --- collects/ffi/unsafe/com.rkt | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index b5769a3e0c..75f4687284 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -623,14 +623,18 @@ (let ([mref (com-object-mref obj)]) (when mref (scheme_remove_managed mref obj))) + ;; Although reference counting should let us release in any + ;; order, comments in the MysterX source suggest that the + ;; order matters, so release type descriptions first and + ;; the main object last. + (when (positive? (hash-count (com-object-types obj))) + (for ([td (in-hash-values (com-object-types obj))]) + (release-type-desc td)) + (set-com-object-types! obj (make-hash))) (define (bye! sel st!) (when (sel obj) (Release (sel obj)) (st! obj #f))) - (bye! com-object-dispatch - set-com-object-dispatch!) - (bye! com-object-unknown - set-com-object-unknown!) (bye! com-object-type-info set-com-object-type-info!) (bye! com-object-event-type-info @@ -639,10 +643,10 @@ set-com-object-connection-point!) (bye! com-object-sink set-com-object-sink!) - (when (positive? (hash-count (com-object-types obj))) - (for ([td (in-hash-values (com-object-types obj))]) - (release-type-desc td)) - (set-com-object-types! obj (make-hash)))))) + (bye! com-object-dispatch + set-com-object-dispatch!) + (bye! com-object-unknown + set-com-object-unknown!)))) (define (release-type-desc td) ;; call in atomic mode From 6ea2c86b880d06095b91871ec6230a5631ef9946 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 2 Aug 2012 10:57:33 -0600 Subject: [PATCH 667/746] ffi/com: thread safety Protect internal data structures via atomic mode. Merge to v5.3 (cherry picked from commit 572252daec900bca9a8f42a25e505f1f28512c5e) --- collects/ffi/unsafe/com.rkt | 294 +++++++++++++++++++----------------- 1 file changed, 154 insertions(+), 140 deletions(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index 75f4687284..c5ac9e93bb 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -678,9 +678,11 @@ (define (com-get-active-object name) (init!) (define clsid (gen->clsid 'com-get-active-object name)) - (define unknown (GetActiveObject clsid)) - (and unknown - (make-com-object unknown clsid))) + (call-as-atomic + (lambda () + (define unknown (GetActiveObject clsid)) + (and unknown + (make-com-object unknown clsid))))) (define (check-com-obj who obj) (unless (com-object? obj) @@ -868,11 +870,13 @@ [else (raise-type-error who "com-object or com-type" obj)])) (define (do-get-methods who obj inv-kind) - (define type-info (extract-type-info who obj #t)) - (define type-attr (GetTypeAttr type-info)) - (begin0 - (sort (get-type-names type-info type-attr null inv-kind) string-ci pFuncDesc->cParams - 1 get packaged into SAFEARRAY - (values - (append - (for/list ([i (in-range num-actual-params)]) - (elem-desc-to-scheme-type (elem-desc-ref func-desc i) + (call-as-atomic + (lambda () + (define type-info (extract-type-info who obj (not internal?))) + (when (and (= inv-kind INVOKE_FUNC) + (is-dispatch-name? name)) + (error who "IDispatch methods not available")) + (define mx-type-desc + (cond + [(com-object? obj) (get-method-type obj name inv-kind (not internal?))] + [else (define x-type-info + (if (= inv-kind INVOKE_EVENT) + (event-type-info-from-com-type obj) + type-info)) + (type-desc-from-type-info name inv-kind x-type-info)])) + (cond + [(not mx-type-desc) + ;; there is no type info + #f] + [else + (define-values (args ret) + (cond + [(function-type-desc? mx-type-desc) + (define func-desc (car (mx-com-type-desc-desc mx-type-desc))) + (define num-actual-params (FUNCDESC-cParams func-desc)) + (cond + [(= -1 (FUNCDESC-cParamsOpt func-desc)) + ;; all args > pFuncDesc->cParams - 1 get packaged into SAFEARRAY + (values + (append + (for/list ([i (in-range num-actual-params)]) + (elem-desc-to-scheme-type (elem-desc-ref func-desc i) + #f + #f + internal?)) + (list '...)) + (elem-desc-to-scheme-type (FUNCDESC-elemdescFunc func-desc) #f #f - internal?)) - (list '...)) - (elem-desc-to-scheme-type (FUNCDESC-elemdescFunc func-desc) - #f - #f - internal?))] - [else - (define last-is-retval? - (is-last-param-retval? inv-kind func-desc)) - (define num-params (- num-actual-params (if last-is-retval? 1 0))) - ;; parameters that are optional with a default value in IDL are not - ;; counted in pFuncDesc->cParamsOpt, so look for default bit flag - (define num-opt-params (get-opt-param-count func-desc num-params)) - (define first-opt-arg (- num-params num-opt-params)) - (values - (for/list ([i (in-range num-params)]) - (elem-desc-to-scheme-type (elem-desc-ref func-desc i) - #f - (i . >= . first-opt-arg) - internal?)) - (elem-desc-to-scheme-type (if last-is-retval? - (elem-desc-ref func-desc num-params) - (FUNCDESC-elemdescFunc func-desc)) - #t - #f - internal?))])] - [(= inv-kind INVOKE_PROPERTYGET) - (define var-desc (mx-com-type-desc-desc mx-type-desc)) - (values null - (elem-desc-to-scheme-type (VARDESC-elemdescVar var-desc) + internal?))] + [else + (define last-is-retval? + (is-last-param-retval? inv-kind func-desc)) + (define num-params (- num-actual-params (if last-is-retval? 1 0))) + ;; parameters that are optional with a default value in IDL are not + ;; counted in pFuncDesc->cParamsOpt, so look for default bit flag + (define num-opt-params (get-opt-param-count func-desc num-params)) + (define first-opt-arg (- num-params num-opt-params)) + (values + (for/list ([i (in-range num-params)]) + (elem-desc-to-scheme-type (elem-desc-ref func-desc i) #f - #f - internal?))] - [(= inv-kind INVOKE_PROPERTYPUT) - (define var-desc (mx-com-type-desc-desc mx-type-desc)) - (values (list (elem-desc-to-scheme-type (VARDESC-elemdescVar var-desc) - #f - #f - internal?)) - 'void)] - [(= inv-kind INVOKE_EVENT) - (values null 'void)])) - `(-> ,args ,ret)])) + (i . >= . first-opt-arg) + internal?)) + (elem-desc-to-scheme-type (if last-is-retval? + (elem-desc-ref func-desc num-params) + (FUNCDESC-elemdescFunc func-desc)) + #t + #f + internal?))])] + [(= inv-kind INVOKE_PROPERTYGET) + (define var-desc (mx-com-type-desc-desc mx-type-desc)) + (values null + (elem-desc-to-scheme-type (VARDESC-elemdescVar var-desc) + #f + #f + internal?))] + [(= inv-kind INVOKE_PROPERTYPUT) + (define var-desc (mx-com-type-desc-desc mx-type-desc)) + (values (list (elem-desc-to-scheme-type (VARDESC-elemdescVar var-desc) + #f + #f + internal?)) + 'void)] + [(= inv-kind INVOKE_EVENT) + (values null 'void)])) + `(-> ,args ,ret)])))) (define (com-method-type obj name) (do-get-method-type 'com-method-type obj name INVOKE_FUNC #f)) @@ -1777,7 +1783,9 @@ (define (do-com-invoke who obj name args inv-kind) (check-com-obj who obj) (unless (string? name) (raise-type-error who "string" name)) - (let ([t (or (do-get-method-type who obj name inv-kind #t) + (let ([t (or (call-as-atomic + (lambda () + (do-get-method-type who obj name inv-kind #t))) ;; wing it by inferring types from the arguments: `(-> ,(map arg-to-type args) any))]) (unless (<= (length (filter (lambda (v) (not (and (pair? v) (eq? (car v) 'opt)))) @@ -1788,64 +1796,66 @@ (for ([arg (in-list args)] [type (in-list (cadr t))]) (check-argument 'com-invoke name arg type)) - (define type-desc (get-method-type obj name inv-kind #f)) ; cached - (cond - [(if type-desc - (mx-com-type-desc-memid type-desc) - (find-memid who obj name)) - => (lambda (memid) - (define-values (num-params-passed method-arguments cleanups commits) - (build-method-arguments type-desc - (cadr t) - inv-kind - args)) - ;; from this point, don't escape/return without running cleanups - (when #f - ;; for debugging, inspect constructed arguments: - (eprintf "~e ~e\n" - t - (reverse - (for/list ([i (in-range num-params-passed)]) - (variant-to-scheme (ptr-ref (DISPPARAMS-rgvarg method-arguments) - _VARIANT - i)))))) - (define method-result - (if (= inv-kind INVOKE_PROPERTYPUT) - #f - (make-a-VARIANT 'atomic))) - (for ([proc (in-list commits)]) (proc)) - (define-values (hr exn-info error-index) - (Invoke (com-object-get-dispatch obj) - memid IID_NULL LOCALE_SYSTEM_DEFAULT - inv-kind method-arguments - method-result)) - (cond - [(zero? hr) - (begin0 - (if method-result - (variant-to-scheme method-result) - (void)) - (for ([proc (in-list cleanups)]) (proc)))] - [(= hr DISP_E_EXCEPTION) - (for ([proc (in-list cleanups)]) (proc)) - (define has-error-code? (positive? (EXCEPINFO-wCode exn-info))) - (define desc (EXCEPINFO-bstrDescription exn-info)) - (windows-error - (if has-error-code? - (format "COM object exception during ~s, error code 0x~x~a~a" - name - (EXCEPINFO-wCode exn-info) - (if desc "\nDescription: " "") - (or desc "")) - (format "COM object exception during ~s~a~a" - name - (if desc "\nDescription: " "") - (or desc ""))) - (EXCEPINFO-scode exn-info))] - [else - (for ([proc (in-list cleanups)]) (proc)) - (windows-error (format "~a: failed for ~s" who name) hr)]))] - [else (error "not yet implemented")]))) + (call-as-atomic + (lambda () + (define type-desc (get-method-type obj name inv-kind #f)) ; cached + (cond + [(if type-desc + (mx-com-type-desc-memid type-desc) + (find-memid who obj name)) + => (lambda (memid) + (define-values (num-params-passed method-arguments cleanups commits) + (build-method-arguments type-desc + (cadr t) + inv-kind + args)) + ;; from this point, don't escape/return without running cleanups + (when #f + ;; for debugging, inspect constructed arguments: + (eprintf "~e ~e\n" + t + (reverse + (for/list ([i (in-range num-params-passed)]) + (variant-to-scheme (ptr-ref (DISPPARAMS-rgvarg method-arguments) + _VARIANT + i)))))) + (define method-result + (if (= inv-kind INVOKE_PROPERTYPUT) + #f + (make-a-VARIANT 'atomic))) + (for ([proc (in-list commits)]) (proc)) + (define-values (hr exn-info error-index) + (Invoke (com-object-get-dispatch obj) + memid IID_NULL LOCALE_SYSTEM_DEFAULT + inv-kind method-arguments + method-result)) + (cond + [(zero? hr) + (begin0 + (if method-result + (variant-to-scheme method-result) + (void)) + (for ([proc (in-list cleanups)]) (proc)))] + [(= hr DISP_E_EXCEPTION) + (for ([proc (in-list cleanups)]) (proc)) + (define has-error-code? (positive? (EXCEPINFO-wCode exn-info))) + (define desc (EXCEPINFO-bstrDescription exn-info)) + (windows-error + (if has-error-code? + (format "COM object exception during ~s, error code 0x~x~a~a" + name + (EXCEPINFO-wCode exn-info) + (if desc "\nDescription: " "") + (or desc "")) + (format "COM object exception during ~s~a~a" + name + (if desc "\nDescription: " "") + (or desc ""))) + (EXCEPINFO-scode exn-info))] + [else + (for ([proc (in-list cleanups)]) (proc)) + (windows-error (format "~a: failed for ~s" who name) hr)]))] + [else (error "not yet implemented")]))))) (define (com-invoke obj name . args) (do-com-invoke 'com-invoke obj name args INVOKE_FUNC)) @@ -2047,11 +2057,15 @@ (define (com-object-get-iunknown obj) (check-com-obj 'com-object-get-iunknown obj) - (com-object-get-unknown obj)) + (call-as-atomic + (lambda () + (com-object-get-unknown obj)))) (define (com-object-get-idispatch obj) (check-com-obj 'com-object-get-idispatch obj) - (com-object-get-dispatch obj)) + (call-as-atomic + (lambda () + (com-object-get-dispatch obj)))) (define (com-iunknown? v) (and (IUnknown? v) #t)) (define (com-idispatch? v) (and (IDispatch? v) #t)) From bfc256270b0fe8fedf2bc0af4259b9e06eb97704 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 2 Aug 2012 11:43:57 -0600 Subject: [PATCH 668/746] ffi/com: fix potential interaction of finalization and custodians Includes new `#:manage?' optional argument to `make-com-object' and better management of internally created objects. Merge to v5.3 (cherry picked from commit 38ce4997a9d5568ed12d5bcad071ab91d53a9ff7) --- collects/ffi/unsafe/com.rkt | 169 ++++++++++++-------- collects/scribblings/foreign/com-auto.scrbl | 5 +- collects/scribblings/foreign/com-intf.scrbl | 10 +- 3 files changed, 115 insertions(+), 69 deletions(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index c5ac9e93bb..df0b355f76 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -258,8 +258,8 @@ (((deallocator cadr) (let ([f expr]) (lambda args - (Release self) - (apply f args)))) + (apply f args) + (Release self)))) self arg ...))])) (define (check-com-type who id id? obj) @@ -492,17 +492,12 @@ -> GetActiveObject p) #:wrap (allocator Release)) -(struct com-object ([unknown #:mutable] - [dispatch #:mutable] - [type-info #:mutable] - [event-type-info #:mutable] - [clsid #:mutable] - [connection-point #:mutable] - [connection-cookie #:mutable] - [sink #:mutable] - [sink-table-links #:mutable] - [types #:mutable] - [mref #:mutable]) +;; We want to create a finalizer on a `com-object' value, +;; and we don't want things that an object references to be +;; finalized before the object. So we use an indirection, +;; the the finalizer on a `com-object' will have the `impl' +;; in its closure: +(struct com-object (impl) #:property prop:equal+hash (list (lambda (a b eql?) (ptr-equal? (com-object-unknown a) (com-object-unknown b))) @@ -511,6 +506,30 @@ (lambda (a ehc2) (ehc2 (com-object-unknown a))))) +(struct com-impl ([unknown #:mutable] + [dispatch #:mutable] + [type-info #:mutable] + [event-type-info #:mutable] + [clsid #:mutable] + [connection-point #:mutable] + [connection-cookie #:mutable] + [sink #:mutable] + [sink-table-links #:mutable] + [types #:mutable] + [mref #:mutable])) + +(define (com-object-unknown obj) (com-impl-unknown (com-object-impl obj))) +(define (com-object-dispatch obj) (com-impl-dispatch (com-object-impl obj))) +(define (com-object-type-info obj) (com-impl-type-info (com-object-impl obj))) +(define (com-object-event-type-info obj) (com-impl-event-type-info (com-object-impl obj))) +(define (com-object-clsid obj) (com-impl-clsid (com-object-impl obj))) +(define (com-object-connection-point obj) (com-impl-connection-point (com-object-impl obj))) +(define (com-object-connection-cookie obj) (com-impl-connection-cookie (com-object-impl obj))) +(define (com-object-sink obj) (com-impl-sink (com-object-impl obj))) +(define (com-object-sink-table-links obj) (com-impl-sink-table-links (com-object-impl obj))) +(define (com-object-types obj) (com-impl-types (com-object-impl obj))) +(define (com-object-mref obj) (com-impl-mref (com-object-impl obj))) + (define (com-object-eq? a b) (check-com-obj 'com-object-eq? a) (check-com-obj 'com-object-eq? b) @@ -542,18 +561,31 @@ (define scheme_remove_managed (get-ffi-obj 'scheme_remove_managed #f (_fun _gcpointer _racket -> _void))) -(define (custodian-shutdown-com obj proc-self) (com-release obj)) +(define (custodian-shutdown-com impl proc-self) (impl-release impl)) (define custodian_shutdown_com (cast custodian-shutdown-com (_fun #:atomic? #t _racket _racket -> _void) _fpointer)) (define (register-with-custodian obj) - (set-com-object-mref! - obj + (define impl (com-object-impl obj)) + (set-com-impl-mref! + impl (scheme_add_managed (current-custodian) - obj + impl custodian_shutdown_com custodian-shutdown-com ; proc as data -> ffi callback retained - 1))) + 1)) + ;; If we don't finalize the object, then it could + ;; happen that the object becomes unreachable and + ;; pointers that the object references could be + ;; finalized at the same time that the custodian + ;; changes its weak reference to a strong one; then, + ;; a custodian shutdown would try to redundantly + ;; free the pointers. At the same time, use 1 as + ;; the last argument above to `scheme_add_managed', + ;; in case the custodian is shutdown between the + ;; time that the finalizer is enqueued and when it + ;; is run. + (register-finalizer obj (lambda (obj) (impl-release impl)))) (define (do-cocreate-instance who clsid [where 'local]) (init!) @@ -597,56 +629,62 @@ (error who "unable to obtain IUnknown interface for remote server")) unknown])) - (define obj (make-com-object unknown clsid)) - (register-with-custodian obj) - obj))) + (make-com-object unknown clsid)))) -(define (make-com-object unknown clsid) +(define (make-com-object unknown clsid #:manage? [manage? #t]) (unless (com-iunknown? unknown) (raise-type-error 'make-com-object "com-iunknown" unknown)) (unless (or (not clsid) (clsid? clsid)) (raise-type-error 'make-com-object "clsid or #f" clsid)) - (com-object unknown - #f - #f - #f - clsid - #f - #f - #f - #f - (make-hash) - #f)) + (define obj (com-object + (com-impl unknown + #f + #f + #f + clsid + #f + #f + #f + #f + (make-hash) + #f))) + (when manage? + (register-with-custodian obj)) + obj) (define (com-release obj) (check-com-obj 'com-release obj) + (impl-release (com-object-impl obj))) + +(define (impl-release impl) (call-as-atomic (lambda () - (let ([mref (com-object-mref obj)]) + (let ([mref (com-impl-mref impl)]) (when mref - (scheme_remove_managed mref obj))) + (set-com-impl-mref! impl #f) + (scheme_remove_managed mref impl))) ;; Although reference counting should let us release in any ;; order, comments in the MysterX source suggest that the ;; order matters, so release type descriptions first and - ;; the main object last. - (when (positive? (hash-count (com-object-types obj))) - (for ([td (in-hash-values (com-object-types obj))]) + ;; the main impl last. + (when (positive? (hash-count (com-impl-types impl))) + (for ([td (in-hash-values (com-impl-types impl))]) (release-type-desc td)) - (set-com-object-types! obj (make-hash))) + (set-com-impl-types! impl (make-hash))) (define (bye! sel st!) - (when (sel obj) - (Release (sel obj)) - (st! obj #f))) - (bye! com-object-type-info - set-com-object-type-info!) - (bye! com-object-event-type-info - set-com-object-event-type-info!) - (bye! com-object-connection-point - set-com-object-connection-point!) - (bye! com-object-sink - set-com-object-sink!) - (bye! com-object-dispatch - set-com-object-dispatch!) - (bye! com-object-unknown - set-com-object-unknown!)))) + (when (sel impl) + (Release (sel impl)) + (st! impl #f))) + (bye! com-impl-type-info + set-com-impl-type-info!) + (bye! com-impl-event-type-info + set-com-impl-event-type-info!) + (bye! com-impl-connection-point + set-com-impl-connection-point!) + (bye! com-impl-sink + set-com-impl-sink!) + (bye! com-impl-dispatch + set-com-impl-dispatch!) + (bye! com-impl-unknown + set-com-impl-unknown!)))) (define (release-type-desc td) ;; call in atomic mode @@ -690,8 +728,8 @@ (define (com-object-set-clsid! obj clsid) (check-com-obj 'com-object-set-clsid! obj) - (unless (clsid? clsid) (raise-type-error 'set-com-object-clsid! "clsid" clsid)) - (set-com-object-clsid! obj clsid)) + (unless (clsid? clsid) (raise-type-error 'com-object-set-clsid! "clsid" clsid)) + (set-com-impl-clsid! (com-object-impl obj) clsid)) ;; ---------------------------------------- ;; Getting COM methods and types @@ -707,7 +745,7 @@ _IDispatch-pointer)]) (unless dispatch (error 'com-object-get-idispatch "cannot get IDispatch interface for object: ~e" obj)) - (set-com-object-dispatch! obj dispatch) + (set-com-impl-dispatch! (com-object-impl obj) dispatch) dispatch))) (define (type-info-from-com-object obj [exn? #t]) @@ -724,7 +762,7 @@ LOCALE_SYSTEM_DEFAULT)]) (unless type-info (error "Error getting COM type information")) - (set-com-object-type-info! obj type-info) + (set-com-impl-type-info! (com-object-impl obj) type-info) type-info))))) (define (com-object-type obj) @@ -818,7 +856,7 @@ (define event-type-info (event-type-info-from-coclass-type-info coclass-type-info)) (Release coclass-type-info) - (set-com-object-event-type-info! obj event-type-info) + (set-com-impl-event-type-info! (com-object-impl obj) event-type-info) event-type-info))) (define (is-dispatch-name? s) @@ -1632,9 +1670,7 @@ p) (lambda (p) (((allocator Release) (lambda () p))) - (define obj (make-com-object p #f)) - (register-with-custodian obj) - obj))) + (make-com-object p #f)))) (define (to-ctype type [as-boxed? #f]) (cond @@ -2020,10 +2056,11 @@ (define sink (QueryInterface sink-unknown IID_ISink _ISink-pointer)) (set_myssink_table sink myssink-table) (define cookie (Advise connection-point sink)) - (set-com-object-connection-point! obj connection-point) - (set-com-object-connection-cookie! obj cookie) - (set-com-object-sink! obj sink) - (set-com-object-sink-table-links! obj sink-table-links) + (define impl (com-object-impl obj)) + (set-com-impl-connection-point! impl connection-point) + (set-com-impl-connection-cookie! impl cookie) + (set-com-impl-sink! impl sink) + (set-com-impl-sink-table-links! impl sink-table-links) (Release connection-point-container) connection-point))) diff --git a/collects/scribblings/foreign/com-auto.scrbl b/collects/scribblings/foreign/com-auto.scrbl index 19ce668b70..b3665180af 100644 --- a/collects/scribblings/foreign/com-auto.scrbl +++ b/collects/scribblings/foreign/com-auto.scrbl @@ -109,7 +109,10 @@ produces a @tech{ProgID} with its version.} Releases the given @tech{COM object}. The given @racket[obj] is subsequently unusable, and the underlying COM object is destroyed unless its reference count has been incremented (via COM methods or -unsafe operations).} +unsafe operations). + +If @racket[obj] has already been released, @racket[com-release] has +no effect.} @defproc[(com-get-active-object [clsid-or-progid (or/c clsid? string?)]) diff --git a/collects/scribblings/foreign/com-intf.scrbl b/collects/scribblings/foreign/com-intf.scrbl index 2d81f08f9f..2c28dc4c51 100644 --- a/collects/scribblings/foreign/com-intf.scrbl +++ b/collects/scribblings/foreign/com-intf.scrbl @@ -105,11 +105,17 @@ returning the new reference count and releasing the interface reference if the count goes to zero.} -@defproc[(make-com-object [iunknown com-iunknown?] [clsid (or/c clsid? #f)]) +@defproc[(make-com-object [iunknown com-iunknown?] [clsid (or/c clsid? #f)] + [#:manage? manage? any/c #t]) com-object?]{ Converts a @tech{COM object} into a object that can be used with the -COM automation functions, such as @racket[com-invoke].} +COM automation functions, such as @racket[com-invoke]. + +If @racket[manage?] is true, the resulting object is registered with +the current custodian and a finalizer to call @racket[com-release] +when the custodian is shut down or when the object becomes +inaccessible.} @; ---------------------------------------- From 76d2de48558cc48b315e8baebfb730f96ac1c96d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 2 Aug 2012 19:17:22 -0600 Subject: [PATCH 669/746] ffi/com: fix interaction with `racket/gui' ... and other things that use the Windows message queue by not providing GCable arguments to IDispatch::Invoke(). Merge to v5.3 (cherry picked from commit 66eaa191e5fd526a58172b28babe07d51e7f3cf7) --- collects/ffi/unsafe/com.rkt | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index df0b355f76..7051b4b0a1 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -1606,7 +1606,9 @@ (define (make-a-VARIANT [mode 'atomic-interior]) (define var (cast (malloc _VARIANT mode) _pointer - (_gcable _VARIANT-pointer))) + (if (eq? mode 'raw) + _VARIANT-pointer + (_gcable _VARIANT-pointer)))) (VariantInit var) var) @@ -1773,7 +1775,10 @@ (define var (ptr-ref vars _VARIANT (- count i 1))) ; reverse order (VariantInit var) (scheme-to-variant! var a (and func-desc (elem-desc-ref func-desc i)) scheme-type))) - (values count + (define disp-params (cast (malloc _DISPPARAMS 'raw) + _pointer + _DISPPARAMS-pointer)) + (memcpy disp-params (make-DISPPARAMS vars (if (= inv-kind INVOKE_PROPERTYPUT) prop-put-long @@ -1782,7 +1787,10 @@ (if (= inv-kind INVOKE_PROPERTYPUT) count 0)) - (unbox cleanup) + (ctype-sizeof _DISPPARAMS)) + (values count + disp-params + (cons (lambda () (free disp-params)) (unbox cleanup)) (unbox commit))) (define (variant-to-scheme var) @@ -1840,7 +1848,7 @@ (mx-com-type-desc-memid type-desc) (find-memid who obj name)) => (lambda (memid) - (define-values (num-params-passed method-arguments cleanups commits) + (define-values (num-params-passed method-arguments arg-cleanups commits) (build-method-arguments type-desc (cadr t) inv-kind @@ -1855,12 +1863,19 @@ (variant-to-scheme (ptr-ref (DISPPARAMS-rgvarg method-arguments) _VARIANT i)))))) - (define method-result + (define-values (method-result cleanups) (if (= inv-kind INVOKE_PROPERTYPUT) - #f - (make-a-VARIANT 'atomic))) + (values #f arg-cleanups) + (let ([r (make-a-VARIANT 'raw)]) + (values r (cons (lambda () (free r)) + arg-cleanups))))) (for ([proc (in-list commits)]) (proc)) (define-values (hr exn-info error-index) + ;; Note that all arguments to `Invoke' should + ;; not be movable by a GC. A call to `Invoke' + ;; may use the Windows message queue, and other + ;; libraries (notably `racket/gui') may have + ;; callbacks triggered via messages. (Invoke (com-object-get-dispatch obj) memid IID_NULL LOCALE_SYSTEM_DEFAULT inv-kind method-arguments From 1a35b6d078b9d5250531874f42fd8d6194fb01da Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Sat, 4 Aug 2012 11:24:16 -0600 Subject: [PATCH 670/746] Fixed off-by-epsilon error; addresses issue with plateaus in contour-intervals and contour-intervals3d reported by Doug Williams Please merge into release (cherry picked from commit a70aca317671403509d0c6f5ae90725309f49417) --- collects/plot/common/marching-squares.rkt | 8 ++++---- collects/plot/tests/plot2d-tests.rkt | 8 ++++++++ collects/plot/tests/plot3d-tests.rkt | 8 ++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/collects/plot/common/marching-squares.rkt b/collects/plot/common/marching-squares.rkt index 657bc2fa24..4bed76be26 100644 --- a/collects/plot/common/marching-squares.rkt +++ b/collects/plot/common/marching-squares.rkt @@ -584,10 +584,10 @@ above. polys2220 polys2221 polys2222)) (define (unsafe-heights->polys za zb z1 z2 z3 z4) - (define t1 (if (z1 . unsafe-fl< . za) 0 (if (z1 . unsafe-fl< . zb) 1 2))) - (define t2 (if (z2 . unsafe-fl< . za) 0 (if (z2 . unsafe-fl< . zb) 1 2))) - (define t3 (if (z3 . unsafe-fl< . za) 0 (if (z3 . unsafe-fl< . zb) 1 2))) - (define t4 (if (z4 . unsafe-fl< . za) 0 (if (z4 . unsafe-fl< . zb) 1 2))) + (define t1 (if (z1 . unsafe-fl< . za) 0 (if (z1 . unsafe-fl<= . zb) 1 2))) + (define t2 (if (z2 . unsafe-fl< . za) 0 (if (z2 . unsafe-fl<= . zb) 1 2))) + (define t3 (if (z3 . unsafe-fl< . za) 0 (if (z3 . unsafe-fl<= . zb) 1 2))) + (define t4 (if (z4 . unsafe-fl< . za) 0 (if (z4 . unsafe-fl<= . zb) 1 2))) (define facet-num (unsafe-fx+ (unsafe-fx+ (unsafe-fx+ (unsafe-fx* (unsafe-fx* (unsafe-fx* t1 3) 3) 3) (unsafe-fx* (unsafe-fx* t2 3) 3)) diff --git a/collects/plot/tests/plot2d-tests.rkt b/collects/plot/tests/plot2d-tests.rkt index 58372caae2..880ec650fc 100644 --- a/collects/plot/tests/plot2d-tests.rkt +++ b/collects/plot/tests/plot2d-tests.rkt @@ -308,6 +308,14 @@ (time (plot (contour-intervals f1 -5 5 -5 5 #:label "z"))) +(time (plot (contour-intervals + (λ (x y) + (define z (- x y)) + (cond [(< z -1) -1] + [(> z 1) 1] + [else z])) + -2 2 -2 2))) + (time (plot (list (tick-grid) (contour-intervals f1 -5 2 -5 2 #:levels 5 diff --git a/collects/plot/tests/plot3d-tests.rkt b/collects/plot/tests/plot3d-tests.rkt index 8182229c66..65252103c6 100644 --- a/collects/plot/tests/plot3d-tests.rkt +++ b/collects/plot/tests/plot3d-tests.rkt @@ -189,6 +189,14 @@ (time (plot3d (contour-intervals3d f5 -4 4 -4 4 #:label "z"))) +(time (plot3d (contour-intervals3d + (λ (x y) + (define z (- x y)) + (cond [(< z -1) -1] + [(> z 1) 1] + [else z])) + -2 2 -2 2))) + (time (plot3d (contour-intervals3d (λ (x y) (+ x y))) #:x-min #e100000000000000.0 #:x-max #e100000000000000.1 From 24e6b04cc8328e0dd2c0d0eb6db5049612fc1455 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 6 Aug 2012 17:25:45 -0400 Subject: [PATCH 671/746] Update version number for the v5.3 release --- src/racket/src/schvers.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 5c5f3fb4c7..8f8ce74ad4 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.2.900.1" +#define MZSCHEME_VERSION "5.3" #define MZSCHEME_VERSION_X 5 -#define MZSCHEME_VERSION_Y 2 -#define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 1 +#define MZSCHEME_VERSION_Y 3 +#define MZSCHEME_VERSION_Z 0 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 21830bfa5842f64ca0c81b59419aed4eb51968d9 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 6 Aug 2012 18:50:33 -0400 Subject: [PATCH 672/746] New Racket version 5.3. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 12 ++++++------ src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index 2341783e47..a846f1bda2 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 33ffe2c13f..8a2a9c6bc3 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,900,1 - PRODUCTVERSION 5,2,900,1 + FILEVERSION 5,3,0,0 + PRODUCTVERSION 5,3,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 2, 900, 1\0" + VALUE "FileVersion", "5, 3, 0, 0\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 900, 1\0" + VALUE "ProductVersion", "5, 3, 0, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index e617914037..26a9a1e8e1 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,900,1 - PRODUCTVERSION 5,2,900,1 + FILEVERSION 5,3,0,0 + PRODUCTVERSION 5,3,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 2, 900, 1" + VALUE "FileVersion", "5, 3, 0, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2012 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 2, 900, 1" + VALUE "ProductVersion", "5, 3, 0, 0" END END BLOCK "VarFileInfo" @@ -105,10 +105,10 @@ CAPTION "MzCOM" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,76,69,50,14,BS_CENTER - CTEXT "MzCOM v. 5.2",IDC_STATIC,71,8,61,8 + CTEXT "MzCOM v. 5.3",IDC_STATIC,71,8,61,8 CTEXT "Copyright (c) 2000-2012 PLT (Paul Steckler)",IDC_STATIC, 41,20,146,9 - CTEXT "Racket v. 5.2",IDC_STATIC,64,35,75,8 + CTEXT "Racket v. 5.3",IDC_STATIC,64,35,75,8 CTEXT "Copyright (c) 1995-2012 PLT Inc.",IDC_STATIC, 30,47,143,8 ICON MZICON,IDC_STATIC,11,16,20,20 diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index 465b7777ac..487b1ef097 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.2.900.1 = s 'MzObj Class' + MzCOM.MzObj.5.3.0.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.2.900.1' + CurVer = s 'MzCOM.MzObj.5.3.0.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.2.900.1' + ProgID = s 'MzCOM.MzObj.5.3.0.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 3bbf686517..34c5833b5c 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index ece8c32489..b22b935e9c 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,900,1 - PRODUCTVERSION 5,2,900,1 + FILEVERSION 5,3,0,0 + PRODUCTVERSION 5,3,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 2, 900, 1\0" + VALUE "FileVersion", "5, 3, 0, 0\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 900, 1\0" + VALUE "ProductVersion", "5, 3, 0, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 8bd200a6d8..774ac73b35 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,900,1 - PRODUCTVERSION 5,2,900,1 + FILEVERSION 5,3,0,0 + PRODUCTVERSION 5,3,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 2, 900, 1\0" + VALUE "FileVersion", "5, 3, 0, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 900, 1\0" + VALUE "ProductVersion", "5, 3, 0, 0\0" END END BLOCK "VarFileInfo" From d8dc08748237fd18391322c57b97434d0f00426d Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 7 Aug 2012 00:10:01 -0400 Subject: [PATCH 673/746] v5.3 stuff (cherry picked from commit 08b271d34c22b1916ad51d3b413c619122395da8) --- collects/meta/web/download/installers.txt | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index c9cbc28237..7b1a4f721e 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -212,3 +212,27 @@ 16601808 5.2/racket/racket-5.2-src-mac.dmg 16260740 5.2/racket/racket-5.2-src-unix.tgz 19575041 5.2/racket/racket-5.2-src-win.zip +11235593 5.3/racket-textual/racket-textual-5.3-bin-i386-linux-f12.sh +11248024 5.3/racket-textual/racket-textual-5.3-bin-i386-linux-ubuntu-karmic.sh +11806657 5.3/racket-textual/racket-textual-5.3-bin-i386-osx-mac.dmg +8616632 5.3/racket-textual/racket-textual-5.3-bin-i386-win32.exe +11733097 5.3/racket-textual/racket-textual-5.3-bin-ppc-osx-mac.dmg +11429790 5.3/racket-textual/racket-textual-5.3-bin-x86_64-linux-debian-squeeze.sh +11433426 5.3/racket-textual/racket-textual-5.3-bin-x86_64-linux-f14.sh +11944406 5.3/racket-textual/racket-textual-5.3-bin-x86_64-osx-mac.dmg +8985418 5.3/racket-textual/racket-textual-5.3-bin-x86_64-win32.exe +6200415 5.3/racket-textual/racket-textual-5.3-src-mac.dmg +6076092 5.3/racket-textual/racket-textual-5.3-src-unix.tgz +7163517 5.3/racket-textual/racket-textual-5.3-src-win.zip +63546257 5.3/racket/racket-5.3-bin-i386-linux-f12.sh +63584563 5.3/racket/racket-5.3-bin-i386-linux-ubuntu-karmic.sh +66195664 5.3/racket/racket-5.3-bin-i386-osx-mac.dmg +43257532 5.3/racket/racket-5.3-bin-i386-win32.exe +66989480 5.3/racket/racket-5.3-bin-ppc-osx-mac.dmg +63926568 5.3/racket/racket-5.3-bin-x86_64-linux-debian-squeeze.sh +63943730 5.3/racket/racket-5.3-bin-x86_64-linux-f14.sh +66712297 5.3/racket/racket-5.3-bin-x86_64-osx-mac.dmg +43943553 5.3/racket/racket-5.3-bin-x86_64-win32.exe +18849342 5.3/racket/racket-5.3-src-mac.dmg +18111154 5.3/racket/racket-5.3-src-unix.tgz +21394184 5.3/racket/racket-5.3-src-win.zip From 87eca8aef72f6b1c18df76263bfe73f7023fcebd Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 8 Oct 2012 02:33:25 -0400 Subject: [PATCH 674/746] Alpha version number for the v5.3.1 release --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 7e642ab091..2199536996 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.3.0.24" +#define MZSCHEME_VERSION "5.3.0.900" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 3 #define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 24 +#define MZSCHEME_VERSION_W 900 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 2bd1d9f123b1f61475196317393344766ff190b4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 8 Oct 2012 08:28:39 -0500 Subject: [PATCH 675/746] adjust the code that initializes the pre-"first Run" repl construction so it has the right inspector closes PR 13056 (cherry picked from commit 9ed7b44222cf958f737ad64531a67aec0e9d1bf1) --- collects/drracket/private/module-language.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/drracket/private/module-language.rkt b/collects/drracket/private/module-language.rkt index 3575b0ed7b..a979084943 100644 --- a/collects/drracket/private/module-language.rkt +++ b/collects/drracket/private/module-language.rkt @@ -125,6 +125,7 @@ (define/private (get-ns str) (define ev (make-evaluator 'racket/base)) + (ev `(current-inspector ,(current-inspector))) (ev `(parameterize ([read-accept-reader #t]) (define stx (read-syntax "here" (open-input-string ,str))) (define modname From 9086e14b5e3b6fa91ab4ff30fa681fd54b772bb5 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 8 Oct 2012 16:28:54 -0400 Subject: [PATCH 676/746] Allow `#:opaque` and `#:struct` in `require/typed`. (cherry picked from commit 9054d0db7dee7d523b6a56a1cb68d703c3426f6f) --- collects/typed-racket/base-env/prims.rkt | 9 +++------ .../scribblings/reference/special-forms.scrbl | 8 ++++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/collects/typed-racket/base-env/prims.rkt b/collects/typed-racket/base-env/prims.rkt index 6ead31e331..6abde03fe5 100644 --- a/collects/typed-racket/base-env/prims.rkt +++ b/collects/typed-racket/base-env/prims.rkt @@ -101,18 +101,15 @@ This file defines two sorts of primitives. All of them are provided into any mod (define-syntax-class (struct-clause legacy) ;#:literals (struct) #:attributes (nm (body 1) (constructor-parts 1)) - (pattern [struct nm:opt-parent (body ...) (~var constructor (opt-constructor legacy #'nm.nm))] - #:fail-unless (eq? 'struct (syntax-e #'struct)) #f + (pattern [(~or (~datum struct) #:struct) nm:opt-parent (body ...) (~var constructor (opt-constructor legacy #'nm.nm))] #:with (constructor-parts ...) #'constructor.value)) (define-syntax-class opaque-clause ;#:literals (opaque) #:attributes (ty pred opt) - (pattern [opaque ty:id pred:id] - #:fail-unless (eq? 'opaque (syntax-e #'opaque)) #f + (pattern [(~or (~datum opaque) #:opaque) ty:id pred:id] #:with opt #'()) - (pattern [opaque ty:id pred:id #:name-exists] - #:fail-unless (eq? 'opaque (syntax-e #'opaque)) #f + (pattern [(~or (~datum opaque) #:opaque) opaque ty:id pred:id #:name-exists] #:with opt #'(#:name-exists))) (define-syntax-class (clause legacy lib) diff --git a/collects/typed-racket/scribblings/reference/special-forms.scrbl b/collects/typed-racket/scribblings/reference/special-forms.scrbl index 3ee935d6fc..e46727213e 100644 --- a/collects/typed-racket/scribblings/reference/special-forms.scrbl +++ b/collects/typed-racket/scribblings/reference/special-forms.scrbl @@ -340,14 +340,14 @@ contexts. Here, @racket[_m] is a module spec, @racket[_pred] is an identifier naming a predicate, and @racket[_r] is an optionally-renamed identifier. -@defform/subs[#:literals (struct opaque) +@defform/subs[#:literals (struct) (require/typed m rt-clause ...) ([rt-clause [r t] - [struct name ([f : t] ...) + [#:struct name ([f : t] ...) struct-option ...] - [struct (name parent) ([f : t] ...) + [#:struct (name parent) ([f : t] ...) struct-option ...] - [opaque t pred]] + [#:opaque t pred]] [struct-option (code:line #:constructor-name constructor-id) (code:line #:extra-constructor-name constructor-id)])] From da477c0c82150c4535e678b32215b1217ffd2cf5 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 9 Oct 2012 12:06:48 -0400 Subject: [PATCH 677/746] Handle contract generation for recursive class types. (cherry picked from commit 6945c5bfb1a807e1e2d4b6cdf50db83b0623ad1d) --- collects/typed-racket/private/type-contract.rkt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collects/typed-racket/private/type-contract.rkt b/collects/typed-racket/private/type-contract.rkt index c417b3aa3a..036a4fb4c8 100644 --- a/collects/typed-racket/private/type-contract.rkt +++ b/collects/typed-racket/private/type-contract.rkt @@ -299,6 +299,8 @@ #,(contract-kind->keyword (current-contract-kind)))]) n*))))] [(Value: #f) #'false/c] + [(Instance: (? Mu? t)) + (t->c (make-Instance (resolve-once t)))] [(Instance: (Class: _ _ (list (list name fcn) ...))) (set-impersonator!) (with-syntax ([(fcn-cnts ...) (for/list ([f fcn]) (t->c/fun f #:method #t))] From c591baf04acccd3cf7c3c4ba70baab79921b1681 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Mon, 8 Oct 2012 19:29:10 -0400 Subject: [PATCH 678/746] Add `Frame%` and `message-box` types. (cherry picked from commit 385246f4db7f0bbf4ecfcdc5ee8a0f7ccbfdd4a1) --- collects/typed/framework/framework.rkt | 5 ++++- collects/typed/mred/mred.rkt | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/collects/typed/framework/framework.rkt b/collects/typed/framework/framework.rkt index ee2e59f593..d03ebffe95 100644 --- a/collects/typed/framework/framework.rkt +++ b/collects/typed/framework/framework.rkt @@ -32,7 +32,10 @@ (-> (Instance Style-List%))] [racket:text% Racket:Text%] [gui-utils:ok/cancel-buttons - ((Instance Horizontal-Panel%) ((Instance Button%) (Instance Event%) -> Void) ((Instance Button%) (Instance Event%) -> Void) -> (values Any Any))]) + ((Instance Horizontal-Panel%) + ((Instance Button%) (Instance Event%) -> Void) + ((Instance Button%) (Instance Event%) -> Void) + -> (values Any Any))]) (require/typed/provide "prefs-contract.rkt" [preferences:get-drracket:large-letters-font (-> (U #f (Pair String Integer)))]) diff --git a/collects/typed/mred/mred.rkt b/collects/typed/mred/mred.rkt index 1fc5b1e356..9b1ca81a75 100644 --- a/collects/typed/mred/mred.rkt +++ b/collects/typed/mred/mred.rkt @@ -2,6 +2,10 @@ (require typed/private/utils) +(dt Frame% (Class () + ([label String]) + ([show (Any -> Void)]))) + (dt Bitmap% (Class (Real Real Boolean) () ([get-width (-> Integer)] @@ -68,11 +72,12 @@ [get-text (Integer (U Integer 'eof) -> String)] [insert (String Number Number -> Void)]))) -(dt Button% (Class () () ())) +(dt Button% (Rec B% (Class (String (Instance Frame%) (B% Any -> Any)) () ()))) (dt Event% (Class () () ())) (require/typed/provide - scheme/gui + racket/gui + [frame% Frame%] [button% Button%] [event% Event%] [the-font-list (Instance Font-List%)] @@ -88,6 +93,7 @@ [bitmap% Bitmap%] [color% Color%] [snip% Snip%] + [message-box (String String -> (U 'ok 'cancel 'yes 'no))] [open-input-text-editor ((Instance Text%) Integer (U 'end Integer) ((Instance Snip%) -> (Instance Snip%)) (Instance Text%) Boolean -> Input-Port)]) From 492174f7a1757bed6ccba7f6b75b67ac4a018e5b Mon Sep 17 00:00:00 2001 From: Kevin Tew Date: Tue, 9 Oct 2012 14:29:44 -0600 Subject: [PATCH 679/746] [Distributed Places] use racket -lm to launch new racket nodes instead of -tm (cherry picked from commit 40ca07ee7ca238fa63329603e557e7fdfcc38f3a) --- collects/racket/place/distributed.rkt | 18 ++++++++++-------- .../scribblings/reference/distributed.scrbl | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/collects/racket/place/distributed.rkt b/collects/racket/place/distributed.rkt index 537a1ed847..74abab4205 100644 --- a/collects/racket/place/distributed.rkt +++ b/collects/racket/place/distributed.rkt @@ -26,7 +26,6 @@ (provide ssh-bin-path racket-path - distributed-launch-path DEFAULT-ROUTER-PORT @@ -1403,7 +1402,7 @@ #:initial-message [initial-message #f] #:racket-path [racketpath (racket-path)] #:ssh-bin-path [sshpath (ssh-bin-path)] - #:distributed-launch-path [distributedlaunchpath (->writeable-module-path distributed-launch-path)] + #:distributed-launch-path [distributedlaunchpath #f] #:restart-on-exit [restart-on-exit #f] #:named [named #f] #:thunk [thunk #f]) @@ -1422,7 +1421,7 @@ #:initial-message [initial-message #f] #:racket-path [racketpath (racket-path)] #:ssh-bin-path [sshpath (ssh-bin-path)] - #:distributed-launch-path [distributedlaunchpath (->writeable-module-path distributed-launch-path)] + #:distributed-launch-path [distributedlaunchpath #f] #:restart-on-exit [restart-on-exit #f] #:named [named #f] #:thunk [thunk #f]) @@ -1439,7 +1438,7 @@ #:initial-message [initial-message #f] #:racket-path [racketpath (racket-path)] #:ssh-bin-path [sshpath (ssh-bin-path)] - #:distributed-launch-path [distributedlaunchpath (->writeable-module-path distributed-launch-path)] + #:distributed-launch-path [distributedlaunchpath #f] #:restart-on-exit [restart-on-exit #f]) (define node (spawn-remote-racket-node host #:listen-port listen-port @@ -1467,18 +1466,20 @@ (define (spawn-remote-racket-node host #:listen-port [listen-port DEFAULT-ROUTER-PORT] #:racket-path [racketpath (racket-path)] #:ssh-bin-path [sshpath (ssh-bin-path)] - #:distributed-launch-path [distributedlaunchpath (->writeable-module-path distributed-launch-path)] + #:distributed-launch-path [distributedlaunchpath #f] #:use-current-ports [use-current-ports #f]) (new remote-node% [host-name host] [listen-port listen-port] - [cmdline-list (list sshpath host racketpath "-tm" distributedlaunchpath "spawn" (->string listen-port))] + [cmdline-list (if distributedlaunchpath + (list sshpath host racketpath "-tm" distributedlaunchpath "spawn" (->string listen-port)) + (list sshpath host racketpath "-lm racket/place/distributed/launch spawn" (->string listen-port)))] [use-current-ports use-current-ports])) (define (create-place-node host #:listen-port [listen-port DEFAULT-ROUTER-PORT] #:racket-path [racketpath (racket-path)] #:ssh-bin-path [sshpath (ssh-bin-path)] - #:distributed-launch-path [distributedlaunchpath (->writeable-module-path distributed-launch-path)] + #:distributed-launch-path [distributedlaunchpath #f] #:use-current-ports [use-current-ports #t]) (spawn-remote-racket-node host #:listen-port listen-port @@ -1508,6 +1509,7 @@ (define-syntax-rule (after-seconds _seconds _body ...) (new after-seconds% [seconds _seconds] [thunk (lambda () _body ...)])) +;; -> node name -> (define (connect-to-named-place node name) (send node remote-connect name)) @@ -1668,7 +1670,7 @@ (define (spawn-node-at host #:listen-port [listen-port DEFAULT-ROUTER-PORT] #:racket-path [racketpath (racket-path)] #:ssh-bin-path [sshpath (ssh-bin-path)] - #:distributed-launch-path [distributedlaunchpath (->writeable-module-path distributed-launch-path)]) + #:distributed-launch-path [distributedlaunchpath #f]) (define ch (make-channel)) (thread diff --git a/collects/scribblings/reference/distributed.scrbl b/collects/scribblings/reference/distributed.scrbl index c5d0cc38f3..57be85dd24 100644 --- a/collects/scribblings/reference/distributed.scrbl +++ b/collects/scribblings/reference/distributed.scrbl @@ -188,7 +188,7 @@ Spawns a new remote node at @racket[hostname] and returns a @racket[remote-node% [#:racket-path racket-path string-path? (racket-path)] [#:ssh-bin-path ssh-path string-path? (ssh-bin-path)] [#:distributed-launch-path launcher-path string-path? (path->string distributed-launch-path)] - [#:use-current-ports use-current-ports #t]) (is-a?/c remote-node%)]{ + [#:use-current-ports use-current-ports boolean? #t]) (is-a?/c remote-node%)]{ Like @racket[spawn-remote-racket-node], but the @racket[current-output-port] and @racket[current-error-port] are used as the standard ports for the spawned process instead of new pipe ports.} From 7a0793e0e5580caf52827527869832fdcbcf6e36 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 24 Sep 2012 18:49:10 -0400 Subject: [PATCH 680/746] Recommend float-specific operations in case of unexpected complex. Please merge to release. (cherry picked from commit 7d317f1e96e77ca9ce85136608b49d420ad39630) --- collects/typed-racket/optimizer/float-complex.rkt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/collects/typed-racket/optimizer/float-complex.rkt b/collects/typed-racket/optimizer/float-complex.rkt index b05872be52..3c2b9e9cd5 100644 --- a/collects/typed-racket/optimizer/float-complex.rkt +++ b/collects/typed-racket/optimizer/float-complex.rkt @@ -449,7 +449,13 @@ (subtypeof? subexpr -Real))) (log-missed-optimization "unexpected complex type" - "This expression has a Complex type, despite all its arguments being reals. If you do not want or expect complex numbers as results, you may want to restrict the type of the arguments, which may have a beneficial impact on performance." + (string-append + "This expression has a Complex type, despite all its " + "arguments being reals. If you do not want or expect " + "complex numbers as results, you may want to restrict " + "the type of the arguments or use float-specific " + "operations (e.g. flsqrt), which may have a beneficial " + "impact on performance.") this-syntax)) ;; We don't actually want to match. #:when #f From 3837602fe6106111a6b18a4c7c8bcf9f173c54f3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 9 Oct 2012 20:04:33 -0600 Subject: [PATCH 681/746] win32: fix combo-field% click handling Closes PR 13173 Merge to v5.3.1 (cherry picked from commit 75008f14d7a46d28262e76de2b9603a54e20c896) --- collects/mred/private/wx/win32/canvas.rkt | 8 ++++++-- collects/mred/private/wx/win32/item.rkt | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/collects/mred/private/wx/win32/canvas.rkt b/collects/mred/private/wx/win32/canvas.rkt index 8f965dc57c..e1c0f655d0 100644 --- a/collects/mred/private/wx/win32/canvas.rkt +++ b/collects/mred/private/wx/win32/canvas.rkt @@ -90,7 +90,8 @@ is-auto-scroll? is-disabled-scroll? get-virtual-width get-virtual-height reset-auto-scroll - refresh-for-autoscroll) + refresh-for-autoscroll + try-mouse) (define hscroll? (or (memq 'hscroll style) (memq 'auto-hscroll style))) @@ -238,7 +239,10 @@ [else (super wndproc w msg wParam lParam default)])) (define/override (wndproc-for-ctlproc w msg wParam lParam default) - (default w msg wParam lParam)) + ;; act on clicks for a combo field: + (if (try-mouse w msg wParam lParam) + 0 + (default w msg wParam lParam))) (define dc (new dc% [canvas this] [transparent? (memq 'transparent style)])) (send dc start-backing-retained) diff --git a/collects/mred/private/wx/win32/item.rkt b/collects/mred/private/wx/win32/item.rkt index 7140637943..5fedef7d8a 100644 --- a/collects/mred/private/wx/win32/item.rkt +++ b/collects/mred/private/wx/win32/item.rkt @@ -20,7 +20,6 @@ (class % (inherit on-set-focus on-kill-focus - try-mouse wndproc) (init-field [callback void]) From 480222a6cf0bf2efd7b9888aadd95910c2c5309b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 9 Oct 2012 20:14:11 -0600 Subject: [PATCH 682/746] fix `vector-append' error reporting Closes PR 13151 Merge to v5.3.1 (cherry picked from commit a414b34b1494a5cd3d6b05ad3abaede9a2781261) --- collects/racket/vector.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/racket/vector.rkt b/collects/racket/vector.rkt index 6c94df2b83..161e70ea37 100644 --- a/collects/racket/vector.rkt +++ b/collects/racket/vector.rkt @@ -173,7 +173,7 @@ (let* ([lens (for/list ([e (in-list vs)] [i (in-naturals)]) (if (vector? e) (unsafe-vector-length e) - (raise-argument-error 'vector-append "vector?" e i)))] + (apply raise-argument-error 'vector-append "vector?" i vs)))] [new-v (make-vector (apply + lens))]) (let loop ([start 0] [lens lens] [vs vs]) (when (pair? lens) From ffc6dd5e83aafac1189686f2823768a7a5bb4bca Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 9 Oct 2012 20:23:56 -0600 Subject: [PATCH 683/746] racket/gui win32: fix drag-and-drop onto frame Closes PR 13109 Merge to v5.3.1 (cherry picked from commit ebe0b64d47be80a78b99635dd8e947807a767d6c) --- collects/mred/private/wx/win32/window.rkt | 3 --- 1 file changed, 3 deletions(-) diff --git a/collects/mred/private/wx/win32/window.rkt b/collects/mred/private/wx/win32/window.rkt index d982b0bf6e..23d0f506c1 100644 --- a/collects/mred/private/wx/win32/window.rkt +++ b/collects/mred/private/wx/win32/window.rkt @@ -64,8 +64,6 @@ (define-shell32 DragAcceptFiles (_wfun _HWND _BOOL -> _void)) (define _HDROP _pointer) -(define-shell32 DragQueryPoint (_wfun _HDROP (p : (_ptr o _POINT)) -> (r : _BOOL) - -> (if r p (failed 'DragQueryPoint)))) (define-shell32 DragQueryFileW (_wfun _HDROP _UINT _pointer _UINT -> _UINT)) (define-shell32 DragFinish (_wfun _HDROP -> _void)) @@ -438,7 +436,6 @@ (define/private (handle-drop-files wParam) (let* ([hdrop (cast wParam _WPARAM _HDROP)] - [pt (DragQueryPoint hdrop)] [count (DragQueryFileW hdrop #xFFFFFFFF #f 0)]) (for ([i (in-range count)]) (let* ([len (DragQueryFileW hdrop i #f 0)] From 7c6b0f4aa39ca721a7fc0ad9924ac87f9f1994fe Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 10 Oct 2012 06:49:01 -0600 Subject: [PATCH 684/746] Scribble: add some macron accents for Latex Merge to v5.3.1 (cherry picked from commit de9ccea7f1b11b43c17f34a2c715dcb452a39e2d) --- collects/scribble/latex-render.rkt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/collects/scribble/latex-render.rkt b/collects/scribble/latex-render.rkt index 98c0011f44..0e12c7a3b5 100644 --- a/collects/scribble/latex-render.rkt +++ b/collects/scribble/latex-render.rkt @@ -964,6 +964,16 @@ [(#\Ô) "\\^{O}"] [(#\û) "\\^{u}"] [(#\Û) "\\^{U}"] + [(#\ā) "\\={a}"] + [(#\ē) "\\={e}"] + [(#\ī) "\\={i}"] + [(#\ō) "\\={o}"] + [(#\ū) "\\={u}"] + [(#\Ā) "\\={A}"] + [(#\Ē) "\\={E}"] + [(#\Ī) "\\={I}"] + [(#\Ō) "\\={O}"] + [(#\Ū) "\\={U}"] [(#\ä) "\\\"a"] [(#\Ä) "\\\"A"] [(#\ü) "\\\"u"] From 5b4f452f16edfcc7edd8837d69c7021f2747bce3 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 11 Oct 2012 19:30:31 -0400 Subject: [PATCH 685/746] New Racket version 5.3.0.900. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index 4ae8aa662f..de8fc6cc6f 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index dfed95fa7a..3f0feaef7c 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,24 - PRODUCTVERSION 5,3,0,24 + FILEVERSION 5,3,0,900 + PRODUCTVERSION 5,3,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 3, 0, 24\0" + VALUE "FileVersion", "5, 3, 0, 900\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 3, 0, 24\0" + VALUE "ProductVersion", "5, 3, 0, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index f173124c92..951d2dc30a 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,24 - PRODUCTVERSION 5,3,0,24 + FILEVERSION 5,3,0,900 + PRODUCTVERSION 5,3,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 3, 0, 24" + VALUE "FileVersion", "5, 3, 0, 900" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2012 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 3, 0, 24" + VALUE "ProductVersion", "5, 3, 0, 900" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index d439958a0a..a83a172b08 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.3.0.24 = s 'MzObj Class' + MzCOM.MzObj.5.3.0.900 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.3.0.24' + CurVer = s 'MzCOM.MzObj.5.3.0.900' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.3.0.24' + ProgID = s 'MzCOM.MzObj.5.3.0.900' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 68f64285c8..9a9c3dad00 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 228fa86177..2bed428fef 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,24 - PRODUCTVERSION 5,3,0,24 + FILEVERSION 5,3,0,900 + PRODUCTVERSION 5,3,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 3, 0, 24\0" + VALUE "FileVersion", "5, 3, 0, 900\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 3, 0, 24\0" + VALUE "ProductVersion", "5, 3, 0, 900\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 25aa589b08..7a827c12aa 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,24 - PRODUCTVERSION 5,3,0,24 + FILEVERSION 5,3,0,900 + PRODUCTVERSION 5,3,0,900 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 3, 0, 24\0" + VALUE "FileVersion", "5, 3, 0, 900\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 3, 0, 24\0" + VALUE "ProductVersion", "5, 3, 0, 900\0" END END BLOCK "VarFileInfo" From 8c0d033fabfe9baaa1d152c2295b048cf2a067f4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 10 Oct 2012 10:24:10 -0500 Subject: [PATCH 686/746] fix some part of the check syntax blinking arrows infrastructure to better cope with tooltips when tabs change and when the frame becomes in-active. related to PR 13139 (cherry picked from commit 197b8308d0a41914409296c0ae523fcba8a38662) --- collects/drracket/private/syncheck/gui.rkt | 32 ++++++++++++---------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/collects/drracket/private/syncheck/gui.rkt b/collects/drracket/private/syncheck/gui.rkt index d3ca124b05..7d3b1464bd 100644 --- a/collects/drracket/private/syncheck/gui.rkt +++ b/collects/drracket/private/syncheck/gui.rkt @@ -988,6 +988,12 @@ If the namespace does not, they are colored the unbound color. [else (update-drawn-arrows)])) + (define tooltips-enabled? #f) + (define/public (enable-tooltips x?) + (set! tooltips-enabled? x?) + (when (update-latent-arrows mouse-x mouse-y) + (start-arrow-draw-timer syncheck-arrow-delay))) + ;; Given a mouse position, updates latent-* variables and tooltips (define/private (update-latent-arrows x y) (define-values (pos text eles tooltip) @@ -999,19 +1005,9 @@ If the namespace does not, they are colored the unbound color. (define-values (pos text) (get-pos/text-dc-location x y)) (define arrow-record (and text pos (hash-ref arrow-records text #f))) (define eles (and arrow-record (interval-map-ref arrow-record pos null))) - (define we-focused-frame? - (let ([f (get-top-level-focus-window)]) - (and f - (eq? f - (let loop ([w (get-canvas)]) - (cond - [(is-a? w top-level-window<%>) - w] - [(is-a? w area<%>) - (loop (send w get-parent))] - [else #f])))))) - (define tooltip (cond [(not we-focused-frame?) #f] - [(equal? latent-eles eles) latent-tooltip] + (define tooltip (cond [(not tooltips-enabled?) #f] + [(and (equal? latent-eles eles) latent-tooltip) + latent-tooltip] [else (get-tooltip eles)])) (values pos text eles tooltip)] [else @@ -1027,7 +1023,7 @@ If the namespace does not, they are colored the unbound color. (or text-changed? eles-changed? tooltip-changed?)) - (define (update-drawn-arrows) + (define/private (update-drawn-arrows) (set! cursor-pos latent-pos) (set! cursor-text latent-text) (set! cursor-eles latent-eles) @@ -1505,6 +1501,8 @@ If the namespace does not, they are colored the unbound color. (define/augment (on-tab-change old-tab new-tab) (inner (void) on-tab-change old-tab new-tab) + (send (send old-tab get-defs) enable-tooltips #f) + (send (send new-tab get-defs) enable-tooltips #t) (send (send old-tab get-defs) syncheck:update-drawn-arrows) (send (send new-tab get-defs) syncheck:update-drawn-arrows) (if (send new-tab get-error-report-visible?) @@ -1513,6 +1511,12 @@ If the namespace does not, they are colored the unbound color. (send report-error-canvas set-editor (send new-tab get-error-report-text)) (update-button-visibility/tab new-tab)) + (define/override (on-activate active?) + (define defs (send (get-current-tab) get-defs)) + (send defs enable-tooltips active?) + (send defs syncheck:update-drawn-arrows) + (super on-activate active?)) + (define/private (update-button-visibility/tab tab) (update-button-visibility/settings (send (send tab get-defs) get-next-settings))) (inherit sort-toolbar-buttons-panel) From 868b02c54e38a84a6b83b46bf9b4b946516f441b Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 10 Oct 2012 10:28:25 -0500 Subject: [PATCH 687/746] rename 'online' to 'speculative' in the drracket GUI. closes PR 13176 (cherry picked from commit f756f694e76efcad48a6d5dbf70b8a429f49d8cc) --- .../private/english-string-constants.rkt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/collects/string-constants/private/english-string-constants.rkt b/collects/string-constants/private/english-string-constants.rkt index 912223c80f..076c10829c 100644 --- a/collects/string-constants/private/english-string-constants.rkt +++ b/collects/string-constants/private/english-string-constants.rkt @@ -233,19 +233,19 @@ please adhere to these guidelines: (sc-f2-to-un/lock "f2 to (un)lock") ;; the online check syntax status messages (mouse over the bottom right of drracket's window to see the messages during online expansion's various phases) - (online-expansion-running "Online expansion running") + (online-expansion-running "Speculative expansion running") (online-expansion-only-raw-text-files-supported "Only pure text files supported") - (online-expansion-abnormal-termination "Online expansion terminated abnormally") - (online-expansion-finished-successfully "Online expansion finished successfully") + (online-expansion-abnormal-termination "Speculative expansion terminated abnormally") + (online-expansion-finished-successfully "Speculative expansion finished successfully") (jump-to-error "Jump to Error") - (online-expansion-is-disabled "Online expansion is disabled") + (online-expansion-is-disabled "Speculative expansion is disabled") ;; these next two show up in the bar along the bottom of the drracket window - (online-expansion-pending "Online expansion pending ...") - (online-expansion-finished "Online expansion finished") ;; note: there may still be errors in this case + (online-expansion-pending "Speculative expansion pending ...") + (online-expansion-finished "Speculative expansion finished") ;; note: there may still be errors in this case ;; the online expansion preferences pane - (online-expansion "Online expansion") ;; title of prefs pane + (online-expansion "Speculative expansion") ;; title of prefs pane ; the different kinds of errors (online-expansion-show-read-errors-as "Show read-level errors") (online-expansion-show-variable-errors-as "Show unbound identifier errors") From 5fcc7d2240b31e845d2fd4fdb6f81c252baeeaca Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 10 Oct 2012 19:46:52 -0500 Subject: [PATCH 688/746] preserve the error-print-source parameter when installing planet packages (cherry picked from commit cb763c81b99f5a498952707057e91fbb73cc292f) --- collects/planet/private/resolver.rkt | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/planet/private/resolver.rkt b/collects/planet/private/resolver.rkt index 19bbfb7624..028e35f176 100644 --- a/collects/planet/private/resolver.rkt +++ b/collects/planet/private/resolver.rkt @@ -343,6 +343,7 @@ See the scribble documentation on the planet/resolver module. [current-module-declare-name #f] [use-compiled-file-paths (call-with-parameterization orig-paramz use-compiled-file-paths)] [current-library-collection-paths (call-with-parameterization orig-paramz current-library-collection-paths)] + [error-print-source-location (call-with-parameterization orig-paramz error-print-source-location)] [powerful-security-guard (call-with-parameterization orig-paramz current-security-guard)]) (let-values ([(path pkg) (get-planet-module-path/pkg/internal spec rmp stx load?)]) (when load? (add-pkg-to-diamond-registry! pkg stx)) From 917cd28782b740f0beb7d4bede3cbd9888d6dfff Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 9 Oct 2012 18:32:11 -0400 Subject: [PATCH 689/746] fixed template tests (cherry picked from commit 07da9c0c3c521f55bef45efdc1a4d8619d31c194) --- collects/tests/stxparse/test-template.rkt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/tests/stxparse/test-template.rkt b/collects/tests/stxparse/test-template.rkt index 16a50b6017..c6a4dee3ca 100644 --- a/collects/tests/stxparse/test-template.rkt +++ b/collects/tests/stxparse/test-template.rkt @@ -179,7 +179,7 @@ ;; Error tests (terx (template (1 ...)) - #rx"no pattern variables in term before ellipsis") + #rx"no pattern variables before ellipsis in template") (terx (template (uu ...)) #rx"too many ellipses in template") @@ -188,7 +188,7 @@ #rx"too many ellipses in template") (terx (template aa) - #rx"pattern variable used at wrong ellipsis depth") + #rx"missing ellipses with pattern variable in template") (terx (template (?@)) #rx"illegal use") @@ -199,7 +199,7 @@ (define-template-metafunction (bad-mf stx) 123) (terx (template (bad-mf)) - #rx"result of metafunction was not syntax") + #rx"result of template metafunction was not syntax") (terx (with-syntax ([(bb ...) #'(y z)]) (template ((aa bb) ...))) #rx"incompatible ellipsis match counts") From c5d2ebcc536043078ed1411a301cb3c44a9a7e52 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 11 Oct 2012 18:11:10 -0400 Subject: [PATCH 690/746] Only recommend dropping exactness in truly inexact contexts. Please merge to release. (cherry picked from commit 758e4ff112bf83544fdfc833f454930cc0bc5322) --- .../missed-optimizations/precision-loss.rkt | 6 +++--- .../typed-racket/optimizer/tests/case-arrow.rkt | 14 +++++++------- collects/typed-racket/optimizer/float.rkt | 3 ++- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/collects/tests/typed-racket/optimizer/missed-optimizations/precision-loss.rkt b/collects/tests/typed-racket/optimizer/missed-optimizations/precision-loss.rkt index b8ea816ff5..c39ee30291 100644 --- a/collects/tests/typed-racket/optimizer/missed-optimizations/precision-loss.rkt +++ b/collects/tests/typed-racket/optimizer/missed-optimizations/precision-loss.rkt @@ -10,15 +10,12 @@ TR missed opt: precision-loss.rkt 48:8 (* 3/4 2/3) -- all args float-arg-expr, r TR opt: precision-loss.rkt 49:3 (car (list (* 2.0 (ann (* 3/4 2/3) Real)))) -- pair TR missed opt: precision-loss.rkt 49:26 (* 3/4 2/3) -- all args float-arg-expr, result not Float -- caused by: 49:29 3/4, 49:33 2/3 TR missed opt: precision-loss.rkt 49:14 (* 2.0 (ann (* 3/4 2/3) Real)) -- all args float-arg-expr, result not Float -- caused by: 49:26 (* 3/4 2/3) -TR missed opt: precision-loss.rkt 49:14 (* 2.0 (ann (* 3/4 2/3) Real)) -- exact ops inside float expr -- caused by: 49:26 (* 3/4 2/3) TR missed opt: precision-loss.rkt 49:26 (* 3/4 2/3) -- all args float-arg-expr, result not Float -- caused by: 49:29 3/4, 49:33 2/3 TR missed opt: precision-loss.rkt 48:0 (* (ann (* 3/4 2/3) Real) (car (list (* 2.0 (ann (* 3/4 2/3) Real)))) 2.0) -- all args float-arg-expr, result not Float -- caused by: 48:8 (* 3/4 2/3), 49:3 (car (list (* 2.0 (ann (* 3/4 2/3) Real)))) -TR missed opt: precision-loss.rkt 48:0 (* (ann (* 3/4 2/3) Real) (car (list (* 2.0 (ann (* 3/4 2/3) Real)))) 2.0) -- exact ops inside float expr -- caused by: 48:8 (* 3/4 2/3) TR missed opt: precision-loss.rkt 48:8 (* 3/4 2/3) -- all args float-arg-expr, result not Float -- caused by: 48:11 3/4, 48:15 2/3 TR opt: precision-loss.rkt 49:3 (car (list (* 2.0 (ann (* 3/4 2/3) Real)))) -- pair TR missed opt: precision-loss.rkt 49:26 (* 3/4 2/3) -- all args float-arg-expr, result not Float -- caused by: 49:29 3/4, 49:33 2/3 TR missed opt: precision-loss.rkt 49:14 (* 2.0 (ann (* 3/4 2/3) Real)) -- all args float-arg-expr, result not Float -- caused by: 49:26 (* 3/4 2/3) -TR missed opt: precision-loss.rkt 49:14 (* 2.0 (ann (* 3/4 2/3) Real)) -- exact ops inside float expr -- caused by: 49:26 (* 3/4 2/3) TR missed opt: precision-loss.rkt 49:26 (* 3/4 2/3) -- all args float-arg-expr, result not Float -- caused by: 49:29 3/4, 49:33 2/3 2.5 2.75 @@ -28,6 +25,9 @@ TR missed opt: precision-loss.rkt 49:26 (* 3/4 2/3) -- all args float-arg-expr, ) + + + #lang typed/racket ;; warn when the extra precision gained by doing exact computations would diff --git a/collects/tests/typed-racket/optimizer/tests/case-arrow.rkt b/collects/tests/typed-racket/optimizer/tests/case-arrow.rkt index 3d8c3f2971..2a8f0dc815 100644 --- a/collects/tests/typed-racket/optimizer/tests/case-arrow.rkt +++ b/collects/tests/typed-racket/optimizer/tests/case-arrow.rkt @@ -2,29 +2,29 @@ ( TR missed opt: case-arrow.rkt 41:15 (- max min) -- all args float-arg-expr, result not Float -- caused by: 41:18 max, 41:22 min TR missed opt: case-arrow.rkt 41:12 (* (- max min) x) -- all args float-arg-expr, result not Float -- caused by: 41:15 (- max min), 41:27 x -TR missed opt: case-arrow.rkt 41:12 (* (- max min) x) -- exact ops inside float expr -- caused by: 41:15 (- max min) TR missed opt: case-arrow.rkt 41:15 (- max min) -- all args float-arg-expr, result not Float -- caused by: 41:18 max, 41:22 min TR missed opt: case-arrow.rkt 41:9 (/ (* (- max min) x) p) -- all args float-arg-expr, result not Float -- caused by: 41:12 (* (- max min) x), 41:30 p -TR missed opt: case-arrow.rkt 41:9 (/ (* (- max min) x) p) -- exact ops inside float expr -- caused by: 41:12 (* (- max min) x) TR missed opt: case-arrow.rkt 41:15 (- max min) -- all args float-arg-expr, result not Float -- caused by: 41:18 max, 41:22 min TR missed opt: case-arrow.rkt 41:12 (* (- max min) x) -- all args float-arg-expr, result not Float -- caused by: 41:15 (- max min), 41:27 x -TR missed opt: case-arrow.rkt 41:12 (* (- max min) x) -- exact ops inside float expr -- caused by: 41:15 (- max min) TR missed opt: case-arrow.rkt 41:15 (- max min) -- all args float-arg-expr, result not Float -- caused by: 41:18 max, 41:22 min TR missed opt: case-arrow.rkt 41:2 (+ min (/ (* (- max min) x) p)) -- all args float-arg-expr, result not Float -- caused by: 41:5 min, 41:9 (/ (* (- max min) x) p) -TR missed opt: case-arrow.rkt 41:2 (+ min (/ (* (- max min) x) p)) -- exact ops inside float expr -- caused by: 41:9 (/ (* (- max min) x) p) TR missed opt: case-arrow.rkt 41:15 (- max min) -- all args float-arg-expr, result not Float -- caused by: 41:18 max, 41:22 min TR missed opt: case-arrow.rkt 41:12 (* (- max min) x) -- all args float-arg-expr, result not Float -- caused by: 41:15 (- max min), 41:27 x -TR missed opt: case-arrow.rkt 41:12 (* (- max min) x) -- exact ops inside float expr -- caused by: 41:15 (- max min) TR missed opt: case-arrow.rkt 41:15 (- max min) -- all args float-arg-expr, result not Float -- caused by: 41:18 max, 41:22 min TR missed opt: case-arrow.rkt 41:9 (/ (* (- max min) x) p) -- all args float-arg-expr, result not Float -- caused by: 41:12 (* (- max min) x), 41:30 p -TR missed opt: case-arrow.rkt 41:9 (/ (* (- max min) x) p) -- exact ops inside float expr -- caused by: 41:12 (* (- max min) x) TR missed opt: case-arrow.rkt 41:15 (- max min) -- all args float-arg-expr, result not Float -- caused by: 41:18 max, 41:22 min TR missed opt: case-arrow.rkt 41:12 (* (- max min) x) -- all args float-arg-expr, result not Float -- caused by: 41:15 (- max min), 41:27 x -TR missed opt: case-arrow.rkt 41:12 (* (- max min) x) -- exact ops inside float expr -- caused by: 41:15 (- max min) TR missed opt: case-arrow.rkt 41:15 (- max min) -- all args float-arg-expr, result not Float -- caused by: 41:18 max, 41:22 min ) #lang typed/racket + + + + + + + ;; Typechecking functions with case-> types causes the body to be typechecked ;; multiple times, which is fine, except that it used to cause the type table ;; to only have information for the last branch (clobbering). This would cause diff --git a/collects/typed-racket/optimizer/float.rkt b/collects/typed-racket/optimizer/float.rkt index 63092e8ed8..a46b0cc61b 100644 --- a/collects/typed-racket/optimizer/float.rkt +++ b/collects/typed-racket/optimizer/float.rkt @@ -147,7 +147,8 @@ (not (in-float-layer? s))) #'e] [_ #f])))) - (when (not (null? extra-precision-subexprs)) + (when (and (not (null? extra-precision-subexprs)) + (subtypeof? this-syntax -InexactReal)) (log-missed-optimization "exact ops inside float expr" "This expression has a Float type, but the highlighted subexpression(s) use exact arithmetic. The extra precision of the exact arithmetic will be lost. Using Float types in these subexpression(s) may result in performance gains without significant precision loss." From 7bdfc1924a9bcde362eae78f5252ce126e5b43f2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 10 Oct 2012 09:23:12 -0600 Subject: [PATCH 691/746] raco setup: improve description of `--doc-pdf' Merge to v5.3.1 (cherry picked from commit a150140684931c97bbb7ed7d313750abcf54d69d) --- collects/setup/setup-cmdline.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/setup/setup-cmdline.rkt b/collects/setup/setup-cmdline.rkt index 0ebdfc84fe..98e677a242 100644 --- a/collects/setup/setup-cmdline.rkt +++ b/collects/setup/setup-cmdline.rkt @@ -77,7 +77,7 @@ (add-flags '((all-users #t)))] [("--mode") mode "Select a compilation mode" (add-flags `((compile-mode ,mode)))] - [("--doc-pdf") dir "Write doc PDF to

" + [("--doc-pdf") dir "Build doc PDFs, write to " (add-flags `((doc-pdf-dest ,dir)))] [("-l") => (lambda (flag . collections) (check-collections short-name collections) From 9323007c9714104868d2db264f213fc98224b5fe Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 11 Oct 2012 16:22:50 -0600 Subject: [PATCH 692/746] slideshow/pict repair Merge to v5.3.1 (cherry picked from commit a755479d59a188b39c5bf32c36296828e98899c7) --- collects/texpict/balloon.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/texpict/balloon.rkt b/collects/texpict/balloon.rkt index bd29b4d323..b4c246cf3e 100644 --- a/collects/texpict/balloon.rkt +++ b/collects/texpict/balloon.rkt @@ -153,7 +153,7 @@ (define pip-wrap-balloon (lambda (p corner dx dy [color balloon-color] [c-rad corner-size] #:factor [factor 1]) - (pin-balloon (wrap-balloon p corner dx dy color c-rad) (blank 0) 0 0 #:factor factor))) + (pin-balloon (wrap-balloon p corner dx dy color c-rad #:factor factor) (blank 0) 0 0))) (define (do-place-balloon flip-proc? balloon p to find-to) (let-values ([(x y) (if (and (number? to) From f4c1b3aceba68bd4f183e958152a9e937a35700f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 12 Oct 2012 09:02:07 -0400 Subject: [PATCH 693/746] make DrRacket's picture values convertible to PNG and PDF (cherry picked from commit 5d65cada2e010edd9b800857d66206b347134ed3) --- collects/drracket/private/pict-snip.rkt | 33 +++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/collects/drracket/private/pict-snip.rkt b/collects/drracket/private/pict-snip.rkt index 8816067088..4fb34f1e7e 100644 --- a/collects/drracket/private/pict-snip.rkt +++ b/collects/drracket/private/pict-snip.rkt @@ -3,15 +3,21 @@ racket/class racket/match racket/draw + file/convertible wxme (prefix-in r: racket/base)) (provide pict-snip% snip-class reader) +(define convertible<%> + (interface* () ([prop:convertible (lambda (v r d) + (send v convert r d))]) + convert)) + ;; this snip is created on the user's space, ;; but its callbacks are invoked on DrRacket's. (define pict-snip% - (class snip% + (class* snip% (convertible<%>) (init-field w h d a recorded-datum) (define/override (get-extent dc x y [wb #f] [hb #f] [descent #f] [space #f] [lspace #f] [rspace #f]) (set-box/f lspace 0) @@ -39,7 +45,30 @@ (send f put (bytes-length bytes) bytes)) (super-new) (inherit set-snipclass) - (set-snipclass snip-class))) + (set-snipclass snip-class) + + (define/public (convert r d) + (case r + [(png-bytes) + (define bm (make-bitmap w h)) + (define dc (send bm make-dc)) + (draw dc 0 0 0 0 w h 0 0 #f) + (define b (open-output-bytes)) + (send bm save-file b 'png) + (get-output-bytes b)] + [(pdf-bytes) + (define b (open-output-bytes)) + (define dc (new pdf-dc% + [interactive #f] + [width w] [height h] + [output b])) + (send dc start-doc "pict") + (send dc start-page) + (draw dc 0 0 0 0 w h 0 0 #f) + (send dc end-page) + (send dc end-doc) + (get-output-bytes b)] + [else d])))) (define (set-box/f b v) (when (box? b) (set-box! b v))) From b31aeb4c6dfde6e65a5a27a765b0a83b283cdf9d Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Sat, 13 Oct 2012 15:48:05 +0200 Subject: [PATCH 694/746] Synch German string constants with latest. (cherry picked from commit 25e5fc715c3e334a147fad6fbd82f0ad2339fa86) --- .../private/german-string-constants.rkt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/collects/string-constants/private/german-string-constants.rkt b/collects/string-constants/private/german-string-constants.rkt index f7239f68c5..d47462559c 100644 --- a/collects/string-constants/private/german-string-constants.rkt +++ b/collects/string-constants/private/german-string-constants.rkt @@ -138,19 +138,19 @@ (sc-f2-to-un/lock "f2 um zu (ent)blockieren") ;; the online check syntax status messages (mouse over the bottom right of drracket's window to see the messages during online expansion's various phases) - (online-expansion-running "Online-Expansion läuft") + (online-expansion-running "Spekulative Expansion läuft") (online-expansion-only-raw-text-files-supported "Nur reine Text-Dateien sind unterstützt") - (online-expansion-abnormal-termination "Online-Expansion unglücklich abgebrochen") - (online-expansion-finished-successfully "Online-Expansion erfolgreich abgeschlossen") + (online-expansion-abnormal-termination "Spekulative Expansion unglücklich abgebrochen") + (online-expansion-finished-successfully "Spekulative Expansion erfolgreich abgeschlossen") (jump-to-error "Zum Fehler springen") - (online-expansion-is-disabled "Online-Expansion ist deaktiviert") + (online-expansion-is-disabled "Spekulative Expansion ist deaktiviert") ;; these next two show up in the bar along the bottom of the drracket window - (online-expansion-pending "Online-Expansion läuft ...") - (online-expansion-finished "Online-Expansion fertig") ;; note: there may still be errors in this case + (online-expansion-pending "Spekulative Expansion läuft ...") + (online-expansion-finished "Spekulative Expansion fertig") ;; note: there may still be errors in this case ;; the online expansion preferences pane - (online-expansion "Online-Expansion") ;; title of prefs pane + (online-expansion "Spekulative Expansion") ;; title of prefs pane ; the different kinds of errors (online-expansion-show-read-errors-as "Reader-Fehler anzeigen") (online-expansion-show-variable-errors-as "Ungebundene Bezeichner anzeigen") From a46e0120a873f28ebbd33c4ad2db58c8004490df Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 13 Oct 2012 08:53:11 -0500 Subject: [PATCH 695/746] change "speculative" to "background" for the online check syntax messages (cherry picked from commit 42c5b287ff31ca24e4cc5f761a5baf51bf6979a4) --- collects/scribblings/drracket/keybindings.scrbl | 2 +- .../private/english-string-constants.rkt | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/collects/scribblings/drracket/keybindings.scrbl b/collects/scribblings/drracket/keybindings.scrbl index ccbd8b5d15..de0ac712f3 100644 --- a/collects/scribblings/drracket/keybindings.scrbl +++ b/collects/scribblings/drracket/keybindings.scrbl @@ -180,7 +180,7 @@ selected. @itemize[ @keybinding["f1"]{Search in the documentation for the words near the insertion point} @keybinding["f2"]{Reveal the blue box for the identifier at the insertion point (requires - online check syntax to be enabled, or normal check syntax to have been + background check syntax to be enabled, or normal check syntax to have been run).} ] diff --git a/collects/string-constants/private/english-string-constants.rkt b/collects/string-constants/private/english-string-constants.rkt index 076c10829c..e2ee195ec1 100644 --- a/collects/string-constants/private/english-string-constants.rkt +++ b/collects/string-constants/private/english-string-constants.rkt @@ -233,19 +233,19 @@ please adhere to these guidelines: (sc-f2-to-un/lock "f2 to (un)lock") ;; the online check syntax status messages (mouse over the bottom right of drracket's window to see the messages during online expansion's various phases) - (online-expansion-running "Speculative expansion running") + (online-expansion-running "Background expansion running") (online-expansion-only-raw-text-files-supported "Only pure text files supported") - (online-expansion-abnormal-termination "Speculative expansion terminated abnormally") - (online-expansion-finished-successfully "Speculative expansion finished successfully") + (online-expansion-abnormal-termination "Background expansion terminated abnormally") + (online-expansion-finished-successfully "Background expansion finished successfully") (jump-to-error "Jump to Error") - (online-expansion-is-disabled "Speculative expansion is disabled") + (online-expansion-is-disabled "Background expansion is disabled") ;; these next two show up in the bar along the bottom of the drracket window - (online-expansion-pending "Speculative expansion pending ...") - (online-expansion-finished "Speculative expansion finished") ;; note: there may still be errors in this case + (online-expansion-pending "Background expansion pending ...") + (online-expansion-finished "Background expansion finished") ;; note: there may still be errors in this case ;; the online expansion preferences pane - (online-expansion "Speculative expansion") ;; title of prefs pane + (online-expansion "Background expansion") ;; title of prefs pane ; the different kinds of errors (online-expansion-show-read-errors-as "Show read-level errors") (online-expansion-show-variable-errors-as "Show unbound identifier errors") From f63b0d262273a0baedd006df987014c5ee47d617 Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Sat, 13 Oct 2012 17:00:23 +0200 Subject: [PATCH 696/746] Synch German string constants with latest. (cherry picked from commit c8dc421ec3520aaa227e74189af51386d9abc735) --- .../private/german-string-constants.rkt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/collects/string-constants/private/german-string-constants.rkt b/collects/string-constants/private/german-string-constants.rkt index d47462559c..dc841094ec 100644 --- a/collects/string-constants/private/german-string-constants.rkt +++ b/collects/string-constants/private/german-string-constants.rkt @@ -138,19 +138,19 @@ (sc-f2-to-un/lock "f2 um zu (ent)blockieren") ;; the online check syntax status messages (mouse over the bottom right of drracket's window to see the messages during online expansion's various phases) - (online-expansion-running "Spekulative Expansion läuft") + (online-expansion-running "Hintergrund-Expansion läuft") (online-expansion-only-raw-text-files-supported "Nur reine Text-Dateien sind unterstützt") - (online-expansion-abnormal-termination "Spekulative Expansion unglücklich abgebrochen") - (online-expansion-finished-successfully "Spekulative Expansion erfolgreich abgeschlossen") + (online-expansion-abnormal-termination "Hintergrund-Expansion unglücklich abgebrochen") + (online-expansion-finished-successfully "Hintergrund-Expansion erfolgreich abgeschlossen") (jump-to-error "Zum Fehler springen") - (online-expansion-is-disabled "Spekulative Expansion ist deaktiviert") + (online-expansion-is-disabled "Hintergrund-Expansion ist deaktiviert") ;; these next two show up in the bar along the bottom of the drracket window - (online-expansion-pending "Spekulative Expansion läuft ...") - (online-expansion-finished "Spekulative Expansion fertig") ;; note: there may still be errors in this case + (online-expansion-pending "Hintergrund-Expansion läuft ...") + (online-expansion-finished "Hintergrund-Expansion fertig") ;; note: there may still be errors in this case ;; the online expansion preferences pane - (online-expansion "Spekulative Expansion") ;; title of prefs pane + (online-expansion "Hintergrund-Expansion") ;; title of prefs pane ; the different kinds of errors (online-expansion-show-read-errors-as "Reader-Fehler anzeigen") (online-expansion-show-variable-errors-as "Ungebundene Bezeichner anzeigen") From 513f85baa2051cd7428ac008e5b2d1e6858f52d6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 13 Oct 2012 05:28:37 -0400 Subject: [PATCH 697/746] repair for picture-to-bitmap conversion (cherry picked from commit 2b902d0eda628dbb5e63c5513c1ccdc27eeecde3) --- collects/drracket/private/pict-snip.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/drracket/private/pict-snip.rkt b/collects/drracket/private/pict-snip.rkt index 4fb34f1e7e..a85a1b3ee7 100644 --- a/collects/drracket/private/pict-snip.rkt +++ b/collects/drracket/private/pict-snip.rkt @@ -50,7 +50,8 @@ (define/public (convert r d) (case r [(png-bytes) - (define bm (make-bitmap w h)) + (define bm (make-bitmap (inexact->exact (ceiling w)) + (inexact->exact (ceiling h)))) (define dc (send bm make-dc)) (draw dc 0 0 0 0 w h 0 0 #f) (define b (open-output-bytes)) From 6c5714c0dd2221aea03de7f1d4893e5a86e506ca Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 16 Oct 2012 17:58:17 -0400 Subject: [PATCH 698/746] fix define-for-syntax within splicing-syntax-parameterize (cherry picked from commit 67d901ccc4c69e2b6ba3038d7ee61d4c23a9ee9d) --- collects/racket/splicing.rkt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/collects/racket/splicing.rkt b/collects/racket/splicing.rkt index 2168b49d7f..797acf05c1 100644 --- a/collects/racket/splicing.rkt +++ b/collects/racket/splicing.rkt @@ -190,7 +190,9 @@ (syntax-case body ( begin define-values define-syntaxes - define-for-syntaxes + begin-for-syntax + module + module* #%require #%provide ) [(begin expr ...) @@ -202,7 +204,9 @@ (letrec-syntaxes ([(sp-id) (syntax-local-value (quote-syntax temp-id))] ...) rhs)))] [(define-syntaxes . _) body] - [(define-for-syntaxes . _) body] + [(begin-for-syntax . _) body] + [(module . _) body] + [(module* . _) body] [(#%require . _) body] [(#%provide . _) body] [expr (syntax/loc body From d76bdd591937e719910cf6d200bf751acc96c803 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 17 Oct 2012 15:36:23 -0600 Subject: [PATCH 699/746] fix planet `raco exe' tests Merge ot v5.3.1 (cherry picked from commit bd146e2d8d2f9f8fdbe071c1943a665d3b17bfbe) --- collects/tests/racket/embed.rktl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/collects/tests/racket/embed.rktl b/collects/tests/racket/embed.rktl index 5c7b6ba662..47c5183ea7 100644 --- a/collects/tests/racket/embed.rktl +++ b/collects/tests/racket/embed.rktl @@ -473,9 +473,9 @@ "planet"))) (define (try-planet) - (system* planet "link" "racket-tester" "p1.plt" "1" "0" + (system* raco "planet" "link" "racket-tester" "p1.plt" "1" "0" (path->string (collection-path "tests" "racket" "embed-planet-1"))) - (system* planet "link" "racket-tester" "p2.plt" "2" "2" + (system* raco "planet" "link" "racket-tester" "p2.plt" "2" "2" (path->string (collection-path "tests" "racket" "embed-planet-2"))) (let ([go (lambda (path expected) @@ -508,8 +508,8 @@ (void)) - (system* planet "unlink" "racket-tester" "p1.plt" "1" "0") - (system* planet "unlink" "racket-tester" "p2.plt" "2" "2")) + (system* raco "planet" "unlink" "racket-tester" "p1.plt" "1" "0") + (system* raco "planet" "unlink" "racket-tester" "p2.plt" "2" "2")) ;; ---------------------------------------- From 6325cd0945f5c9a21eda96b99a77f6541db4e349 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 17 Oct 2012 16:14:29 -0600 Subject: [PATCH 700/746] fix `raco exe' for `module+' submodules Closes PR 13116 Merge to v5.3.1 (cherry picked from commit e1a6d2b07d263ababc89642ab78f6e17fce19be4) --- collects/compiler/embed-unit.rkt | 65 +++++++++++++++------------- collects/tests/racket/embed-me20.rkt | 7 +++ collects/tests/racket/embed.rktl | 8 ++++ 3 files changed, 50 insertions(+), 30 deletions(-) create mode 100644 collects/tests/racket/embed-me20.rkt diff --git a/collects/compiler/embed-unit.rkt b/collects/compiler/embed-unit.rkt index 3b1d118e62..c162ff3fcb 100644 --- a/collects/compiler/embed-unit.rkt +++ b/collects/compiler/embed-unit.rkt @@ -261,11 +261,11 @@ ;; Represent modules with lists starting with the filename, so we ;; can use assoc: (define (make-mod normal-file-path normal-module-path - code name prefix full-name relative-mappings + code name prefix full-name relative-mappings-box runtime-paths runtime-module-syms actual-file-path) (list normal-file-path normal-module-path code - name prefix full-name relative-mappings + name prefix full-name relative-mappings-box runtime-paths runtime-module-syms actual-file-path)) @@ -275,7 +275,7 @@ (define (mod-name m) (list-ref m 3)) (define (mod-prefix m) (list-ref m 4)) (define (mod-full-name m) (list-ref m 5)) - (define (mod-mappings m) (list-ref m 6)) + (define (mod-mappings m) (unbox (list-ref m 6))) (define (mod-runtime-paths m) (list-ref m 7)) (define (mod-runtime-module-syms m) (list-ref m 8)) (define (mod-actual-file m) (list-ref m 9)) @@ -420,7 +420,7 @@ (set-box! codes (cons (make-mod filename module-path code name prefix full-name - null null null + (box null) null null actual-filename) (unbox codes)))] [code @@ -527,7 +527,7 @@ (set-box! codes (cons (make-mod filename module-path #f #f #f #f - null null null + (box null) null null actual-filename) (unbox codes)))) ;; Build up relative module resolutions, relative to this one, @@ -538,34 +538,35 @@ (mod-full-name m) ;; must have been a cycle... (hash-ref working sub-filename))))] - [mappings (append - (map (lambda (sub-i sub-filename sub-path) - (and (not (and collects-dest - (is-lib-path? sub-path))) - (let-values ([(path base) (module-path-index-split sub-i)]) - (and base ; can be #f if path isn't relative - (begin - ;; Assert: base should refer to this module: - (let-values ([(path2 base2) (module-path-index-split base)]) - (when (or path2 base2) - (error 'embed "unexpected nested module path index"))) - (cons path (lookup-full-name sub-filename))))))) - all-file-imports sub-files sub-paths) - (map (lambda (m) - (define name (cadr (module-compiled-name m))) - (cons `(submod "." ,name) - (lookup-full-name - (collapse-module-path-index - (module-path-index-join `(submod "." ,name) #f) - filename)))) - (append pre-submods post-submods)))]) + [get-submod-mapping + (lambda (m) + (define name (cadr (module-compiled-name m))) + (cons `(submod "." ,name) + (lookup-full-name + (collapse-module-path-index + (module-path-index-join `(submod "." ,name) #f) + filename))))] + [mappings-box + (box (append + (filter (lambda (p) (and p (cdr p))) + (map (lambda (sub-i sub-filename sub-path) + (and (not (and collects-dest + (is-lib-path? sub-path))) + (let-values ([(path base) (module-path-index-split sub-i)]) + (and base ; can be #f if path isn't relative + (begin + ;; Assert: base should refer to this module: + (let-values ([(path2 base2) (module-path-index-split base)]) + (when (or path2 base2) + (error 'embed "unexpected nested module path index"))) + (cons path (lookup-full-name sub-filename))))))) + all-file-imports sub-files sub-paths)) + (map get-submod-mapping pre-submods)))]) ;; Record the module (set-box! codes (cons (make-mod filename module-path code name prefix full-name - (filter (lambda (p) - (and p (cdr p))) - mappings) + mappings-box runtime-paths ;; extract runtime-path module symbols: (let loop ([runtime-paths runtime-paths] @@ -581,7 +582,11 @@ actual-filename) (unbox codes))) ;; Add code for post submodules: - (for-each get-one-submodule-code post-submods)))))))] + (for-each get-one-submodule-code post-submods) + ;; Add post-submodule mappings: + (set-box! mappings-box + (append (unbox mappings-box) + (map get-submod-mapping post-submods)))))))))] [else (set-box! codes (cons (make-mod filename module-path code diff --git a/collects/tests/racket/embed-me20.rkt b/collects/tests/racket/embed-me20.rkt new file mode 100644 index 0000000000..d4b8fe1586 --- /dev/null +++ b/collects/tests/racket/embed-me20.rkt @@ -0,0 +1,7 @@ +#lang racket/base + +;; like "embed-me16.rkt" using `module+' +(module+ main + (with-output-to-file "stdout" + (lambda () (printf "This is 20.\n")) + #:exists 'append)) diff --git a/collects/tests/racket/embed.rktl b/collects/tests/racket/embed.rktl index 47c5183ea7..39da0cdd83 100644 --- a/collects/tests/racket/embed.rktl +++ b/collects/tests/racket/embed.rktl @@ -288,6 +288,14 @@ (path->string (build-path (collection-path "tests" "racket") "embed-me16.rkt"))) (try-exe (mk-dest mred?) "This is 16.\n" mred?) + ;; raco exe on a module with a `main' submodule+ + (system* raco + "exe" + "-o" (path->string (mk-dest mred?)) + (if mred? "--gui" "--") + (path->string (build-path (collection-path "tests" "racket") "embed-me20.rkt"))) + (try-exe (mk-dest mred?) "This is 20.\n" mred?) + ;;raco exe --launcher (system* raco "exe" From ccf3f9c1c59a68d6f8b47665cbf261a83736b468 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 17 Oct 2012 16:16:36 -0600 Subject: [PATCH 701/746] update change history for v5.3.1 Merge to v5.3.1 (cherry picked from commit 1d28b6c0f66f954df1351e5249822a57ab5f5214) --- doc/release-notes/racket/HISTORY.txt | 30 ++++++++++------------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index 5d45daece1..6b54437ba7 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,12 +1,4 @@ -Version 5.3.0.24 -Added PLTCOMPILEDROOTS and --compiled/-R command-line flag -Added reroot-path -Added #:break and #:final clauses to for forms -syntax/for-body: added -racket/set: added set-first and set-rest, sets are streams -racket/require-transformer: an import's module path can be syntax - -Version 5.3.0.23 +Version 5.3.1, October 2012 Changed make-log-receiver to accept a logger name as an event filter Addded define-logger @@ -14,23 +6,23 @@ Changed -W, -L, PLTSTDERR, and PLTSYSLOG to support log filters of the form " = ..." Changed log-error, etc., to support format mode Added racket/format, which is re-exported by racket - -Version 5.3.0.22 -Changed a thread's initial prompt to use the default handler - (instead of accepting and ignoring abort arguments) -ffi/unsafe: added cpointer-gcable? -racket/class: added dynamic-get-field and dynamic-set-field! - -Version 5.3.0.20 +Added #:break and #:final clauses to for forms Added exn:break:hang-up and exn:break:terminate, added extra argument to break-thread and place-break, and redirect SIGTERM and SIGHUP as breaks Add #:fill option to for/vector, for*/vector, for/flvector, for*/flvector, for/fxvector, and for*/fxvector - -Version 5.3.0.16 +Added PLTCOMPILEDROOTS and --compiled/-R command-line flag +Added reroot-path +Changed a thread's initial prompt to use the default handler + (instead of accepting and ignoring abort arguments) +ffi/unsafe: added cpointer-gcable? +racket/class: added dynamic-get-field and dynamic-set-field! +racket/set: added set-first and set-rest, sets are streams +racket/require-transformer: an import's module path can be syntax scribble/base: add items/c scribble/decode: add spliceof +syntax/for-body: added Version 5.3, August 2012 Added submodules, including module* From 3f8d12e55d1c955835ba59fa8712da77bf8cfb48 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 17 Oct 2012 16:18:29 -0600 Subject: [PATCH 702/746] update HISTORY for `{chaperone,impersonate}-prompt-tag' changes (cherry picked from commit 31d56e10afc633831bcfbf424be5a636346364b9) --- doc/release-notes/racket/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index 6b54437ba7..776ca6970a 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,3 +1,7 @@ +Version 5.3.1.1 +Added arguments to impersonate-prompt-tag and chaperone-prompt-tag + to support interposition on non-composable continuation results + Version 5.3.1, October 2012 Changed make-log-receiver to accept a logger name as an event filter From 2db4378e4e7d1e49fdab67da327969e1d3900eab Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Wed, 17 Oct 2012 09:55:43 -0400 Subject: [PATCH 703/746] fixed Adam Shaw's typo, eliminated the word match (cherry picked from commit b48d122dd7fa17c7e1a9bd613fedb014ec075eb7) --- collects/scribblings/htdp-langs/prim-ops.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/scribblings/htdp-langs/prim-ops.rkt b/collects/scribblings/htdp-langs/prim-ops.rkt index b58443cbfa..a85b47dfff 100644 --- a/collects/scribblings/htdp-langs/prim-ops.rkt +++ b/collects/scribblings/htdp-langs/prim-ops.rkt @@ -324,12 +324,12 @@ @defform*[#:id [check-error check-error-id] - [(check-error expression match-expression) + [(check-error expression expected-error-message) (#,check-error-elem expression)]]{ Checks that the @racket[expression] reports an error, where the error messages matches the - value of @racket[matchexpression], if it is present.} + value of @racket[expected-error-message], if it is present.} @defform*[#:id [check-member-of check-member-of-id] From 959fb114a02b4591683f4e67321104c8343fa4e1 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Wed, 17 Oct 2012 20:26:18 -0400 Subject: [PATCH 704/746] fix string-ith's error message; Closes PR 13197 (cherry picked from commit f733f149f554b9f1275464ab182126df129dcb88) --- collects/lang/private/teachprims.rkt | 6 +++--- collects/tests/htdp-lang/beg-adv.rktl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/collects/lang/private/teachprims.rkt b/collects/lang/private/teachprims.rkt index fd0c6abeac..3bad49ef0b 100644 --- a/collects/lang/private/teachprims.rkt +++ b/collects/lang/private/teachprims.rkt @@ -482,11 +482,11 @@ namespace. (define-teach beginner string-ith (lambda (s n) - (define f "exact integer in [0, length of the given string]") (cerr 'string-ith (string? s) "string" s "first") (cerr 'string-ith (and (number? n) (integer? n) (>= n 0)) NAT n "second") - (let ([l (string-length s)]) - (cerr 'string-ith (< n l) f n "second")) + (define l (string-length s)) + (define f (format "exact integer in [0, ~a) (i.e., less than the length of the given string)" l)) + (cerr 'string-ith (< n l) f n "second") (string (string-ref s n)))) ;; ----------------------------------------------------------------------------- diff --git a/collects/tests/htdp-lang/beg-adv.rktl b/collects/tests/htdp-lang/beg-adv.rktl index a3be217b03..1e50b78f51 100644 --- a/collects/tests/htdp-lang/beg-adv.rktl +++ b/collects/tests/htdp-lang/beg-adv.rktl @@ -321,7 +321,7 @@ (htdp-err/rt-test (string-ith "hell" 4) (exn-type-and-msg exn:fail:contract? - "string-ith: expected an exact integer in [0, length of the given string] for the second argument, but received 4")) + "string-ith: expected an exact integer in [0, 4) (i.e., less than the length of the given string) for the second argument, but received 4")) (htdp-err/rt-test (string-ith 10 4) (exn-type-and-msg exn:fail:contract? From 622641353c905a85f0b26b4f5306e4504296a260 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 17 Oct 2012 20:18:46 -0500 Subject: [PATCH 705/746] fix group-test merge to release branch, please (cherry picked from commit 975426f00c2886c8bd1d933d2f84706744027942) --- collects/tests/framework/group-test.rkt | 43 +++++++++++++------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/collects/tests/framework/group-test.rkt b/collects/tests/framework/group-test.rkt index 1956729d02..78605b96c7 100644 --- a/collects/tests/framework/group-test.rkt +++ b/collects/tests/framework/group-test.rkt @@ -100,19 +100,19 @@ 'windows-menu (lambda (x) (equal? x (append windows-menu-prefix (list "first" "test")))) - (lambda () + (λ () (queue-sexp-to-mred '(let ([frame (make-object frame:basic% "test")]) (send frame show #t))) (wait-for-frame "test") (queue-sexp-to-mred - '(begin0 (map (lambda (x) - (and (is-a? x labelled-menu-item<%>) (send x get-label))) - (send (car* (send (send (get-top-level-focus-window) - get-menu-bar) - get-items)) - get-items)) - (send (get-top-level-focus-window) close))))) + '(let ([mb (send (get-top-level-focus-window) get-menu-bar)]) + (send mb on-demand) + (define labels + (for/list ([x (send (car* (send mb get-items)) get-items)]) + (and (is-a? x labelled-menu-item<%>) (send x get-label)))) + (send (get-top-level-focus-window) close) + labels)))) (test 'windows-menu-unshown @@ -125,13 +125,13 @@ (send frame1 show #t))) (wait-for-frame "test") (queue-sexp-to-mred - '(begin0 (map (lambda (x) - (and (is-a? x labelled-menu-item<%>) (send x get-label))) - (send (car* (send (send (get-top-level-focus-window) - get-menu-bar) - get-items)) - get-items)) - (send (get-top-level-focus-window) close))))) + '(let ([mb (send (get-top-level-focus-window) get-menu-bar)]) + (send mb on-demand) + (define items + (for/list ([x (send (car* (send mb get-items)) get-items)]) + (and (is-a? x labelled-menu-item<%>) (send x get-label)))) + (send (get-top-level-focus-window) close) + items)))) (test 'windows-menu-sorted1 @@ -148,10 +148,11 @@ (wait-for-frame "bbb") (queue-sexp-to-mred `(let ([frames (send (group:get-the-frame-group) get-frames)]) + (define mb (send (car* frames) get-menu-bar)) + (send mb on-demand) (begin0 (map (lambda (x) (and (is-a? x labelled-menu-item<%>) (send x get-label))) - (send (car* (send (send (car* frames) get-menu-bar) - get-items)) + (send (car* (send mb get-items)) get-items)) (for-each (lambda (x) (unless (equal? (send x get-label) "first") @@ -173,13 +174,13 @@ (wait-for-frame "aaa") (queue-sexp-to-mred `(let ([frames (send (group:get-the-frame-group) get-frames)]) + (define mb (send (car* frames) get-menu-bar)) + (send mb on-demand) (begin0 (map (lambda (x) (and (is-a? x labelled-menu-item<%>) (send x get-label))) - (send (car* (send (send (car* frames) get-menu-bar) - get-items)) + (send (car* (send mb get-items)) get-items)) (for-each (lambda (x) (unless (equal? (send x get-label) "first") (send x close))) - frames)))))) - ) + frames))))))) From a13aedacc6a2e93257a504b4f910b7110b3ce158 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 17 Oct 2012 20:45:25 -0500 Subject: [PATCH 706/746] drracket history updates please include in release (cherry picked from commit 0660227d8a426957b4bc0267453fb4442463c6eb) --- doc/release-notes/drracket/HISTORY.txt | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/doc/release-notes/drracket/HISTORY.txt b/doc/release-notes/drracket/HISTORY.txt index f515fdd98a..11b464df3c 100644 --- a/doc/release-notes/drracket/HISTORY.txt +++ b/doc/release-notes/drracket/HISTORY.txt @@ -2,21 +2,25 @@ Version 5.3.1 ------------------------------ - . Enable online check syntax by default (it has been - available in the last two releases, but was disabled - by default) + . Enable online check syntax by default (it has been + available in the last two releases, but was disabled by + default) - . Check Syntax now shows the blue boxes from the + . Check Syntax now shows the blue boxes from the documentation in the definitions window - . Change the "Variables" pane of the debugger so that it does not do - word-wrapping (this avoids some performance problems when very - large values are rendered there) + . Add a spell checker for string constants; use + -shift-c to turn it off or on - . Adjust the Install .plt File dialog so that it cleans up after the - end of an installation (specifically, it shuts down the custodian - that was running the installation process), which also causes the - Abort button to be disabled. + . Change the "Variables" pane of the debugger so that it + does not do word-wrapping (this avoids some performance + problems when very large values are rendered there) + + . Adjust the Install .plt File dialog so that it cleans up + after the end of an installation (specifically, it shuts + down the custodian that was running the installation + process), which also causes the Abort button to be + disabled. ------------------------------ Version 5.3 From 6167b016e4f49fc135cf6c5b926c341c5910987e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 17 Oct 2012 20:46:16 -0500 Subject: [PATCH 707/746] redex history release notes merge to release please (cherry picked from commit 8827f4b6b51a702ad9ca395c345c2a54f456a931) --- doc/release-notes/redex/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes/redex/HISTORY.txt b/doc/release-notes/redex/HISTORY.txt index 69fc6b919c..7bac3ffbee 100644 --- a/doc/release-notes/redex/HISTORY.txt +++ b/doc/release-notes/redex/HISTORY.txt @@ -6,6 +6,10 @@ v5.3.1 * added judgment-form-cases + * adjust define-judgment-form typesetting so that it uses + the line breaks in a premise to determine how to line + break the typeset version + v5.3 * added the amb tutorial. From 2905090f583431303138d4e47177ab02088ccd35 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 18 Oct 2012 10:00:53 -0600 Subject: [PATCH 708/746] racket/draw: fix problems with monochrome PNGs Merge to v5.3.1 (cherry picked from commit 274d0045464b80116fa83faef4cc21e87f651a7c) --- collects/racket/draw/private/bitmap.rkt | 8 ++--- collects/racket/draw/unsafe/png.rkt | 9 +++--- collects/tests/gracket/dc.rktl | 41 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/collects/racket/draw/private/bitmap.rkt b/collects/racket/draw/private/bitmap.rkt index 10deb3dc7d..77be9adddb 100644 --- a/collects/racket/draw/private/bitmap.rkt +++ b/collects/racket/draw/private/bitmap.rkt @@ -231,7 +231,7 @@ (cairo_image_surface_get_width s) (cairo_image_surface_get_height s) b&w? - alpha? + (and alpha? (not b&w?)) s mask-bm) (values #f 0 0 #f #f #f #f))))] @@ -546,9 +546,9 @@ (let ([src (+ (* j row-width) (* (* bi 8) 4))]) (for/fold ([v 0]) ([k (in-range 8)]) (if ((+ (* 8 bi) k) . < . width) - (if (zero? (bytes-ref data (+ src (* 4 k)))) - v - (bitwise-ior v (unsafe-fxrshift 128 k))) + (if (zero? (bytes-ref data (+ src 3 (* 4 k)))) + (bitwise-ior v (unsafe-fxrshift 128 k)) + v) v))))))) (let ([w (create-png-writer out width height #t #f)]) (write-png w rows) diff --git a/collects/racket/draw/unsafe/png.rkt b/collects/racket/draw/unsafe/png.rkt index b8cb0599f1..a39b92ecab 100644 --- a/collects/racket/draw/unsafe/png.rkt +++ b/collects/racket/draw/unsafe/png.rkt @@ -220,12 +220,13 @@ interlace-type compression-type filter-type) (png_get_IHDR png info)]) (let* ([tRNS? (positive? (png_get_valid png info PNG_INFO_tRNS))] - [alpha? (and keep-alpha? - (or tRNS? - (positive? (bitwise-ior color-type PNG_COLOR_MASK_ALPHA))))] [b&w? (and (= depth 1) (= color-type PNG_COLOR_TYPE_GRAY) - (not tRNS?))]) + (not tRNS?))] + [alpha? (and keep-alpha? + (not b&w?) + (or tRNS? + (positive? (bitwise-ior color-type PNG_COLOR_MASK_ALPHA))))]) (unless b&w? ;; Normalize formal of returned rows: (when (= color-type PNG_COLOR_TYPE_PALETTE) diff --git a/collects/tests/gracket/dc.rktl b/collects/tests/gracket/dc.rktl index fde2dc637b..adb61ea8d8 100644 --- a/collects/tests/gracket/dc.rktl +++ b/collects/tests/gracket/dc.rktl @@ -623,6 +623,47 @@ (let ([bm (make-object bitmap% 1 1)]) (test #t 'load-file (send bm load-file (collection-file-path "sk.jpg" "icons")))) +;; ---------------------------------------- +;; Check save & load of monochrome PNG: + +(let () + (define N 5) + + (define bm (make-object bitmap% N N #t #f)) + (define dc (make-object bitmap-dc% bm)) + + (send dc draw-rectangle 2 2 (- N 2) (- N 2)) + + (define-values (i o) (make-pipe)) + (send bm save-file o 'png) + (close-output-port o) + + (define bm2 (make-object bitmap% 10 10)) + (send bm2 load-file i 'png) + + (define-values (i2 o2) (make-pipe)) + (send bm save-file o2 'png) + (close-output-port o2) + + (define bm3 (read-bitmap i2)) + + (define s1 (make-bytes (* N N 4))) + (define s2 (make-bytes (* N N 4))) + (define s3 (make-bytes (* N N 4))) + + (send bm get-argb-pixels 0 0 N N s1) + (send bm2 get-argb-pixels 0 0 N N s2) + (send bm3 get-argb-pixels 0 0 N N s3) + + (test #t 'same (equal? s1 s2)) + (test #t 'same (equal? s1 s3)) + (test 1 'mono (send bm2 get-depth)) + (test 1 'mono (send bm3 get-depth)) + (test #f 'b&w (send bm2 is-color?)) + (test #f 'b&w (send bm3 is-color?)) + (test #f 'no-alpha (send bm2 has-alpha-channel?)) + (test #f 'no-alpha (send bm3 has-alpha-channel?))) + ;; ---------------------------------------- (report-errs) From fa6fb56192f3f8807b1f1334aa0ff4cbd1a8167d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 18 Oct 2012 11:02:06 -0600 Subject: [PATCH 709/746] fix check for constructor of struct setter of immutable field Merge to v5.3.1 (cherry picked from commit b912d0f0590bed9a007a732fde6a4679c08c12d1) --- src/racket/src/struct.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/racket/src/struct.c b/src/racket/src/struct.c index fa8820983c..bfa0c73ffd 100644 --- a/src/racket/src/struct.c +++ b/src/racket/src/struct.c @@ -3828,10 +3828,18 @@ make_struct_proc(Scheme_Struct_Type *struct_type, 2 + need_pos, 2 + need_pos, 0); if (need_pos) flags |= SCHEME_PRIM_STRUCT_TYPE_INDEXLESS_SETTER; - else if (struct_type->immutables && struct_type->immutables[field_num]) - flags |= SCHEME_PRIM_STRUCT_TYPE_BROKEN_INDEXED_SETTER; - else - flags |= SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER; + else { + flags |= SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER; + + if (struct_type->immutables) { + if (struct_type->name_pos) + field_num -= struct_type->parent_types[struct_type->name_pos - 1]->num_slots; + if (struct_type->immutables[field_num]) { + flags -= SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER; + flags |= SCHEME_PRIM_STRUCT_TYPE_BROKEN_INDEXED_SETTER; + } + } + } /* See note above: if (need_pos) struct_type->mutator = p; */ } From dbe955b30e7145fa057512905447ad34bfad17a5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 18 Oct 2012 11:58:59 -0600 Subject: [PATCH 710/746] accomodate OpenBSD linking of libssl Merge to v5.3.1 (cherry picked from commit be538b4f690c229a7a1b9612028db0eecd1de7ac) --- collects/openssl/libcrypto.rkt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/collects/openssl/libcrypto.rkt b/collects/openssl/libcrypto.rkt index 438abe8eca..32e09b72ef 100644 --- a/collects/openssl/libcrypto.rkt +++ b/collects/openssl/libcrypto.rkt @@ -19,4 +19,9 @@ (with-handlers ([exn:fail? (lambda (x) (set! libcrypto-load-fail-reason (exn-message x)) #f)]) - (ffi-lib libcrypto-so '("" "1.0.0" "1.0" "0.9.8b" "0.9.8" "0.9.7")))) + (ffi-lib libcrypto-so '("" "1.0.0" "1.0" "0.9.8b" "0.9.8" "0.9.7") + ;; On OpenBSD, libssl is linked in a way that requires libcrypto + ;; to be opened as global: + #:global? (member (path->bytes (system-library-subpath #f)) + '(#"i386-openbsd" + #"x86_64-openbsd"))))) From 5f6e5924a5aa8ed8404a5fae902c5391fe66ebfa Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 18 Oct 2012 21:13:52 -0500 Subject: [PATCH 711/746] adjust the teaching languages interactions with drracket so they put the 'source' field into the syntax objects that they create (at the very top) this allows the debugger to connect the syntax objects to the file that's open in drracket (the way this worked changed a while back, but I didn't check the teaching languages to see if the debugger was supposed to work there) closes PR 13159 please merge to the release branch (cherry picked from commit 3ba54a2a3eded1f081769f21f8f6560ae9d98f3f) --- collects/lang/run-teaching-program.rkt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/collects/lang/run-teaching-program.rkt b/collects/lang/run-teaching-program.rkt index 97419e9dde..58f77bcf9f 100644 --- a/collects/lang/run-teaching-program.rkt +++ b/collects/lang/run-teaching-program.rkt @@ -27,7 +27,6 @@ ;; the user has added. Also, any 'provide' expressions are stripped out. (define (expand-teaching-program port reader language-module teachpacks [module-name '#%htdp] [enable-testing? #t]) - (define state 'init) ;; state : 'init => 'require => 'done-or-exn @@ -67,7 +66,8 @@ #`(define #,(datum->syntax #f 'test~object) (namespace-variable-value 'test~object)) 'test-call #t))) '()) - ,@body-exps)))))] + ,@body-exps) + (vector (object-name port) #f #f #f #f)))))] [(require) (set! state 'done-or-exn) (stepper-skip @@ -121,9 +121,10 @@ (with-syntax ([(rewritten-bodies ...) (filter not-provide? (syntax->list (syntax (bodies ...))))]) - #`(module name lang + (syntax/loc stx + (module name lang (#%plain-module-begin - rewritten-bodies ...)))] + rewritten-bodies ...))))] [else (raise-syntax-error 'htdp-languages "internal error .1")])) From 68444d5ce95bd6366c9852c5dde22d9dcd32e0ab Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 19 Oct 2012 05:15:56 -0400 Subject: [PATCH 712/746] Name cleanup in mailmap. (cherry picked from commit 61fe1ed5ee168e3efddc479b638614a10efb1138) --- .mailmap | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.mailmap b/.mailmap index e11a64ac9d..485fa108bd 100644 --- a/.mailmap +++ b/.mailmap @@ -1,3 +1,4 @@ +# Core racket-lang.org people Eli Barzilay Eli Barzilay Kevin Tew @@ -20,5 +21,17 @@ Asumu Takikawa Asumu Takikawa Guillaume Marceau Danny Yoo +Danny Yoo Philippe Meunier David Van Horn + +# Additional people +Eric Dobson +Gregory Cooper +Gregory Cooper +J. Ian Johnson +J. Ian Johnson +Michael Wilber +Rodolfo Carvalho +Steven Jaconette +Marc Burns Marc Burns From e6dffa7a3810ef5cfebe3ad3aada327ca89f10b8 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 19 Oct 2012 05:16:23 -0400 Subject: [PATCH 713/746] No more "planet" executable. (cherry picked from commit a03b636936d71c7766dae34be4a70ff88ec63d00) --- collects/meta/build/unix-installer/test-installer | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/collects/meta/build/unix-installer/test-installer b/collects/meta/build/unix-installer/test-installer index 4f753167d9..3d5233c0ef 100755 --- a/collects/meta/build/unix-installer/test-installer +++ b/collects/meta/build/unix-installer/test-installer @@ -171,7 +171,7 @@ exec racket "$0" "$@" (default: skip links) > @i{.} Installing links in "@|testdir|/bin"... drracket, gracket skipped (non-link exists), gracket-text, mred, @; - mred-text, mzc, mzpp, mzscheme, mztext, pdf-slatex, planet, plt-games, @; + mred-text, mzc, mzpp, mzscheme, mztext, pdf-slatex, plt-games, @; plt-help, plt-r5rs, plt-r6rs, plt-web-server, racket, raco, scribble, @; setup-plt, slatex, slideshow, swindle done. @@ -184,9 +184,9 @@ exec racket "$0" "$@" README, bin/, collects/, doc/, include/, lib/, man/ sh> @i{LS bin} @s|{drracket@, gracket, gracket-text@, mred@, mred-text@, mzc@, mzpp@, - mzscheme@, mztext@, pdf-slatex@, planet@, plt-games@, plt-help@, - plt-r5rs@, plt-r6rs@, plt-web-server@, racket@, raco@, scribble@, - setup-plt@, slatex@, slideshow@, swindle@}| + mzscheme@, mztext@, pdf-slatex@, plt-games@, plt-help@, plt-r5rs@, + plt-r6rs@, plt-web-server@, racket@, raco@, scribble@, setup-plt@, + slatex@, slideshow@, swindle@}| sh> @i{LS -l bin/ra*} lrwxrwxrwx. @... bin/racket -> @|testdir|/R/bin/racket* lrwxrwxrwx. @... bin/raco -> @|testdir|/R/bin/raco* @@ -304,9 +304,9 @@ exec racket "$0" "$@" bin/, include/, lib/, share/ sh> @i{LS bin} drracket*, gracket*, gracket-text*, mred*, mred-text*, mzc*, mzpp*, - mzscheme*, mztext*, pdf-slatex*, planet*, plt-games*, plt-help*, - plt-r5rs*, plt-r6rs*, plt-web-server*, racket*, racket-uninstall*, - raco*, scribble*, setup-plt*, slatex*, slideshow*, swindle* + mzscheme*, mztext*, pdf-slatex*, plt-games*, plt-help*, plt-r5rs*, + plt-r6rs*, plt-web-server*, racket*, racket-uninstall*, raco*, + scribble*, setup-plt*, slatex*, slideshow*, swindle* sh> @i{LS include && LS lib && LS share} racket@|N|/ racket@|N|/ From 6c0f0dfeb23149a5529d7d29434c24fd4d5962db Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 19 Oct 2012 05:17:48 -0400 Subject: [PATCH 714/746] Change checksums for -h changes. Also add completion for the new -R option. (cherry picked from commit bc29e6ed2a1dc91cb63d9ca8bac3a0faccf81512) --- collects/meta/contrib/completion/racket-completion.zsh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/collects/meta/contrib/completion/racket-completion.zsh b/collects/meta/contrib/completion/racket-completion.zsh index 06088a55ea..79772d0e0c 100644 --- a/collects/meta/contrib/completion/racket-completion.zsh +++ b/collects/meta/contrib/completion/racket-completion.zsh @@ -115,7 +115,7 @@ _racket_self_test() { ############################################################################### -_racket_self_test 'racket:1580018499:grep -v "Welcome to Racket"' +_racket_self_test 'racket:3785877773:grep -v "Welcome to Racket"' RACKET_COMMON=( -C -s -w -S : '(- : *)'{-h,--help}'[Display help]' ) RACKET_ARGS=( "$RACKET_COMMON[@]" ) @@ -149,6 +149,7 @@ RACKET_ARGS+=( '(-X --collects)'{-X,--collects}'+[Main collects dir ("" disables all)]:directory:_files -/' '*'{-S,--search}'+[More collects dir (after main)]:directory:_files -/' '(-A --addon)'{-A,--addon}'+[Addon directory]:directory:_files -/' + '(-R --compiled)'{-A,--addon}'+[Set compiled-file search roots to directory]:directory:_files -/' '(-C --links)'{-C,--links}'+[User-specific collection links file]:file:_files' '(-U --no-user-path)'{-U,--no-user-path}'[Ignore user-specific collects, etc.]' '(-N --name)'{-N,--name}'+[Sets (find-system-path '"'"'run-file)]:file:_files' @@ -205,7 +206,7 @@ _raco_cmd_docs() { _racket_do_state } -_racket_self_test 'raco setup:1426826849:tail -n +2' # full path for this one +_racket_self_test 'raco setup:2092236815:tail -n +2' # full path for this one _raco_cmd_setup() { _arguments "$RACKET_COMMON[@]" \ '(-c --clean)'{-c,--clean}'[Delete existing compiled files; implies -nxi]' \ From 47ca55e68a0bc5639857c0522a435b5bf6738855 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 19 Oct 2012 06:30:11 -0400 Subject: [PATCH 715/746] One more name. (cherry picked from commit 6b1f423c983bb953f6c4b4f1e8fa15699705cdd1) --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 485fa108bd..ac4210bdd8 100644 --- a/.mailmap +++ b/.mailmap @@ -34,4 +34,5 @@ J. Ian Johnson Michael Wilber Rodolfo Carvalho Steven Jaconette +Tim Brown Marc Burns Marc Burns From 76cad3ceddf5178bc37eecb39ab8140a6917ee5d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 20 Oct 2012 09:34:37 -0600 Subject: [PATCH 716/746] fix mismanagement of temporary print buffer Closes PR 13199 Merge to v5.3.1 (cherry picked from commit 70fee17ef9cde98e868ddb67f91706d64c28c0f9) --- src/racket/src/print.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/racket/src/print.c b/src/racket/src/print.c index 252d5085e8..1d772dbdc4 100644 --- a/src/racket/src/print.c +++ b/src/racket/src/print.c @@ -124,7 +124,7 @@ static void print_vector(Scheme_Object *vec, int notdisplay, int compact, static void print_char(Scheme_Object *chobj, int notdisplay, PrintParams *pp); static char *print_to_string(Scheme_Object *obj, intptr_t * volatile len, int write, Scheme_Object *port, intptr_t maxl, - Scheme_Object *qq_depth); + Scheme_Object *qq_depth, int *_release_to_quick); static void custom_write_struct(Scheme_Object *s, Scheme_Hash_Table *ht, Scheme_Marshal_Tables *mt, @@ -384,7 +384,7 @@ static void *print_to_string_k(void) p->ku.k.p2 = NULL; p->ku.k.p3 = NULL; - return (void *)print_to_string(obj, len, iswrite, NULL, maxl, qq_depth); + return (void *)print_to_string(obj, len, iswrite, NULL, maxl, qq_depth, NULL); } char *scheme_write_to_string_w_max(Scheme_Object *obj, intptr_t *len, intptr_t maxl) @@ -956,7 +956,7 @@ static char * print_to_string(Scheme_Object *obj, intptr_t * volatile len, int write, Scheme_Object *port, intptr_t maxl, - Scheme_Object *qq_depth) + Scheme_Object *qq_depth, int *_release_to_quick) { Scheme_Hash_Table *ht; Scheme_Hash_Table *uq_ht; @@ -1111,8 +1111,14 @@ print_to_string(Scheme_Object *obj, params.inspector = NULL; - if (port && !quick_print_buffer) - quick_print_buffer = ca; + if (_release_to_quick) { + *_release_to_quick = 0; + if (params.print_buffer != ca) { + if (!quick_print_buffer) + quick_print_buffer = ca; + } else + *_release_to_quick = 1; + } return params.print_buffer; } @@ -1124,6 +1130,7 @@ print_to_port(char *name, Scheme_Object *obj, Scheme_Object *port, int notdispla Scheme_Output_Port *op; char *str; intptr_t len; + int rel; op = scheme_output_port_record(port); if (op->closed) @@ -1131,9 +1138,12 @@ print_to_port(char *name, Scheme_Object *obj, Scheme_Object *port, int notdispla " port: %V", name, port); - str = print_to_string(obj, &len, notdisplay, port, maxl, qq_depth); + str = print_to_string(obj, &len, notdisplay, port, maxl, qq_depth, &rel); scheme_write_byte_string(str, len, port); + + if (rel && !quick_print_buffer) + quick_print_buffer = str; } static void print_this_string(PrintParams *pp, const char *str, int offset, int autolen) @@ -2850,10 +2860,13 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht, if (pp->print_syntax) { intptr_t slen; char *str; + int rel; print_utf8_string(pp, " ", 0, 1); str = print_to_string(scheme_syntax_to_datum((Scheme_Object *)stx, 0, NULL), - &slen, 1, NULL, pp->print_syntax, NULL); + &slen, 1, NULL, pp->print_syntax, NULL, &rel); print_utf8_string(pp, str, 0, slen); + if (rel && !quick_print_buffer) + quick_print_buffer = str; } print_utf8_string(pp, ">", 0, 1); } else { From d16bc258218a18ee66a446e63239b0575557622c Mon Sep 17 00:00:00 2001 From: Stephen Bloch Date: Sat, 20 Oct 2012 13:31:00 -0400 Subject: [PATCH 717/746] Changed "right" error messages to match new actual error messages. (cherry picked from commit 71a59cf653761c6134bee4a6c6229492bff738fa) --- .../tests/tiles-error-tests.rkt | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/collects/picturing-programs/tests/tiles-error-tests.rkt b/collects/picturing-programs/tests/tiles-error-tests.rkt index f5f98274ac..a488f15014 100644 --- a/collects/picturing-programs/tests/tiles-error-tests.rkt +++ b/collects/picturing-programs/tests/tiles-error-tests.rkt @@ -4,34 +4,34 @@ (require picturing-programs) (check-error (reflect-horiz 17) - "reflect-horiz: expected as first argument, given: 17") + "reflect-horiz: expected as first argument, given 17") (check-error (reflect-vert "hello") - "reflect-vert: expected as first argument, given: \"hello\"") + "reflect-vert: expected as first argument, given \"hello\"") (check-error (reflect-main-diag true) - "reflect-main-diag: expected as first argument, given: true") + "reflect-main-diag: expected as first argument, given true") (check-error (reflect-other-diag false) - "reflect-other-diag: expected as first argument, given: false") + "reflect-other-diag: expected as first argument, given false") (check-error (flip-main 'blue) - "flip-main: expected as first argument, given: 'blue") + "flip-main: expected as first argument, given 'blue") (check-error (flip-other "snark") - "flip-other: expected as first argument, given: \"snark\"") + "flip-other: expected as first argument, given \"snark\"") (check-error (crop-left pic:hacker 50) - "crop-left: expected as second argument, given: 50") + "crop-left: expected as second argument, given 50") (check-error (crop-right pic:bloch 100) - "crop-right: expected as second argument, given: 100") + "crop-right: expected as second argument, given 100") (check-error (crop-top pic:book 56) - "crop-top: expected as second argument, given: 56") + "crop-top: expected as second argument, given 56") (check-error (crop-bottom pic:hacker 56) - "crop-bottom: expected as second argument, given: 56") + "crop-bottom: expected as second argument, given 56") (check-error (crop-left pic:hacker -3) - "crop-left: expected as second argument, given: -3") + "crop-left: expected as second argument, given -3") (check-error (crop-top pic:book 3.2) - "crop-top: expected as second argument, given: 3.2") + "crop-top: expected as second argument, given 3.2") (check-error (crop-bottom pic:book pic:book) - "crop-bottom: expected as second argument, given: #") + "crop-bottom: expected as second argument, given #") (check-error (rotate-cw 17) - "rotate-cw: expected as first argument, given: 17") + "rotate-cw: expected as first argument, given 17") (check-error (rotate-ccw true) - "rotate-ccw: expected as first argument, given: true") + "rotate-ccw: expected as first argument, given true") (check-error (rotate-180 "goodbye") - "rotate-180: expected as first argument, given: \"goodbye\"") + "rotate-180: expected as first argument, given \"goodbye\"") From ee0da81dc0d8598ea90c2bae61041f196ab22d26 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 21 Oct 2012 07:43:54 -0600 Subject: [PATCH 718/746] ffi/unsafe: defend against some finalization bugs Turn use of a finalized ffi callout into a reported error, instead of a crash. Clarify the existence of the finalizer in the docs. Fix error logging of the finalizer thread. Merge to v5.3.1 (cherry picked from commit 9708a01a0aaa1ff9e639494596c34ef89d00ff29) --- collects/ffi/unsafe.rkt | 1 + collects/scribblings/foreign/types.scrbl | 5 ++++ collects/tests/racket/ffi-call-final.rkt | 32 ++++++++++++++++++++++++ src/foreign/foreign.c | 12 +++++++-- src/foreign/foreign.rktc | 12 +++++++-- 5 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 collects/tests/racket/ffi-call-final.rkt diff --git a/collects/ffi/unsafe.rkt b/collects/ffi/unsafe.rkt index 43a6b225ae..37ffc7c12b 100644 --- a/collects/ffi/unsafe.rkt +++ b/collects/ffi/unsafe.rkt @@ -1702,6 +1702,7 @@ (cweh (lambda (exn) (log-message logger + 'error (if (exn? exn) (exn-message exn) (format "~s" exn)) diff --git a/collects/scribblings/foreign/types.scrbl b/collects/scribblings/foreign/types.scrbl index 1ea8ebdaea..a13870cce1 100644 --- a/collects/scribblings/foreign/types.scrbl +++ b/collects/scribblings/foreign/types.scrbl @@ -485,6 +485,11 @@ For @tech{callouts} to foreign functions with the generated type: that values managed by the Racket garbage collector might be moved in memory by the garbage collector.} + @item{A @tech{callout} object is finalized internally. Beware + of trying to use a @tech{callout} object that is reachable + only from a finalized object, since the two objects + might be finalized in either order.} + ] For @tech{callbacks} to Racket functions with the generated type: diff --git a/collects/tests/racket/ffi-call-final.rkt b/collects/tests/racket/ffi-call-final.rkt new file mode 100644 index 0000000000..4993ee27f8 --- /dev/null +++ b/collects/tests/racket/ffi-call-final.rkt @@ -0,0 +1,32 @@ +#lang racket/base + +;; Check for a good effort at error reporting on an attempt to +;; use a foreign function that is finalized already. + +(define src + '(module m racket/base + (require ffi/unsafe) + (for ([i 10]) + (for ([i 10]) + (define m (get-ffi-obj 'fabs #f (_fun _double -> _double))) + ;; Since `m' is accessible only via the finalized value, it + ;; can be finalized before `(list m)': + (register-finalizer (list m) (lambda (p) ((car p) 10.0)))) + (collect-garbage)))) + +(define l (make-logger)) +(define r (make-log-receiver l 'error)) + +(parameterize ([current-namespace (make-base-namespace)] + [current-logger l]) + (eval src) + (namespace-require ''m)) + +;; Print logged errors, of which there are likely to be +;; some (although it's not guaranteed) if the finalizer +;; thread is logging correctly: +(let loop () + (define m (sync/timeout 0 r)) + (when m + (printf "~s\n" m) + (loop))) diff --git a/src/foreign/foreign.c b/src/foreign/foreign.c index d55c77d98d..ba085986ec 100644 --- a/src/foreign/foreign.c +++ b/src/foreign/foreign.c @@ -3055,7 +3055,7 @@ Scheme_Object *ffi_do_call(void *data, int argc, Scheme_Object *argv[]) #ifdef MZ_USE_PLACES int orig_place = SCHEME_TRUEP(SCHEME_VEC_ELS(data)[7]); #endif - int nargs = cif->nargs; + int nargs /* = cif->nargs, after checking cif */; /* When the foreign function is called, we need an array (ivals) of nargs * ForeignAny objects to store the actual C values that are created, and we * need another array (avalues) for the pointers to these values (this is @@ -3082,6 +3082,13 @@ Scheme_Object *ffi_do_call(void *data, int argc, Scheme_Object *argv[]) if (orig_place && (scheme_current_place_id == 0)) orig_place = 0; #endif + if (!cif) { + scheme_signal_error("ffi-call: foreign-function reference was already finalized%s%s", + name ? "\n name: " : "", + name ? name : ""); + return NULL; + } + nargs = cif->nargs; if ((nargs <= MAX_QUICK_ARGS)) { ivals = stack_ivals; avalues = stack_avalues; @@ -3151,8 +3158,9 @@ Scheme_Object *ffi_do_call(void *data, int argc, Scheme_Object *argv[]) } /* see below */ -void free_fficall_data(void *ignored, void *p) +void free_fficall_data(void *data, void *p) { + SCHEME_VEC_ELS(data)[4] = NULL; free(((ffi_cif*)p)->arg_types); free(p); } diff --git a/src/foreign/foreign.rktc b/src/foreign/foreign.rktc index 702db57354..e70e2a423c 100755 --- a/src/foreign/foreign.rktc +++ b/src/foreign/foreign.rktc @@ -2411,7 +2411,7 @@ Scheme_Object *ffi_do_call(void *data, int argc, Scheme_Object *argv[]) #ifdef MZ_USE_PLACES int orig_place = SCHEME_TRUEP(SCHEME_VEC_ELS(data)[7]); #endif - int nargs = cif->nargs; + int nargs /* = cif->nargs, after checking cif */; /* When the foreign function is called, we need an array (ivals) of nargs * ForeignAny objects to store the actual C values that are created, and we * need another array (avalues) for the pointers to these values (this is @@ -2438,6 +2438,13 @@ Scheme_Object *ffi_do_call(void *data, int argc, Scheme_Object *argv[]) if (orig_place && (scheme_current_place_id == 0)) orig_place = 0; #endif + if (!cif) { + scheme_signal_error("ffi-call: foreign-function reference was already finalized%s%s", + name ? "\n name: " : "", + name ? name : ""); + return NULL; + } + nargs = cif->nargs; if ((nargs <= MAX_QUICK_ARGS)) { ivals = stack_ivals; avalues = stack_avalues; @@ -2507,8 +2514,9 @@ Scheme_Object *ffi_do_call(void *data, int argc, Scheme_Object *argv[]) } /* see below */ -void free_fficall_data(void *ignored, void *p) +void free_fficall_data(void *data, void *p) { + SCHEME_VEC_ELS(data)[4] = NULL; free(((ffi_cif*)p)->arg_types); free(p); } From 20a9dcbdbdb316d9e7ab492ec54647778879f299 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 22 Oct 2012 13:18:52 -0400 Subject: [PATCH 719/746] db: fix finalization bug (cherry picked from commit 8226899df387629babc5a7bf7ffbcdbac4f237be) --- collects/db/private/odbc/connection.rkt | 9 ++++++++- collects/db/private/sqlite3/connection.rkt | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/collects/db/private/odbc/connection.rkt b/collects/db/private/odbc/connection.rkt index 30414008f9..5f23a1c5c2 100644 --- a/collects/db/private/odbc/connection.rkt +++ b/collects/db/private/odbc/connection.rkt @@ -656,7 +656,14 @@ #:on-notice add-notice!))) (super-new) - (register-finalizer this (lambda (obj) (send obj disconnect))))) + (register-finalizer this + (lambda (obj) + ;; Keep a reference to the class to keep all FFI callout objects + ;; (eg, SQLDisconnect) used by its methods from being finalized. + (let ([dont-gc this%]) + (send obj disconnect) + ;; Dummy result to prevent reference from being optimized away + dont-gc))))) ;; ---------------------------------------- diff --git a/collects/db/private/sqlite3/connection.rkt b/collects/db/private/sqlite3/connection.rkt index 5a716249cc..a4d04423fb 100644 --- a/collects/db/private/sqlite3/connection.rkt +++ b/collects/db/private/sqlite3/connection.rkt @@ -316,7 +316,14 @@ ;; ---- (super-new) - (register-finalizer this (lambda (obj) (send obj disconnect))))) + (register-finalizer this + (lambda (obj) + ;; Keep a reference to the class to keep all FFI callout objects + ;; (eg, sqlite3_close) used by its methods from being finalized. + (let ([dont-gc this%]) + (send obj disconnect) + ;; Dummy result to prevent reference from being optimized away + dont-gc))))) ;; ---------------------------------------- From 03c2846560e26767fc4ccab87e2583609bd2cdb7 Mon Sep 17 00:00:00 2001 From: John Clements Date: Mon, 22 Oct 2012 14:56:36 -0700 Subject: [PATCH 720/746] updated HISTORY Include in 5.3.1 release. (cherry picked from commit 54c5538fd61ca90b4410faaea6c5799d3ab80c72) --- doc/release-notes/stepper/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes/stepper/HISTORY.txt b/doc/release-notes/stepper/HISTORY.txt index cc7534f783..2f1c1ca385 100644 --- a/doc/release-notes/stepper/HISTORY.txt +++ b/doc/release-notes/stepper/HISTORY.txt @@ -1,6 +1,10 @@ Stepper ------- +Changes for 5.3.1: + +Addded external interface, for third-party stepper developers. + Changes for 5.3: Minor bug fixes. From 6b6a0b21d59756845b5eb5712130fde8be5159de Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 22 Oct 2012 17:09:32 -0400 Subject: [PATCH 721/746] macro stepper: fix bug re taking over run button Closes PR 13019 (cherry picked from commit 5f154015617715c8325519120079327b3e9dd6fd) --- collects/macro-debugger/tool.rkt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/collects/macro-debugger/tool.rkt b/collects/macro-debugger/tool.rkt index 5c48147b03..f5716694d1 100644 --- a/collects/macro-debugger/tool.rkt +++ b/collects/macro-debugger/tool.rkt @@ -269,8 +269,12 @@ (set! user-custodian (current-custodian))) (define (uncaught-exception-raised) ;; =user= - ;; formerly shut down user custodian - (void)) + (set! normal-termination? #t) + (parameterize ([current-eventspace drs-eventspace]) + (queue-callback + (λ () + (cleanup) + (custodian-shutdown-all user-custodian))))) (define (show-error-report/tab) ;; =drs= (send the-tab turn-on-error-report) (send (send the-tab get-error-report-text) scroll-to-position 0) @@ -294,7 +298,6 @@ (parameterize ([current-eventspace drs-eventspace]) (queue-callback (λ () - (send the-tab syncheck:clear-highlighting) (cleanup) (custodian-shutdown-all user-custodian)))))) From 67b600c68b86b085352012708edf6514f97db4a7 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Mon, 22 Oct 2012 17:26:33 -0400 Subject: [PATCH 722/746] macro-stepper: show errors in provide expansion closes PR 13018 (cherry picked from commit 1137b444ad8393cd01faff18602e3facc3322c89) --- collects/macro-debugger/model/reductions.rkt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/collects/macro-debugger/model/reductions.rkt b/collects/macro-debugger/model/reductions.rkt index 6757bdf582..b0e9e1f807 100644 --- a/collects/macro-debugger/model/reductions.rkt +++ b/collects/macro-debugger/model/reductions.rkt @@ -221,12 +221,7 @@ [#:learn (list #'?var)])] [(Wrap p:provide (e1 e2 rs ?1 inners ?2)) - (let ([wrapped-inners - (for/list ([inner (in-list inners)]) - (match inner - [(Wrap deriv (e1 e2)) - (make local-expansion e1 e2 - #f e1 inner #f e2 #f)]))]) + (let ([wrapped-inners (map expr->local-action inners)]) (R [! ?1] [#:pattern ?form] [#:pass1] @@ -657,7 +652,9 @@ [#:do (DEBUG (printf "** module begin pass 2\n"))] [ModulePass ?forms pass2] ;; ignore pass3 for now: only provides - )])) + [#:new-local-context + [#:pattern ?form] + [LocalActions ?form (map expr->local-action (or pass3 null))]])])) ;; ModulePass : (list-of MBRule) -> RST (define (ModulePass mbrules) @@ -785,6 +782,12 @@ (when #f (apply error sym args))) +(define (expr->local-action d) + (match d + [(Wrap deriv (e1 e2)) + (make local-expansion e1 e2 + #f e1 d #f e2 #f)])) + ;; opaque-table ;; Weakly remembers assoc between opaque values and ;; actual syntax, so that actual can be substituted in From f61c3ca3f8e2056c086d16655dff7fcb3092057a Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 24 Oct 2012 06:45:11 -0600 Subject: [PATCH 723/746] fix GC alignment bug Merge to v5.3.1 (cherry picked from commit a2c4f6064d4b315372aff3a717ad8a27ae2a0ec1) --- src/racket/gc2/newgc.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/racket/gc2/newgc.c b/src/racket/gc2/newgc.c index 9956f8b9e3..3246bca34a 100644 --- a/src/racket/gc2/newgc.c +++ b/src/racket/gc2/newgc.c @@ -753,14 +753,17 @@ int GC_is_allocated(void *p) # else # define PREFIX_WSIZE 3 # endif +# define CHECK_ALIGN_MASK 0xF #elif defined(GC_ALIGN_EIGHT) # if defined(SIXTY_FOUR_BIT_INTEGERS) # define PREFIX_WSIZE 0 # else # define PREFIX_WSIZE 1 # endif +# define CHECK_ALIGN_MASK 0x7 #else /* GC_ALIGN_FOUR or byte aligned */ # define PREFIX_WSIZE 0 +# define CHECK_ALIGN_MASK 0x3 #endif #define PREFIX_SIZE (PREFIX_WSIZE * WORD_SIZE) @@ -773,7 +776,8 @@ int GC_is_allocated(void *p) #define MAX_OBJECT_SIZE (APAGE_SIZE - ((PREFIX_WSIZE + 3) * WORD_SIZE)) #define ASSERT_TAG(tag) GC_ASSERT((tag) >= 0 && (tag) <= NUMBER_OF_TAGS) -#define ASSERT_VALID_OBJPTR(objptr) GC_ASSERT(!((intptr_t)(objptr) & (0x3))) +#define ASSERT_VALID_OBJPTR(objptr) GC_ASSERT(!((intptr_t)(objptr) & CHECK_ALIGN_MASK)) +#define ASSERT_VALID_INFOPTR(objptr) GC_ASSERT(!(((intptr_t)(objptr) + sizeof(objhead)) & CHECK_ALIGN_MASK)) /* Generation 0. Generation 0 is a set of very large pages in a list(gc->gen0.pages), plus a set of smaller bigpages in a separate list(gc->gen0.big_pages). @@ -1233,8 +1237,8 @@ inline static void gen0_allocate_and_setup_new_page(NewGC *gc) { if (!gc->gen0.pages) gc->gen0.pages = new_mpage; - GC_gen0_alloc_page_ptr = NUM(new_mpage->addr); - ASSERT_VALID_OBJPTR(GC_gen0_alloc_page_ptr); + GC_gen0_alloc_page_ptr = NUM(new_mpage->addr) + new_mpage->size; + ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); GC_gen0_alloc_page_end = NUM(new_mpage->addr) + GEN0_ALLOC_SIZE(new_mpage); } @@ -1249,7 +1253,7 @@ inline static uintptr_t allocate_slowpath(NewGC *gc, size_t allocate_size, uintp if(gc->gen0.curr_alloc_page && gc->gen0.curr_alloc_page->next) { gc->gen0.curr_alloc_page = gc->gen0.curr_alloc_page->next; GC_gen0_alloc_page_ptr = NUM(gc->gen0.curr_alloc_page->addr) + gc->gen0.curr_alloc_page->size; - ASSERT_VALID_OBJPTR(GC_gen0_alloc_page_ptr); + ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); GC_gen0_alloc_page_end = NUM(gc->gen0.curr_alloc_page->addr) + GEN0_ALLOC_SIZE(gc->gen0.curr_alloc_page); } /* WARNING: tries to avoid a collection but @@ -1269,7 +1273,7 @@ inline static uintptr_t allocate_slowpath(NewGC *gc, size_t allocate_size, uintp #endif } newptr = GC_gen0_alloc_page_ptr + allocate_size; - ASSERT_VALID_OBJPTR(newptr); + ASSERT_VALID_INFOPTR(newptr); } while (OVERFLOWS_GEN0(newptr)); @@ -1288,7 +1292,6 @@ inline static void *allocate(const size_t request_size, const int type) /* ensure that allocation will fit in a gen0 page */ newptr = GC_gen0_alloc_page_ptr + allocate_size; - ASSERT_VALID_OBJPTR(newptr); /* SLOW PATH: allocate_size overflows current gen0 page */ if(OVERFLOWS_GEN0(newptr)) { @@ -1302,12 +1305,15 @@ inline static void *allocate(const size_t request_size, const int type) newptr = allocate_slowpath(gc, allocate_size, newptr); } + + ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); /* actual Allocation */ { objhead *info = (objhead *)PTR(GC_gen0_alloc_page_ptr); GC_gen0_alloc_page_ptr = newptr; + ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); if (type == PAGE_ATOMIC) memset(info, 0, sizeof(objhead)); /* init objhead */ @@ -1333,7 +1339,6 @@ inline static void *fast_malloc_one_small_tagged(size_t request_size, int dirty) const size_t allocate_size = COMPUTE_ALLOC_SIZE_FOR_OBJECT_SIZE(request_size); newptr = GC_gen0_alloc_page_ptr + allocate_size; - ASSERT_VALID_OBJPTR(newptr); if(OVERFLOWS_GEN0(newptr)) { return GC_malloc_one_tagged(request_size); @@ -1341,6 +1346,7 @@ inline static void *fast_malloc_one_small_tagged(size_t request_size, int dirty) objhead *info = (objhead *)PTR(GC_gen0_alloc_page_ptr); GC_gen0_alloc_page_ptr = newptr; + ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); if (dirty) memset(info, 0, sizeof(objhead)); /* init objhead */ @@ -1366,7 +1372,6 @@ void *GC_malloc_pair(void *car, void *cdr) const size_t allocate_size = PAIR_SIZE_IN_BYTES; newptr = GC_gen0_alloc_page_ptr + allocate_size; - ASSERT_VALID_OBJPTR(newptr); if(OVERFLOWS_GEN0(newptr)) { NewGC *gc = GC_get_GC(); @@ -1384,6 +1389,7 @@ void *GC_malloc_pair(void *car, void *cdr) else { objhead *info = (objhead *) PTR(GC_gen0_alloc_page_ptr); GC_gen0_alloc_page_ptr = newptr; + ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); memset(info, 0, sizeof(objhead)); /* init objhead */ @@ -1391,8 +1397,9 @@ void *GC_malloc_pair(void *car, void *cdr) info->size = BYTES_MULTIPLE_OF_WORD_TO_WORDS(allocate_size); /* ALIGN_BYTES_SIZE bumbed us up to the next word boundary */ pair = OBJHEAD_TO_OBJPTR(info); - ASSERT_VALID_OBJPTR(pair); } + + ASSERT_VALID_OBJPTR(pair); /* initialize pair */ { @@ -1711,7 +1718,7 @@ inline static void resize_gen0(NewGC *gc, uintptr_t new_size) /* we're going to allocate onto the first page now */ gc->gen0.curr_alloc_page = gc->gen0.pages; GC_gen0_alloc_page_ptr = NUM(gc->gen0.curr_alloc_page->addr) + gc->gen0.curr_alloc_page->size; - ASSERT_VALID_OBJPTR(GC_gen0_alloc_page_ptr); + ASSERT_VALID_INFOPTR(GC_gen0_alloc_page_ptr); GC_gen0_alloc_page_end = NUM(gc->gen0.curr_alloc_page->addr) + GEN0_ALLOC_SIZE(gc->gen0.curr_alloc_page); /* set the two size variables */ @@ -2594,7 +2601,7 @@ static void wait_if_master_in_progress(NewGC *gc, Log_Master_Info *lmi) { /* MUST CALL WITH cangc lock */ static intptr_t NewGCMasterInfo_find_free_id() { - GC_ASSERT(MASTERGCINFO->live <= MASTERGCINFO->size); + GC_ASSERT(MASTERGCINFO->alive <= MASTERGCINFO->size); if ((MASTERGCINFO->alive + 1) == MASTERGCINFO->size) { MASTERGCINFO->size++; MASTERGCINFO->alive++; @@ -2613,6 +2620,7 @@ static intptr_t NewGCMasterInfo_find_free_id() { } printf("Error in MASTERGCINFO table\n"); abort(); + return 0; } static void NewGCMasterInfo_register_gc(NewGC *newgc) { From 4f504e5f19430c017be3912c21cef3d9baa2d629 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 24 Oct 2012 13:12:22 -0700 Subject: [PATCH 724/746] fix syntax checking for `case' Merge to v5.3.1 (cherry picked from commit f43172128b12d08b3827ce0c3da0665ad2e7e0a2) --- collects/racket/private/case.rkt | 51 +++++++++++++++++++++++------- collects/tests/racket/syntax.rktl | 10 ++++++ collects/tests/racket/testing.rktl | 7 ++-- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/collects/racket/private/case.rkt b/collects/racket/private/case.rkt index 1609e25402..201316b59b 100644 --- a/collects/racket/private/case.rkt +++ b/collects/racket/private/case.rkt @@ -32,18 +32,45 @@ (case/dispatch tmp [(k ...) e1 e2 ...] ... [else x1 x2 ...]))))] ;; Error cases - [(_ v (bad e1 e2 ...) . rest) - (raise-syntax-error - #f - "bad syntax (not a datum sequence)" - stx - (syntax bad))] - [(_ v clause . rest) - (raise-syntax-error - #f - "bad syntax (missing expression after datum sequence)" - stx - (syntax clause))] + [(_ v clause ...) + (let loop ([clauses (syntax->list #'(clause ...))]) + (unless (null? clauses) + (let ([clause (car clauses)]) + (syntax-case clause () + [((_ ...) _ _ ...) + (loop (cdr clauses))] + [((_ ...) . _) + (syntax-case clause () + [(_) + (raise-syntax-error + #f + "bad syntax (missing expression after datum sequence)" + stx + clause)] + [(_ . _) + (raise-syntax-error + #f + "bad syntax (illegal use of `.' in clause)" + stx + clause)] + [_ + (raise-syntax-error + #f + "bad syntax (ill-formed clause)" + stx + clause)])] + [(bad . _) + (raise-syntax-error + #f + "bad syntax (not a datum sequence)" + stx + (syntax bad))] + [_ + (raise-syntax-error + #f + "bad syntax (ill-formed clause)" + stx + (syntax bad))]))))] [(_ . v) (not (null? (syntax-e (syntax v)))) (raise-syntax-error diff --git a/collects/tests/racket/syntax.rktl b/collects/tests/racket/syntax.rktl index 788ed8b283..a73c98fefc 100644 --- a/collects/tests/racket/syntax.rktl +++ b/collects/tests/racket/syntax.rktl @@ -315,6 +315,16 @@ [else #f]))) (error-test #'(cond [(values 1 2) 8]) arity?) (error-test #'(case (values 1 2) [(a) 8]) arity?) +(syntax-test #'(case 1 []) #rx"ill-formed clause") +(syntax-test #'(case 1 [(y) 5] []) #rx"ill-formed clause") +(syntax-test #'(case 1 [x]) #rx"not a datum sequence") +(syntax-test #'(case 1 [(y) 5] [x]) #rx"not a datum sequence") +(syntax-test #'(case 1 [(y) 5] [x x]) #rx"not a datum sequence") +(syntax-test #'(case 1 [x x]) #rx"not a datum sequence") +(syntax-test #'(case 1 [(x)]) #rx"missing expression after datum sequence") +(syntax-test #'(case 1 [(y) 5] [(x)]) #rx"missing expression after datum sequence") +(syntax-test #'(case 1 [(x) . 8]) #rx"illegal use of `.'") +(syntax-test #'(case 1 [(x) 10] . 9) #rx"illegal use of `.'") ;; test larger `case' dispatches to trigger for binary-search ;; and hash-table-based dispatch: diff --git a/collects/tests/racket/testing.rktl b/collects/tests/racket/testing.rktl index 661a84b25e..671cbc0314 100644 --- a/collects/tests/racket/testing.rktl +++ b/collects/tests/racket/testing.rktl @@ -222,11 +222,14 @@ transcript. (define no-extra-if-tests? #f) -(define (syntax-test expr) +(define (syntax-test expr [rx #f]) (error-test expr exn:fail:syntax?) (unless no-extra-if-tests? (error-test (datum->syntax expr `(if #f ,expr (void)) expr) - exn:fail:syntax?))) + (lambda (x) + (and (exn:fail:syntax? x) + (or (not rx) + (regexp-match? rx (exn-message x)))))))) (define arity-test (case-lambda From 1a535768f44d23c013279aa00e80bf0d8ee64aa9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 24 Oct 2012 17:03:35 -0700 Subject: [PATCH 725/746] doc repair Looks like it was an accidental incorrect update Merge to v5.3.1 (cherry picked from commit b239a295447845d6214c1a346826256e5d6240bc) --- collects/scribblings/reference/struct.scrbl | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/collects/scribblings/reference/struct.scrbl b/collects/scribblings/reference/struct.scrbl index 82954a27c7..a4ba5ac309 100644 --- a/collects/scribblings/reference/struct.scrbl +++ b/collects/scribblings/reference/struct.scrbl @@ -100,9 +100,7 @@ override the default @racket[equal?] definition through the [immutables (listof exact-nonnegative-integer?) null] [guard (or/c procedure? #f) #f] - [constructor-name (or/c symbol? #f) #f] - [generate (-> contract? (-> int? any/c))] - [exercise (-> contract? (-> int? any/c any/c))]) + [constructor-name (or/c symbol? #f) #f]) (values struct-type? struct-constructor-procedure? struct-predicate-procedure? @@ -176,14 +174,6 @@ If @racket[constructor-name] is not @racket[#f], it is used as the name of the generated @tech{constructor} procedure as returned by @racket[object-name] or in the printed form of the constructor value. -The @racket[generate] argument is used to define a new generator for -this structure type, which can be used to create random instances of -the structure type. For more information see @racket[contract-generate]. - -The @racket[exercise] argument allows you to define a function to verify -that a given value is an instance of your contract. This will also be used -for random generation. - The result of @racket[make-struct-type] is five values: @itemize[ From 3c8111f93aa184c0b71e2ea09d82192503d51189 Mon Sep 17 00:00:00 2001 From: Stevie Strickland Date: Wed, 24 Oct 2012 19:09:48 -0700 Subject: [PATCH 726/746] Don't copy chaperoned immutable vectors. (cherry picked from commit 717cf332b6a12d0cb9bf476d8b78335ed80188a4) --- collects/racket/contract/private/box.rkt | 2 +- collects/racket/contract/private/hash.rkt | 2 +- collects/racket/contract/private/vector.rkt | 4 +- collects/tests/racket/contract-test.rktl | 47 ++++++++++++++++++++- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/collects/racket/contract/private/box.rkt b/collects/racket/contract/private/box.rkt index c2512cac9b..e0731d763e 100644 --- a/collects/racket/contract/private/box.rkt +++ b/collects/racket/contract/private/box.rkt @@ -78,7 +78,7 @@ [neg-elem-proj ((contract-projection elem-ctc) (blame-swap blame))]) (λ (val) (check-box/c ctc val blame) - (if (immutable? val) + (if (and (immutable? val) (not (chaperone? val))) (box-immutable (pos-elem-proj (unbox val))) (box-wrapper val (λ (b v) (pos-elem-proj v)) diff --git a/collects/racket/contract/private/hash.rkt b/collects/racket/contract/private/hash.rkt index b88c4da0ac..1fe4e68be4 100644 --- a/collects/racket/contract/private/hash.rkt +++ b/collects/racket/contract/private/hash.rkt @@ -169,7 +169,7 @@ (define neg-rng-proj (rng-proc (blame-add-context blame "the values of" #:swap? #t))) (λ (val) (check-hash/c ctc val blame) - (if (immutable? val) + (if (and (immutable? val) (not (chaperone? val))) (let ([hash-maker (cond [(hash-equal? val) make-immutable-hash] diff --git a/collects/racket/contract/private/vector.rkt b/collects/racket/contract/private/vector.rkt index 6155074821..83568fb9d5 100644 --- a/collects/racket/contract/private/vector.rkt +++ b/collects/racket/contract/private/vector.rkt @@ -104,7 +104,7 @@ (apply raise-blame-error blame val args))) (λ (val) (check val raise-blame #f) - (if (immutable? val) + (if (and (immutable? val) (not (chaperone? val))) (apply vector-immutable (for/list ([e (in-vector val)]) (elem-pos-proj e))) @@ -249,7 +249,7 @@ (blame-add-context blame (format "the ~a element of" (n->th i)) #:swap? #t)))]) (λ (val) (check-vector/c ctc val blame) - (if (immutable? val) + (if (and (immutable? val) (not (chaperone? val))) (apply vector-immutable (for/list ([e (in-vector val)] [i (in-naturals)]) diff --git a/collects/tests/racket/contract-test.rktl b/collects/tests/racket/contract-test.rktl index 9177af5f49..77a2317ae8 100644 --- a/collects/tests/racket/contract-test.rktl +++ b/collects/tests/racket/contract-test.rktl @@ -4503,8 +4503,53 @@ 'make-flat-contract-bad-6 '(chaperone-contract? proj:prime-list/c) #t) + - +;; Adding tests for using vector/box/hash contracts with already chaperoned values + + (test/no-error + '(let ([v (chaperone-vector (vector-immutable 1) + (λ (vec i v) v) + (λ (vec i v) v))]) + (contract (vectorof any/c) v 'pos 'neg))) + + (test/no-error + '(let ([v (chaperone-vector (vector-immutable 1) + (λ (vec i v) v) + (λ (vec i v) v))]) + (contract (vector/c any/c) v 'pos 'neg))) + + (test/no-error + '(let ([v (chaperone-box (box-immutable 1) + (λ (box v) v) + (λ (box v) v))]) + (contract (box/c any/c) v 'pos 'neg))) + + (test/no-error + '(let ([v (chaperone-hash (make-immutable-hash (list (cons 1 2))) + (λ (hash k) (values k (λ (h k v) v))) + (λ (hash k v) (values k v)) + (λ (hash k) k) + (λ (hash k) k))]) + (contract (hash/c any/c any/c) v 'pos 'neg))) + + (test/no-error + '(let ([v (chaperone-hash (make-immutable-hasheq (list (cons 1 2))) + (λ (hash k) (values k (λ (h k v) v))) + (λ (hash k v) (values k v)) + (λ (hash k) k) + (λ (hash k) k))]) + (contract (hash/c any/c any/c) v 'pos 'neg))) + + (test/no-error + '(let ([v (chaperone-hash (make-immutable-hasheqv (list (cons 1 2))) + (λ (hash k) (values k (λ (h k v) v))) + (λ (hash k v) (values k v)) + (λ (hash k) k) + (λ (hash k) k))]) + (contract (hash/c any/c any/c) v 'pos 'neg))) + + ; ; ; From 7abf69ef8543b0da0cd64458ae8ee0af18a2c89d Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Sun, 14 Oct 2012 15:09:22 -0400 Subject: [PATCH 727/746] Generate ->* contracts for functions with both optional and keyword arguments. (cherry picked from commit 844e898a548ea3b8fcecb97b0e59f8dcf06e0949) --- .../typed-racket/succeed/contract-opt+kw.rkt | 37 ++++++++ .../typed-racket/private/type-contract.rkt | 84 ++++++++++++++----- 2 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 collects/tests/typed-racket/succeed/contract-opt+kw.rkt diff --git a/collects/tests/typed-racket/succeed/contract-opt+kw.rkt b/collects/tests/typed-racket/succeed/contract-opt+kw.rkt new file mode 100644 index 0000000000..d7151db8ad --- /dev/null +++ b/collects/tests/typed-racket/succeed/contract-opt+kw.rkt @@ -0,0 +1,37 @@ +#lang racket/load + +(module defs typed/racket + (provide (all-defined-out)) + + (: foo (case-> ([#:extra Integer] -> Integer) + (Integer [#:extra Integer] -> Integer))) + (define (foo [x 0] #:extra [y 0]) (+ x y)) + + ;; this is not contractable, yet (keywords not the same) + (: bar (case-> (Integer [#:extra Integer] -> Integer) + (Integer [#:extra String] -> Integer))) + (define (bar x #:extra [y "a"]) (+ x (if (integer? y) y (string-length y)))) + + (: baz (case-> (#:extra Integer -> Integer) + (Integer #:extra Integer -> Integer))) + (define (baz [x 0] #:extra y) (+ x y)) + + (: qux (case-> (#:extra Integer [#:super-extra Integer] -> Integer) + (Integer #:extra Integer [#:super-extra Integer] -> Integer))) + (define (qux [x 0] #:extra y #:super-extra [z 0]) (+ x y z))) + +(require 'defs) +(foo) +(foo 1) +(foo #:extra 1) +(foo 1 #:extra 1) + +; (bar 3) ; not contractable + +(baz #:extra 1) +(baz 1 #:extra 1) + +(qux #:extra 1) +(qux 1 #:extra 1) +(qux #:extra 1 #:super-extra 2) +(qux 1 #:extra 1 #:super-extra 3) diff --git a/collects/typed-racket/private/type-contract.rkt b/collects/typed-racket/private/type-contract.rkt index 036a4fb4c8..8b85b94c72 100644 --- a/collects/typed-racket/private/type-contract.rkt +++ b/collects/typed-racket/private/type-contract.rkt @@ -121,14 +121,62 @@ [(Function: (list (top-arr:))) #'procedure?] [(Function: arrs) (set-chaperone!) - (let () + ;; Try to generate a single `->*' contract if possible. + ;; This allows contracts to be generated for functions with both optional and keyword args. + ;; (and don't otherwise require full `case->') + (define conv (match-lambda [(Keyword: kw kty _) (list kw (t->c/neg kty))])) + (define (partition-kws kws) (partition (match-lambda [(Keyword: _ _ mand?) mand?]) kws)) + (define (process-dom dom*) (if method? (cons #'any/c dom*) dom*)) + (define (process-rngs rngs*) + (match rngs* + [(list r) r] + [_ #`(values #,@rngs*)])) + (cond + ;; To generate a single `->*', everything must be the same for all arrs, except for positional + ;; arguments which only need to be monotonically increasing. + ;; TODO sufficient condition, but may not be necessary + [(and + (> (length arrs) 1) + ;; Keyword args, range and rest specs all the same. + (let ([xs (map (match-lambda [(arr: _ rng rest-spec _ kws) (list rng rest-spec kws)]) arrs)]) + (foldl equal? (first xs) (rest xs))) + ;; Positionals are monotonically increasing. + (let-values ([(_ ok?) + (for/fold ([positionals '()] + [ok-so-far? #t]) + ([arr (in-list arrs)]) + (match arr + [(arr: dom _ _ _ _) + (values dom + (and ok-so-far? + (>= (length dom) (length positionals)) + (equal? positionals (take dom (length positionals)))))]))]) + ok?)) + (match* ((first arrs) (last arrs)) + [((arr: first-dom (Values: (list (Result: rngs (FilterSet: (Top:) (Top:)) (Empty:)) ...)) rst #f kws) + (arr: last-dom _ _ _ _)) ; all but dom is the same for all + (with-syntax + ([(dom* ...) + ;; Mandatory arguments are positionals of the first arr + ;; (smallest set, since postitionals are monotonically increasing) + ;; and mandatory kw args. + (let*-values ([(mand-kws opt-kws) (partition-kws kws)]) + (process-dom (append (map t->c/neg first-dom) + (append-map conv mand-kws))))] + [(opt-dom* ...) + (let-values ([(mand-kws opt-kws) (partition-kws kws)]) + (append (map t->c/neg (drop last-dom (length first-dom))) + (append-map conv opt-kws)))] + [rng* (process-rngs (map t->c rngs))] + [(rst-spec ...) (if rst #'(#:rest (listof #,(t->c/neg rest))) #'())]) + #'((dom* ...) (opt-dom* ...) rst-spec ... . ->* . rng*))])] + [else (define ((f [case-> #f]) a) (define-values (dom* opt-dom* rngs* rst) (match a ;; functions with no filters or objects [(arr: dom (Values: (list (Result: rngs (FilterSet: (Top:) (Top:)) (Empty:)) ...)) rst #f kws) - (let-values ([(mand-kws opt-kws) (partition (match-lambda [(Keyword: _ _ mand?) mand?]) kws)] - [(conv) (match-lambda [(Keyword: kw kty _) (list kw (t->c/neg kty))])]) + (let-values ([(mand-kws opt-kws) (partition-kws kws)]) (values (append (map t->c/neg dom) (append-map conv mand-kws)) (append-map conv opt-kws) (map t->c rngs) @@ -143,21 +191,19 @@ (exit (fail)))] [_ (exit (fail))])) (with-syntax* - ([(dom* ...) (if method? (cons #'any/c dom*) dom*)] - [(opt-dom* ...) opt-dom*] - [rng* (match rngs* - [(list r) r] - [_ #`(values #,@rngs*)])] - [rst* rst] - [(rst-spec ...) (if rst #'(#:rest (listof rst*)) #'())]) - ;; Garr, I hate case->! - (if (and (pair? (syntax-e #'(opt-dom* ...))) case->) - (exit (fail)) - (if (or rst (pair? (syntax-e #'(opt-dom* ...)))) - (if case-> - #'(dom* ... rst-spec ... . -> . rng*) - #'((dom* ...) (opt-dom* ...) rst-spec ... . ->* . rng*)) - #'(dom* ... . -> . rng*))))) + ([(dom* ...) (process-dom dom*)] + [(opt-dom* ...) opt-dom*] + [rng* (process-rngs rngs*)] + [rst* rst] + [(rst-spec ...) (if rst #'(#:rest (listof rst*)) #'())]) + ;; Garr, I hate case->! + (if (and (pair? (syntax-e #'(opt-dom* ...))) case->) + (exit (fail)) + (if (or rst (pair? (syntax-e #'(opt-dom* ...)))) + (if case-> + #'(dom* ... rst-spec ... . -> . rng*) + #'((dom* ...) (opt-dom* ...) rst-spec ... . ->* . rng*)) + #'(dom* ... . -> . rng*))))) (unless (no-duplicates (for/list ([t arrs]) (match t [(arr: dom _ _ _ _) (length dom)] @@ -166,7 +212,7 @@ (exit (fail))) (match (map (f (not (= 1 (length arrs)))) arrs) [(list e) e] - [l #`(case-> #,@l)]))] + [l #`(case-> #,@l)])])] [_ (int-err "not a function" f)])) ;; Helpers for contract requirements From 422a24db81f56a032bb13647cb54ac3f1c2aa440 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 25 Oct 2012 00:18:50 -0700 Subject: [PATCH 728/746] Improve contract generation in Typed Racket. This fixes several issues: - `Parameter` generates impersonator contracts correctly - `Any` handling now copies immutable data when possible - `Any` now recognizes more atomic base types Merge to 5.3.1. (cherry picked from commit c6dc1e6ece441a7d56c2f2229dc9c0e144f8ff6f) --- .../typed-racket/succeed/parameter-c.rkt | 7 +++ .../typed-racket/succeed/vector-chap.rkt | 11 +++++ .../typed-racket/private/type-contract.rkt | 43 +++++++++++++------ collects/typed-racket/utils/any-wrap.rkt | 21 +++++++-- 4 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 collects/tests/typed-racket/succeed/parameter-c.rkt create mode 100644 collects/tests/typed-racket/succeed/vector-chap.rkt diff --git a/collects/tests/typed-racket/succeed/parameter-c.rkt b/collects/tests/typed-racket/succeed/parameter-c.rkt new file mode 100644 index 0000000000..95743ae043 --- /dev/null +++ b/collects/tests/typed-racket/succeed/parameter-c.rkt @@ -0,0 +1,7 @@ +#lang typed/racket/base + +(require/typed + rackunit + [current-check-around (Parameter Any)]) + + diff --git a/collects/tests/typed-racket/succeed/vector-chap.rkt b/collects/tests/typed-racket/succeed/vector-chap.rkt new file mode 100644 index 0000000000..7ca8aa758c --- /dev/null +++ b/collects/tests/typed-racket/succeed/vector-chap.rkt @@ -0,0 +1,11 @@ +#lang racket/load + +(module m1 racket + (define (f x y) (equal? x y)) + (provide f)) + +(module m2 typed/racket + (require/typed 'm1 [f (Any Any -> Boolean)]) + (f (vector 1 2) (vector 1 2))) + +(require 'm2) diff --git a/collects/typed-racket/private/type-contract.rkt b/collects/typed-racket/private/type-contract.rkt index 8b85b94c72..e537217a07 100644 --- a/collects/typed-racket/private/type-contract.rkt +++ b/collects/typed-racket/private/type-contract.rkt @@ -54,14 +54,24 @@ (let ([typ (if maker? ((map fld-t (Struct-flds (lookup-type-name (Name-id typ)))) #f . t:->* . typ) typ)]) - (with-syntax ([cnt (type->contract - typ - ;; this is for a `require/typed', so the value is not from the typed side - #:typed-side #f - #:kind kind - (lambda () (tc-error/stx prop "Type ~a could not be converted to a contract." typ)))]) - (quasisyntax/loc stx (define-values (n) (recursive-contract cnt #,(contract-kind->keyword kind))))))] - [_ (int-err "should never happen - not a define-values: ~a" (syntax->datum stx))])) + (with-syntax ([cnt (type->contract + typ + ;; this is for a `require/typed', so the value is not from the typed side + #:typed-side #f + #:kind kind + (λ () + (tc-error/stx + prop + "Type ~a could not be converted to a contract." + typ)))]) + (quasisyntax/loc + stx + (define-values (n) + (recursive-contract + cnt + #,(contract-kind->keyword kind))))))] + [_ (int-err "should never happen - not a define-values: ~a" + (syntax->datum stx))])) (define (change-contract-fixups forms) (map (lambda (e) @@ -89,7 +99,6 @@ (for/fold ((acc i)) ((v args)) (contract-kind-max2 v acc))) - (define (contract-kind-min i . args) (define (contract-kind-min2 x y) (cond @@ -106,7 +115,7 @@ (string->keyword (symbol->string sym))) (define (type->contract ty fail #:out [out? #f] #:typed-side [from-typed? #t] #:kind [kind 'impersonator]) - (define vars (make-parameter '())) + (define vars (make-parameter '())) (define current-contract-kind (make-parameter flat-sym)) (define (increase-current-contract-kind! kind) (current-contract-kind (contract-kind-max (current-contract-kind) kind))) @@ -138,7 +147,9 @@ [(and (> (length arrs) 1) ;; Keyword args, range and rest specs all the same. - (let ([xs (map (match-lambda [(arr: _ rng rest-spec _ kws) (list rng rest-spec kws)]) arrs)]) + (let ([xs (map (match-lambda [(arr: _ rng rest-spec _ kws) + (list rng rest-spec kws)]) + arrs)]) (foldl equal? (first xs) (rest xs))) ;; Positionals are monotonically increasing. (let-values ([(_ ok?) @@ -338,11 +349,13 @@ (match-let ([(Mu-name: n-nm _) ty]) (with-syntax ([(n*) (generate-temporaries (list n-nm))]) (parameterize ([vars (cons (list n #'n*) (vars))] - [current-contract-kind (contract-kind-min kind chaperone-sym)]) + [current-contract-kind + (contract-kind-min kind chaperone-sym)]) (define ctc (t->c b)) #`(letrec ([n* (recursive-contract #,ctc - #,(contract-kind->keyword (current-contract-kind)))]) + #,(contract-kind->keyword + (current-contract-kind)))]) n*))))] [(Value: #f) #'false/c] [(Instance: (? Mu? t)) @@ -389,7 +402,9 @@ #`(syntax/c #,(t->c t #:kind flat-sym))] [(Value: v) #`(flat-named-contract #,(format "~a" v) (lambda (x) (equal? x '#,v)))] ;; TODO Is this sound? - [(Param: in out) #`(parameter/c #,(t->c out))] + [(Param: in out) + (set-impersonator!) + #`(parameter/c #,(t->c out))] [(Hashtable: k v) (when (equal? kind flat-sym) (exit (fail))) #`(hash/c #,(t->c k #:kind chaperone-sym) #,(t->c v) #:immutable 'dont-care)] diff --git a/collects/typed-racket/utils/any-wrap.rkt b/collects/typed-racket/utils/any-wrap.rkt index da3f65d963..4699ad75bb 100644 --- a/collects/typed-racket/utils/any-wrap.rkt +++ b/collects/typed-racket/utils/any-wrap.rkt @@ -1,12 +1,12 @@ #lang racket/base -(require racket/match racket/contract/base racket/contract/combinator) +(require racket/match racket/contract/base racket/contract/combinator racket/flonum racket/fixnum) (define undef (letrec ([x x]) x)) (define (traverse b) (define (fail v) - (raise-blame-error (blame-swap b) v "Attempted to use a higher-order value passed as `Any`")) + (raise-blame-error (blame-swap b) v "Attempted to use a higher-order value passed as `Any` in untyped code")) (define (t v) (define (wrap-struct s) @@ -43,10 +43,25 @@ (match v [(? (lambda (e) (or (number? e) (string? e) (char? e) (symbol? e) - (null? e) (regexp? e) (eq? undef e) + (null? e) (regexp? e) (eq? undef e) (path? e) + (flvector? e) (flvector? e) (regexp? e) (keyword? e) (bytes? e) (boolean? e) (void? e)))) v] [(cons x y) (cons (t x) (t y))] + [(? vector? (? immutable?)) + ;; fixme -- should have an immutable for/vector + (vector->immutable-vector + (for/vector #:length (vector-length v) + ([i (in-vector v)]) (t i)))] + [(? box? (? immutable?)) (box-immutable (t (unbox v)))] + ;; fixme -- handling keys + ;; [(? hasheq? (? immutable?)) + ;; (for/hasheq ([(k v) (in-hash v)]) (values k v))] + ;; [(? hasheqv? (? immutable?)) + ;; (for/hasheqv ([(k v) (in-hash v)]) (values k v))] + + [(? hash? (? immutable?)) + (for/hash ([(k v) (in-hash v)]) (values (t k) (t v)))] [(? vector?) (chaperone-vector v (lambda (v i e) (t e)) (lambda (v i e) (fail v)))] From 64826c1db36e7aa40d0e30c558193cec3e980945 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 27 Oct 2012 09:57:40 -0500 Subject: [PATCH 729/746] adjust drracket gui test suite infrastructure so that it waits for pending events to finish when looking for new frames (cherry picked from commit 24592a08007426b7d5810e36311b93210e00921d) --- .../drracket/private/drracket-test-util.rkt | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/collects/tests/drracket/private/drracket-test-util.rkt b/collects/tests/drracket/private/drracket-test-util.rkt index e1f69725ef..b5aa08cc36 100644 --- a/collects/tests/drracket/private/drracket-test-util.rkt +++ b/collects/tests/drracket/private/drracket-test-util.rkt @@ -100,42 +100,48 @@ (method-in-interface? 'get-execute-button (object-interface frame))) (define (wait-for-drracket-frame [print-message? #f]) - (let ([wait-for-drracket-frame-pred - (lambda () - (let ([active (fw:test:get-active-top-level-window)]) - (if (and active - (drracket-frame? active)) - active - #f)))]) + (define (wait-for-drracket-frame-pred) + (define active (fw:test:get-active-top-level-window)) + (if (and active + (drracket-frame? active)) + active + #f)) + (define drr-fr (or (wait-for-drracket-frame-pred) (begin (when print-message? (printf "Select DrRacket frame\n")) - (poll-until wait-for-drracket-frame-pred))))) + (poll-until wait-for-drracket-frame-pred)))) + (when drr-fr + (wait-for-events-in-frame-eventspace drr-fr)) + drr-fr) ;; wait-for-new-frame : frame [(listof eventspace) = null] -> frame ;; returns the newly opened frame, waiting until old-frame ;; is no longer frontmost. Optionally checks other eventspaces ;; waits until the new frame has a focus'd window, too. - (define wait-for-new-frame - (case-lambda - [(old-frame) (wait-for-new-frame old-frame null)] - [(old-frame extra-eventspaces) - (wait-for-new-frame old-frame extra-eventspaces 10)] - [(old-frame extra-eventspaces timeout) - (let ([wait-for-new-frame-pred - (lambda () - (let ([active (or (fw:test:get-active-top-level-window) - (ormap - (lambda (eventspace) - (parameterize ([current-eventspace eventspace]) - (fw:test:get-active-top-level-window))) - extra-eventspaces))]) - (if (and active - (not (eq? active old-frame))) - active - #f)))]) - (poll-until wait-for-new-frame-pred timeout))])) + (define (wait-for-new-frame old-frame [extra-eventspaces '()] [timeout 10]) + (define (wait-for-new-frame-pred) + (define active (or (fw:test:get-active-top-level-window) + (for/or ([eventspace (in-list extra-eventspaces)]) + (parameterize ([current-eventspace eventspace]) + (fw:test:get-active-top-level-window))))) + (if (and active + (not (eq? active old-frame))) + active + #f)) + (define fr (poll-until wait-for-new-frame-pred timeout)) + (when fr (wait-for-events-in-frame-eventspace fr)) + (sleep 1) + fr) + + (define (wait-for-events-in-frame-eventspace fr) + (define sema (make-semaphore 0)) + (parameterize ([current-eventspace (send fr get-eventspace)]) + (queue-callback + (λ () (semaphore-post sema)) + #f)) + (semaphore-wait sema)) ;; wait-for-computation : frame -> void ;; waits until the drracket frame finishes some computation. @@ -377,8 +383,9 @@ child))) (send list-item get-items))]) (when (null? which) - (error 'set-language-level! "couldn't find language: ~e, no match at ~e" - in-language-spec name)) + (error 'set-language-level! "couldn't find language: ~e, no match at ~e, poss: ~s" + in-language-spec name (map (λ (child) (send (send child get-editor) get-text)) + (send list-item get-items)))) (unless (= 1 (length which)) (error 'set-language-level! "couldn't find language: ~e, double match ~e" in-language-spec name)) From 421e8a469e63b27f7090b38ba8272bacc8e5e1ab Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Sat, 27 Oct 2012 17:44:12 -0700 Subject: [PATCH 730/746] Add more specific class types instead of `Any`. Fixes Insert Large Letters dialog. Merge to 5.3.1. (cherry picked from commit 4124c9a41b26092aa0dd7a33916fd8e080aa626f) --- .../drracket/private/insert-large-letters.rkt | 10 +++--- collects/typed/framework/framework.rkt | 17 +--------- collects/typed/mred/mred.rkt | 34 ++++++++++++++----- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/collects/drracket/private/insert-large-letters.rkt b/collects/drracket/private/insert-large-letters.rkt index 7bdbc81a1d..8bcde0a4ee 100644 --- a/collects/drracket/private/insert-large-letters.rkt +++ b/collects/drracket/private/insert-large-letters.rkt @@ -7,7 +7,7 @@ (define-type-alias Bitmap-Message% (Class () - ([parent Any]) + ([parent (Instance Horizontal-Panel%)]) ([set-bm ((Instance Bitmap%) -> Void)]))) @@ -16,7 +16,7 @@ (provide insert-large-letters) -(: insert-large-letters (String Char (Instance Racket:Text%) Any -> Void)) +(: insert-large-letters (String Char (Instance Text:Basic%) Any -> Void)) (define (insert-large-letters comment-prefix comment-character edit parent) (let ([str (make-large-letters-dialog comment-prefix comment-character #f)]) (when (and str @@ -90,7 +90,7 @@ (: pane2 (Instance Horizontal-Pane%)) (define pane2 (new horizontal-pane% (parent info-bar))) - (: txt (Instance Racket:Text%)) + (: txt (Instance Text:Basic%)) (define txt (new racket:text%)) (: ec (Instance Editor-Canvas%)) (define ec (new editor-canvas% [parent dlg] [editor txt])) @@ -145,7 +145,7 @@ (format " (~a)" (floor (inexact->exact w)))))) -(: get-max-line-width ((Instance Racket:Text%) -> Real)) +(: get-max-line-width ((Instance Text:Basic%) -> Real)) (define (get-max-line-width txt) (let loop ([i (+ (send txt last-paragraph) 1)] [#{m : Integer} 0]) @@ -156,7 +156,7 @@ (send txt paragraph-start-position (- i 1)))))]))) -(: render-large-letters (String Char (Instance Font%) String (Instance Racket:Text%) -> (Instance Bitmap%))) +(: render-large-letters (String Char (Instance Font%) String (Instance Text:Basic%) -> (Instance Bitmap%))) (define (render-large-letters comment-prefix comment-character the-font str edit) (define bdc (make-object bitmap-dc% (make-object bitmap% 1 1 #t))) (define-values (tw raw-th td ta) (send bdc get-text-extent str the-font)) diff --git a/collects/typed/framework/framework.rkt b/collects/typed/framework/framework.rkt index d03ebffe95..8501d9b091 100644 --- a/collects/typed/framework/framework.rkt +++ b/collects/typed/framework/framework.rkt @@ -9,28 +9,13 @@ () ([get-font (-> (Instance Font%))]))))]))) -(dt Racket:Text% (Class () - () - ([begin-edit-sequence (-> Void)] - [end-edit-sequence (-> Void)] - [lock (Boolean -> Void)] - [last-position (-> Number)] - [last-paragraph (-> Exact-Nonnegative-Integer)] - [delete (Number Number -> Void)] - [auto-wrap (Any -> Void)] - [paragraph-end-position (Number -> Natural)] - [paragraph-start-position (Number -> Natural)] - [get-start-position (-> Number)] - [get-end-position (-> Number)] - [insert (String Number Number -> Void)]))) - (require/typed/provide framework/framework [preferences:set-default (Symbol Sexp (Any -> Boolean) -> Void)] [preferences:set (Symbol Sexp -> Void)] [editor:get-standard-style-list (-> (Instance Style-List%))] - [racket:text% Racket:Text%] + [racket:text% Text:Basic%] [gui-utils:ok/cancel-buttons ((Instance Horizontal-Panel%) ((Instance Button%) (Instance Event%) -> Void) diff --git a/collects/typed/mred/mred.rkt b/collects/typed/mred/mred.rkt index 9b1ca81a75..2fa0519ea9 100644 --- a/collects/typed/mred/mred.rkt +++ b/collects/typed/mred/mred.rkt @@ -20,28 +20,30 @@ ([parent Any] [width Integer] [label String]) ([show (Any -> Void)]))) (dt Text-Field% (Class () - ([parent Any] [callback Any] [label String]) - ([get-value (-> String)] - [focus (-> Void)]))) + ([parent (Instance Dialog%)] + [callback (Any Any -> Any)] + [label String]) + ([get-value (-> String)] + [focus (-> Void)]))) (dt Horizontal-Panel% (Class () - ([parent Any] + ([parent (Instance Dialog%)] [stretchable-height Any #t] [alignment (List Symbol Symbol) #t]) ())) (dt Choice% (Class () - ([parent Any] [label String] [choices (Listof Any)] [callback Any]) + ([parent (Instance Horizontal-Panel%)] [label String] [choices (Listof Any)] [callback (Any Any -> Any)]) ([get-selection (-> (Option Natural))] [set-selection (Integer -> Any)] [get-string-selection (-> (Option String))] [set-string-selection (String -> Void)]))) (dt Message% (Class () - ([parent Any] [label String]) + ([parent (Instance Horizontal-Panel%)] [label String]) ([set-label ((U String (Instance Bitmap%)) -> Void)]))) (dt Horizontal-Pane% (Class () - ([parent Any]) + ([parent (Instance Horizontal-Panel%)]) ())) (dt Editor-Canvas% (Class () - ([parent Any] [editor Any]) + ([parent (Instance Dialog%)] [editor (Instance Text:Basic%)]) ([set-line-count ((U #f Integer) -> Void)]))) (dt Bitmap-DC% (Class ((Instance Bitmap%)) () @@ -55,6 +57,22 @@ (dt Snip% (Class () () ([get-count (-> Integer)]))) +(dt Text:Basic% (Class () + () + ([begin-edit-sequence (-> Void)] + [end-edit-sequence (-> Void)] + [lock (Boolean -> Void)] + [last-position (-> Number)] + [last-paragraph (-> Exact-Nonnegative-Integer)] + [delete (Number Number -> Void)] + [auto-wrap (Any -> Void)] + [paragraph-end-position (Number -> Integer)] + [paragraph-start-position (Number -> Integer)] + [get-start-position (-> Integer)] + [get-end-position (-> Integer)] + [get-text (Integer (U Integer 'eof) -> String)] + [insert (String Number Number -> Void)]))) + (dt Text% (Class () () ([begin-edit-sequence (-> Void)] From c0ee979ff4702d5739e66053e00710b68d1712c5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 27 Oct 2012 21:31:08 -0600 Subject: [PATCH 731/746] racket/gui gtk: fix on-subwindow-... handling Handling was broken by changes to fix enter and leave events (in commit a5d7812732) Merge to v5.3.1 (cherry picked from commit ba6e383963de1c5e64058d99efceb799171827a9) --- collects/mred/private/wx/gtk/frame.rkt | 2 +- collects/mred/private/wx/gtk/window.rkt | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/collects/mred/private/wx/gtk/frame.rkt b/collects/mred/private/wx/gtk/frame.rkt index e9fc5a56b5..fc041d70d6 100644 --- a/collects/mred/private/wx/gtk/frame.rkt +++ b/collects/mred/private/wx/gtk/frame.rkt @@ -169,7 +169,7 @@ (values vbox-gtk panel-gtk)))) (gtk_widget_show vbox-gtk) (gtk_widget_show panel-gtk) - (connect-key-and-mouse gtk) + (connect-enter-and-leave gtk) (unless is-dialog? (gtk_window_set_icon_list gtk (cdr (force icon-pixbufs+glist)))) diff --git a/collects/mred/private/wx/gtk/window.rkt b/collects/mred/private/wx/gtk/window.rkt index 87c0d0e66b..643f5a13be 100644 --- a/collects/mred/private/wx/gtk/window.rkt +++ b/collects/mred/private/wx/gtk/window.rkt @@ -35,6 +35,7 @@ connect-focus connect-key-and-mouse + connect-enter-and-leave do-button-event (struct-out GtkRequisition) _GtkRequisition-pointer @@ -293,6 +294,10 @@ (let ([wx (gtk->wx gtk)]) (when wx (send wx leave-window))) (do-button-event gtk event #f #t))) +(define (connect-enter-and-leave gtk) + (connect-enter gtk) + (connect-leave gtk)) + (define (connect-key-and-mouse gtk [skip-press? #f]) (connect-key-press gtk) (connect-key-release gtk) @@ -300,8 +305,7 @@ (connect-button-press gtk) (unless skip-press? (connect-button-release gtk)) (connect-pointer-motion gtk) - (connect-enter gtk) - (connect-leave gtk)) + (connect-enter-and-leave gtk)) (define (do-button-event gtk event motion? crossing?) (let ([type (if motion? From 7c49cd5138e3b0c4e77c2d1c9515ee75da849366 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 30 Oct 2012 12:43:41 -0400 Subject: [PATCH 732/746] fix doc typo closes PR 13216 (cherry picked from commit 832d90bf93b5d44185b4bf31fb0e8a18353b7606) --- collects/scribblings/reference/syntax-util.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/reference/syntax-util.scrbl b/collects/scribblings/reference/syntax-util.scrbl index f31f449105..d4125b3507 100644 --- a/collects/scribblings/reference/syntax-util.scrbl +++ b/collects/scribblings/reference/syntax-util.scrbl @@ -79,7 +79,7 @@ creates pattern variable definitions for the pattern variables of (define/with-syntax (px ...) #'(a b c)) (define/with-syntax (tmp ...) (generate-temporaries #'(px ...))) #'([tmp px] ...) -(define-pattern-variable name #'Alice) +(define/with-syntax name #'Alice) #'(hello name) ] } From fd81d53e7babb351a37e2c6f91fdfdb817a2cae5 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 31 Oct 2012 12:17:24 -0600 Subject: [PATCH 733/746] fix error-message code Closes PR 13222 (cherry picked from commit 8f73ebbc36dcb66afa1051889c4e0636f50be5f4) --- collects/tests/racket/udp.rktl | 14 ++++++++++++++ src/racket/src/network.c | 6 ++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/collects/tests/racket/udp.rktl b/collects/tests/racket/udp.rktl index 12c565e3ce..ce4d45331b 100644 --- a/collects/tests/racket/udp.rktl +++ b/collects/tests/racket/udp.rktl @@ -178,3 +178,17 @@ (test w sync w)) (test #t evt? (udp-receive!-evt udp1 us1)) (test #t evt? (udp-send-to-evt udp1 "127.0.0.1" port #"here's more")) + + +;; check that error-repoting doesn't crash: +(let () + (define (q) + (define s (udp-open-socket #f #f)) + (udp-bind! s #f 5999) + s) + + (define s (q)) + (err/rt-test (q) exn:fail:network?) + (udp-close s)) + + diff --git a/src/racket/src/network.c b/src/racket/src/network.c index 446b52a3ca..af10f4736a 100644 --- a/src/racket/src/network.c +++ b/src/racket/src/network.c @@ -3225,7 +3225,8 @@ static Scheme_Object *udp_bind_or_connect(const char *name, int argc, Scheme_Obj " port number: %d\n" " system error: %E", name, - port, address ? address : "#f", + address ? address : "#f", + port, SOCK_ERRNO()); return NULL; } @@ -3257,7 +3258,8 @@ static Scheme_Object *udp_bind_or_connect(const char *name, int argc, Scheme_Obj " port number: %d\n" " system error: %E", name, - port, address ? address : "#f", + address ? address : "#f", + port, SOCK_ERRNO()); return NULL; } From 8bffa07ad55e3991bb6ba83a04ae65d0fec30299 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Wed, 31 Oct 2012 14:53:28 -0400 Subject: [PATCH 734/746] basic history, please merge (cherry picked from commit 45a5cfca12be47d617993004d88c9c3efa78bd17) --- doc/release-notes/teachpack/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes/teachpack/HISTORY.txt b/doc/release-notes/teachpack/HISTORY.txt index 6f480b0057..a2479a554a 100644 --- a/doc/release-notes/teachpack/HISTORY.txt +++ b/doc/release-notes/teachpack/HISTORY.txt @@ -1,3 +1,7 @@ +Version 5.3.1 [Wed Oct 31 14:52:48 EDT 2012] + +* bug fixes + ------------------------------------------------------------------------ Version 5.2.1 [Thu Jan 19 11:36:19 EST 2012] From 74a18c27aa489d676c73b066f036fcaeddbe252e Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 31 Oct 2012 21:13:01 -0400 Subject: [PATCH 735/746] Fix accidental use of the wrong letrec-bound variable. (cherry picked from commit 0e71f2d5dc58bd497a686f23c0ed0781590a3dc6) --- collects/tests/typed-racket/succeed/exn-any.rkt | 15 +++++++++++++++ collects/typed-racket/utils/any-wrap.rkt | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 collects/tests/typed-racket/succeed/exn-any.rkt diff --git a/collects/tests/typed-racket/succeed/exn-any.rkt b/collects/tests/typed-racket/succeed/exn-any.rkt new file mode 100644 index 0000000000..131aec6e28 --- /dev/null +++ b/collects/tests/typed-racket/succeed/exn-any.rkt @@ -0,0 +1,15 @@ +#lang racket/load + +(module m typed/racket + (struct: s ()) + + (struct: s2 s ()) + (define: v : Any (s2)) + (provide v)) + +(module n racket + (require 'm) + v) + +(require 'n) + diff --git a/collects/typed-racket/utils/any-wrap.rkt b/collects/typed-racket/utils/any-wrap.rkt index 4699ad75bb..dfb4505807 100644 --- a/collects/typed-racket/utils/any-wrap.rkt +++ b/collects/typed-racket/utils/any-wrap.rkt @@ -12,7 +12,7 @@ (define (wrap-struct s) (define (extract-functions struct-type) (define-values (sym init auto ref set! imms par skip?) - (struct-type-info type)) + (struct-type-info struct-type)) (when skip? (fail s)) ;; "Opaque struct type!") (define-values (fun/chap-list _) (for/fold ([res null] @@ -34,7 +34,7 @@ res) imms)))) (cond - [par (cons fun/chap-list (extract-functions par))] + [par (append fun/chap-list (extract-functions par))] [else fun/chap-list])) (define-values (type skipped?) (struct-info s)) (when skipped? (fail s)); "Opaque struct type!" From f72e2b6f02ea67e46a5a9a19faaca009209b5505 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Wed, 31 Oct 2012 21:39:16 -0400 Subject: [PATCH 736/746] Fix binding of `udp?`. (cherry picked from commit f2fd47905f4fe981dea4bda03fd08bd930dc63a1) --- collects/typed-racket/types/abbrev.rkt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/collects/typed-racket/types/abbrev.rkt b/collects/typed-racket/types/abbrev.rkt index cadae87bee..517b645184 100644 --- a/collects/typed-racket/types/abbrev.rkt +++ b/collects/typed-racket/types/abbrev.rkt @@ -14,12 +14,11 @@ ;; avoid the other dependencies of `racket/place` '#%place unstable/function - racket/udp unstable/lazy-require (except-in racket/contract/base ->* -> one-of/c) (prefix-in c: racket/contract/base) (for-syntax racket/base syntax/parse racket/list) - (for-template racket/base racket/contract/base racket/promise racket/tcp racket/flonum) + (for-template racket/base racket/contract/base racket/promise racket/tcp racket/flonum racket/udp) racket/pretty racket/udp ;; for base type predicates racket/promise racket/tcp racket/flonum) From f8a0be011615b796fe7ce75ec29336831433852c Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Tue, 30 Oct 2012 13:42:20 -0400 Subject: [PATCH 737/746] Correct TR types for udp-bind! and udp-connect!. (cherry picked from commit a57e158c43b25fac9803cb1af399e53b97144df0) --- collects/typed-racket/base-env/base-env.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/typed-racket/base-env/base-env.rkt b/collects/typed-racket/base-env/base-env.rkt index 6f9b4754eb..fcb090e39d 100644 --- a/collects/typed-racket/base-env/base-env.rkt +++ b/collects/typed-racket/base-env/base-env.rkt @@ -1484,8 +1484,8 @@ ;;racket/udp [udp-open-socket (->opt [(-opt -String) (-opt -String)] -UDP-Socket)] -[udp-bind! (-> -UDP-Socket (-opt -String) -PosInt)] -[udp-connect! (-> -UDP-Socket (-opt -String) -PosInt)] +[udp-bind! (-> -UDP-Socket (-opt -String) -Nat -Void)] +[udp-connect! (-> -UDP-Socket (-opt -String) (-opt -Nat) -Void)] [udp-send-to (->opt -UDP-Socket -String -Nat -Bytes [-Nat -Nat] -Void)] [udp-send (->opt -UDP-Socket -Bytes [-Nat -Nat] -Void)] From 6be04963076cad28fe6b2997f77b1ce73ca633f1 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 1 Nov 2012 07:19:19 -0600 Subject: [PATCH 738/746] fix problem with places and `struct-type-info' Merge to v5.3.1 (cherry picked from commit 0e4305fc45c457824936607f61d06bbe8b4ea02c) --- collects/tests/racket/place-struct-info.rkt | 20 +++++++++++++++ src/racket/src/error.c | 1 + src/racket/src/schpriv.h | 2 ++ src/racket/src/struct.c | 27 ++++++++++++--------- 4 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 collects/tests/racket/place-struct-info.rkt diff --git a/collects/tests/racket/place-struct-info.rkt b/collects/tests/racket/place-struct-info.rkt new file mode 100644 index 0000000000..fcb2fa9301 --- /dev/null +++ b/collects/tests/racket/place-struct-info.rkt @@ -0,0 +1,20 @@ +#lang racket/base +(require racket/place) + +;; Some results from `struct-type-info' may be created on demand. +;; Check that any sharing of `struct:exn' across places handles +;; that on-demand creation correctly. + +(define (go) + (place + pch + (define-values (sym init auto ref set! imms par skip?) + (struct-type-info struct:exn)) + (unless (procedure? ref) + (error "bad reference procedure")) + (collect-garbage))) + +(module+ main + (void (place-wait (go))) + (collect-garbage) + (void (place-wait (go)))) diff --git a/src/racket/src/error.c b/src/racket/src/error.c index 837ac566ce..cd1a7aec90 100644 --- a/src/racket/src/error.c +++ b/src/racket/src/error.c @@ -4313,6 +4313,7 @@ void scheme_init_exn(Scheme_Env *env) if (exn_table[i].count) { Scheme_Object **values; + scheme_force_struct_type_info((Scheme_Struct_Type *)exn_table[i].type); values = scheme_make_struct_values(exn_table[i].type, exn_table[i].names, exn_table[i].count, diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index 9e5a1e27af..e924d9476b 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -851,6 +851,8 @@ Scheme_Object *scheme_make_serialized_struct_instance(Scheme_Object *s, int num_ Scheme_Object *scheme_struct_getter(int argc, Scheme_Object **args, Scheme_Object *prim); Scheme_Object *scheme_struct_setter(int argc, Scheme_Object **args, Scheme_Object *prim); +void scheme_force_struct_type_info(Scheme_Struct_Type *stype); + Scheme_Object *scheme_extract_checked_procedure(int argc, Scheme_Object **argv); Scheme_Object *scheme_rename_struct_proc(Scheme_Object *p, Scheme_Object *sym); diff --git a/src/racket/src/struct.c b/src/racket/src/struct.c index bfa0c73ffd..db193d4f2f 100644 --- a/src/racket/src/struct.c +++ b/src/racket/src/struct.c @@ -2627,18 +2627,8 @@ static Scheme_Object *check_type_and_inspector(const char *who, int always, int return insp; } -static void get_struct_type_info(int argc, Scheme_Object *argv[], Scheme_Object **a, int always) +void scheme_force_struct_type_info(Scheme_Struct_Type *stype) { - Scheme_Struct_Type *stype, *parent; - Scheme_Object *insp, *ims; - int p, cnt; - - insp = check_type_and_inspector("struct-type-info", always, argc, argv); - if (SCHEME_NP_CHAPERONEP(argv[0])) - stype = (Scheme_Struct_Type *)SCHEME_CHAPERONE_VAL(argv[0]); - else - stype = (Scheme_Struct_Type *)argv[0]; - /* Make sure generic accessor and mutator are created: */ if (!stype->accessor) { Scheme_Object *p; @@ -2651,6 +2641,21 @@ static void get_struct_type_info(int argc, Scheme_Object *argv[], Scheme_Object p = make_struct_proc(stype, fn, SCHEME_GEN_SETTER, 0); stype->mutator = p; } +} + +static void get_struct_type_info(int argc, Scheme_Object *argv[], Scheme_Object **a, int always) +{ + Scheme_Struct_Type *stype, *parent; + Scheme_Object *insp, *ims; + int p, cnt; + + insp = check_type_and_inspector("struct-type-info", always, argc, argv); + if (SCHEME_NP_CHAPERONEP(argv[0])) + stype = (Scheme_Struct_Type *)SCHEME_CHAPERONE_VAL(argv[0]); + else + stype = (Scheme_Struct_Type *)argv[0]; + + scheme_force_struct_type_info(stype); if (stype->name_pos) parent = stype->parent_types[stype->name_pos - 1]; From 0565935eb264285f8aa7d43e214f354d431a4ba9 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 1 Nov 2012 12:15:26 -0400 Subject: [PATCH 739/746] Replace #lang scheme deprecation notice with a pointer to #lang racket. (cherry picked from commit ee97c08e0a0428555e4ecf3547978f7bb95b0a6b) --- collects/scribblings/scheme/scheme.scrbl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/scribblings/scheme/scheme.scrbl b/collects/scribblings/scheme/scheme.scrbl index 845171971f..553ac7cd7c 100644 --- a/collects/scribblings/scheme/scheme.scrbl +++ b/collects/scribblings/scheme/scheme.scrbl @@ -60,7 +60,8 @@ Racket was once called ``PLT Scheme,'' and a number of libraries with names starting @racketidfont{scheme} provide compatibility with the old name. A few @seclink["compat-exe"]{old executables} are also provided. -@deprecated[@racketmodname[racket]]{} +Do not use @racketmodfont{#lang} @racketmodname[scheme] to start new projects; +@racketmodfont{#lang} @racketmodname[racket] is the preferred language. @table-of-contents[] From 8f6397bf0710174d701514c38d9ffe19c752d9e8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 2 Nov 2012 12:56:09 -0600 Subject: [PATCH 740/746] fix locking for futures on uniprocessors The scheme_is_multiprocessor() function wasn't the right guard for whether to use a locking compare-and-swap instruction; any use of pthread-based futures needs the compare-and-swap. Merge to v5.3.1 (cherry picked from commit 55170581c4179d37d42c6e0975b290ee08dd14d0) --- src/racket/src/future.c | 19 ++++++++----------- src/racket/src/hash.c | 4 +--- src/racket/src/jitcommon.c | 4 ++-- src/racket/src/jitinline.c | 2 +- src/racket/src/schpriv.h | 2 +- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/racket/src/future.c b/src/racket/src/future.c index 58babfef63..a6d283544d 100644 --- a/src/racket/src/future.c +++ b/src/racket/src/future.c @@ -156,7 +156,7 @@ static Scheme_Object *processor_count(int argc, Scheme_Object *argv[]) return scheme_make_integer(1); } -int scheme_is_multiprocessor(int now) +int scheme_is_multithreaded(int now) { return 0; } @@ -2185,17 +2185,14 @@ static void init_cpucount(void) #endif } -int scheme_is_multiprocessor(int now) +int scheme_is_multithreaded(int now) { - if (cpucount > 1) { - if (!now) - return 1; - else { - Scheme_Future_State *fs = scheme_future_state; - return (fs && fs->future_threads_created); - } - } else - return 0; + if (!now) + return 1; + else { + Scheme_Future_State *fs = scheme_future_state; + return (fs && fs->future_threads_created); + } } Scheme_Object *processor_count(int argc, Scheme_Object *argv[]) diff --git a/src/racket/src/hash.c b/src/racket/src/hash.c index 3df6636489..58ebf57d30 100644 --- a/src/racket/src/hash.c +++ b/src/racket/src/hash.c @@ -61,8 +61,6 @@ static void register_traversers(void); running in a future and setting flags on pairs. */ SHARED_OK static uintptr_t keygen; -XFORM_NONGCING extern int scheme_is_multiprocessor(); - XFORM_NONGCING static MZ_INLINE uintptr_t PTR_TO_LONG(Scheme_Object *o) { @@ -92,7 +90,7 @@ uintptr_t PTR_TO_LONG(Scheme_Object *o) #endif if (!v) v = 0x1AD0; #ifdef MZ_USE_FUTURES - if (SCHEME_PAIRP(o) && scheme_is_multiprocessor(1)) { + if (SCHEME_PAIRP(o) && scheme_is_multithreaded(1)) { /* Use CAS to avoid losing a hash code due to a conflict with JIT-generated `list?' test, which itself uses CAS to set "is a list" or "not a list" flags on pairs. */ diff --git a/src/racket/src/jitcommon.c b/src/racket/src/jitcommon.c index b2fa5444eb..1bf70cf146 100644 --- a/src/racket/src/jitcommon.c +++ b/src/racket/src/jitcommon.c @@ -2349,7 +2349,7 @@ static int common7(mz_jit_state *jitter, void *_data) jit_ldxi_s(JIT_R2, JIT_R1, &MZ_OPT_HASH_KEY(&((Scheme_Stx *)0x0)->iso)); #ifdef MZ_USE_FUTURES - if (scheme_is_multiprocessor(0)) { + if (scheme_is_multithreaded(0)) { /* Need an atomic update in case another thread is setting a hash code on the target pair. */ ref5 = jit_bmsi_i(jit_forward(), JIT_R2, PAIR_IS_LIST); @@ -2386,7 +2386,7 @@ static int common7(mz_jit_state *jitter, void *_data) jit_ldxi_s(JIT_R2, JIT_R1, &MZ_OPT_HASH_KEY(&((Scheme_Stx *)0x0)->iso)); #ifdef MZ_USE_FUTURES /* As above: */ - if (scheme_is_multiprocessor(0)) { + if (scheme_is_multithreaded(0)) { ref5 = jit_bmsi_i(jit_forward(), JIT_R2, PAIR_IS_NON_LIST); jit_movr_i(JIT_R0, JIT_R2); jit_ori_i(JIT_R2, JIT_R2, PAIR_IS_NON_LIST); diff --git a/src/racket/src/jitinline.c b/src/racket/src/jitinline.c index c14af07bec..45f3257401 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -2883,7 +2883,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int /* This is the actual CAS: */ #ifdef MZ_USE_FUTURES - if (scheme_is_multiprocessor(0)) { + if (scheme_is_multithreaded(0)) { jit_lock_cmpxchgr_l(JIT_R1, JIT_V1); /* implicitly uses JIT_R0 */ reffalse = (JNEm(jit_forward(), 0,0,0), _jit.x.pc); } else diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index e924d9476b..547bad1b46 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -303,7 +303,7 @@ void scheme_free_dynamic_extensions(void); void scheme_free_all_code(void); void scheme_free_ghbn_data(void); -XFORM_NONGCING int scheme_is_multiprocessor(int now); +XFORM_NONGCING int scheme_is_multithreaded(int now); /* Type readers & writers for compiled code data */ typedef Scheme_Object *(*Scheme_Type_Reader)(Scheme_Object *list); From 9fb2a5b5ff713cc3308fd39a460ee262ab29c425 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Fri, 2 Nov 2012 15:35:05 -0400 Subject: [PATCH 741/746] Typed Racket HISTORY. (cherry picked from commit 6f1f04f99c919bc7e877214f8bb98b5159a38e27) --- doc/release-notes/typed-racket/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes/typed-racket/HISTORY.txt b/doc/release-notes/typed-racket/HISTORY.txt index 42577848d0..67868c2269 100644 --- a/doc/release-notes/typed-racket/HISTORY.txt +++ b/doc/release-notes/typed-racket/HISTORY.txt @@ -1,3 +1,7 @@ +5.3.1 +- Revised handling of `Any` exported to untyped code +- Added `cast` +- Correctly compute variance of polymorphic type application 5.3 - Keyword and optional arguments - Faster startup From 67711f53da3d236cb17b59a67011110480218268 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 3 Nov 2012 07:10:33 -0600 Subject: [PATCH 742/746] fix problem with prompts, call/cc, and tail-buffer allocation Merge to v5.3.1 (cherry picked from commit 8079ff6c4f7a1deb0d7b5779cf6b2fd44cebb4d6) --- src/racket/gc2/newgc.c | 21 +++++++++++++++++++++ src/racket/src/eval.c | 2 ++ src/racket/src/fun.c | 13 +++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/racket/gc2/newgc.c b/src/racket/gc2/newgc.c index 3246bca34a..8f59726af8 100644 --- a/src/racket/gc2/newgc.c +++ b/src/racket/gc2/newgc.c @@ -1280,6 +1280,21 @@ inline static uintptr_t allocate_slowpath(NewGC *gc, size_t allocate_size, uintp return newptr; } +static void check_allocation_time_invariants() +{ +#if 0 + Scheme_Thread *p = scheme_current_thread; + if (p) { + if (p->values_buffer) { + memset(p->values_buffer, 0, sizeof(Scheme_Object*) * p->values_buffer_size); + } + if (p->tail_buffer && (p->tail_buffer != p->runstack_tmp_keep)) { + memset(p->tail_buffer, 0, sizeof(Scheme_Object*) * p->tail_buffer_size); + } + } +#endif +} + inline static void *allocate(const size_t request_size, const int type) { size_t allocate_size; @@ -1287,6 +1302,8 @@ inline static void *allocate(const size_t request_size, const int type) if(request_size == 0) return (void *) zero_sized; + check_allocation_time_invariants(); + allocate_size = COMPUTE_ALLOC_SIZE_FOR_OBJECT_SIZE(request_size); if(allocate_size > MAX_OBJECT_SIZE) return allocate_big(request_size, type); @@ -1338,6 +1355,8 @@ inline static void *fast_malloc_one_small_tagged(size_t request_size, int dirty) uintptr_t newptr; const size_t allocate_size = COMPUTE_ALLOC_SIZE_FOR_OBJECT_SIZE(request_size); + check_allocation_time_invariants(); + newptr = GC_gen0_alloc_page_ptr + allocate_size; if(OVERFLOWS_GEN0(newptr)) { @@ -1371,6 +1390,8 @@ void *GC_malloc_pair(void *car, void *cdr) void *pair; const size_t allocate_size = PAIR_SIZE_IN_BYTES; + check_allocation_time_invariants(); + newptr = GC_gen0_alloc_page_ptr + allocate_size; if(OVERFLOWS_GEN0(newptr)) { diff --git a/src/racket/src/eval.c b/src/racket/src/eval.c index 14c2b22409..21c5a19428 100644 --- a/src/racket/src/eval.c +++ b/src/racket/src/eval.c @@ -1580,6 +1580,8 @@ Scheme_Object *scheme_jump_to_continuation(Scheme_Object *obj, int num_rands, Sc else { GC_CAN_IGNORE Scheme_Object *vals; vals = scheme_values(num_rands, (Scheme_Object **)value); + if (SAME_OBJ(p->ku.multiple.array, p->values_buffer)) + p->values_buffer = NULL; c->value = vals; } diff --git a/src/racket/src/fun.c b/src/racket/src/fun.c index a453aae645..d3ba7a5d3e 100644 --- a/src/racket/src/fun.c +++ b/src/racket/src/fun.c @@ -6368,6 +6368,11 @@ static Scheme_Object *call_with_prompt (int in_argc, Scheme_Object *in_argv[]) p = scheme_current_thread; + if (v == SCHEME_MULTIPLE_VALUES) { + if (SAME_OBJ(p->ku.multiple.array, p->values_buffer)) + p->values_buffer = NULL; + } + restore_from_prompt(prompt); p->suspend_break = 0; @@ -6392,6 +6397,10 @@ static Scheme_Object *call_with_prompt (int in_argc, Scheme_Object *in_argv[]) if (v) { /* Got a result: */ + if (v == SCHEME_MULTIPLE_VALUES) { + if (SAME_OBJ(p->ku.multiple.array, p->values_buffer)) + p->values_buffer = NULL; + } prompt_unwind_one_dw(prompt_tag); handler = NULL; } else { @@ -6456,6 +6465,10 @@ static Scheme_Object *call_with_prompt (int in_argc, Scheme_Object *in_argv[]) if (SAME_OBJ(handler, scheme_values_func)) { v = scheme_values(argc, argv); + if (v == SCHEME_MULTIPLE_VALUES) { + if (SAME_OBJ(p->ku.multiple.array, p->values_buffer)) + p->values_buffer = NULL; + } handler = NULL; } else if (SCHEME_FALSEP(handler)) { if (argc == 1) { From 5c79d60eb4ab9aa3a84498920c308471bb2458a7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 3 Nov 2012 08:23:13 -0600 Subject: [PATCH 743/746] fix test to not depend on network connection (cherry picked from commit 4c61dfc2170d10a16391022f47ad824bc542cb56) --- collects/tests/racket/udp.rktl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/tests/racket/udp.rktl b/collects/tests/racket/udp.rktl index ce4d45331b..6e1107d92f 100644 --- a/collects/tests/racket/udp.rktl +++ b/collects/tests/racket/udp.rktl @@ -184,7 +184,7 @@ (let () (define (q) (define s (udp-open-socket #f #f)) - (udp-bind! s #f 5999) + (udp-bind! s "127.0.0.1" 5999) s) (define s (q)) From 2b660869687cd15d5705e68eff2c2fefe31d37f9 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 6 Nov 2012 05:29:56 -0500 Subject: [PATCH 744/746] Update version number for the v5.3.1 release --- src/racket/src/schvers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 2199536996..23b5348468 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.3.0.900" +#define MZSCHEME_VERSION "5.3.1" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 3 -#define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 900 +#define MZSCHEME_VERSION_Z 1 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 4dc07782f68e4a6740593188555cfc645f635557 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 6 Nov 2012 05:45:19 -0500 Subject: [PATCH 745/746] New Racket version 5.3.1. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index de8fc6cc6f..171449d719 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 3f0feaef7c..e5ca7c33bd 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,900 - PRODUCTVERSION 5,3,0,900 + FILEVERSION 5,3,1,0 + PRODUCTVERSION 5,3,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 3, 0, 900\0" + VALUE "FileVersion", "5, 3, 1, 0\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 3, 0, 900\0" + VALUE "ProductVersion", "5, 3, 1, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 951d2dc30a..5c649f298c 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,900 - PRODUCTVERSION 5,3,0,900 + FILEVERSION 5,3,1,0 + PRODUCTVERSION 5,3,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 3, 0, 900" + VALUE "FileVersion", "5, 3, 1, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2012 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 3, 0, 900" + VALUE "ProductVersion", "5, 3, 1, 0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index a83a172b08..43ee209cb0 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.3.0.900 = s 'MzObj Class' + MzCOM.MzObj.5.3.1.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.3.0.900' + CurVer = s 'MzCOM.MzObj.5.3.1.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.3.0.900' + ProgID = s 'MzCOM.MzObj.5.3.1.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 9a9c3dad00..67efa5d49b 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 2bed428fef..66001259f0 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,900 - PRODUCTVERSION 5,3,0,900 + FILEVERSION 5,3,1,0 + PRODUCTVERSION 5,3,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 3, 0, 900\0" + VALUE "FileVersion", "5, 3, 1, 0\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 3, 0, 900\0" + VALUE "ProductVersion", "5, 3, 1, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 7a827c12aa..81656a3293 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,900 - PRODUCTVERSION 5,3,0,900 + FILEVERSION 5,3,1,0 + PRODUCTVERSION 5,3,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 3, 0, 900\0" + VALUE "FileVersion", "5, 3, 1, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 3, 0, 900\0" + VALUE "ProductVersion", "5, 3, 1, 0\0" END END BLOCK "VarFileInfo" From 2f4c677441008c83d5f2529cd1247db74ae3d3d8 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 7 Nov 2012 14:50:24 -0500 Subject: [PATCH 746/746] v5.3.1 stuff (cherry picked from commit d15059ada7882d5139e1df713e156e25f91b11ca) --- collects/meta/web/download/installers.txt | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index 7b1a4f721e..499c65c725 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -212,6 +212,30 @@ 16601808 5.2/racket/racket-5.2-src-mac.dmg 16260740 5.2/racket/racket-5.2-src-unix.tgz 19575041 5.2/racket/racket-5.2-src-win.zip +11552351 5.3.1/racket-textual/racket-textual-5.3.1-bin-i386-linux-f12.sh +11570689 5.3.1/racket-textual/racket-textual-5.3.1-bin-i386-linux-ubuntu-karmic.sh +12143855 5.3.1/racket-textual/racket-textual-5.3.1-bin-i386-osx-mac.dmg +8803203 5.3.1/racket-textual/racket-textual-5.3.1-bin-i386-win32.exe +12081255 5.3.1/racket-textual/racket-textual-5.3.1-bin-ppc-osx-mac.dmg +11748331 5.3.1/racket-textual/racket-textual-5.3.1-bin-x86_64-linux-debian-squeeze.sh +11757467 5.3.1/racket-textual/racket-textual-5.3.1-bin-x86_64-linux-f14.sh +12278659 5.3.1/racket-textual/racket-textual-5.3.1-bin-x86_64-osx-mac.dmg +9171125 5.3.1/racket-textual/racket-textual-5.3.1-bin-x86_64-win32.exe +6254337 5.3.1/racket-textual/racket-textual-5.3.1-src-mac.dmg +6134415 5.3.1/racket-textual/racket-textual-5.3.1-src-unix.tgz +7252130 5.3.1/racket-textual/racket-textual-5.3.1-src-win.zip +64527997 5.3.1/racket/racket-5.3.1-bin-i386-linux-f12.sh +64562401 5.3.1/racket/racket-5.3.1-bin-i386-linux-ubuntu-karmic.sh +67179194 5.3.1/racket/racket-5.3.1-bin-i386-osx-mac.dmg +43655604 5.3.1/racket/racket-5.3.1-bin-i386-win32.exe +67981764 5.3.1/racket/racket-5.3.1-bin-ppc-osx-mac.dmg +64911589 5.3.1/racket/racket-5.3.1-bin-x86_64-linux-debian-squeeze.sh +64927156 5.3.1/racket/racket-5.3.1-bin-x86_64-linux-f14.sh +67721160 5.3.1/racket/racket-5.3.1-bin-x86_64-osx-mac.dmg +44343519 5.3.1/racket/racket-5.3.1-bin-x86_64-win32.exe +19042596 5.3.1/racket/racket-5.3.1-src-mac.dmg +18296513 5.3.1/racket/racket-5.3.1-src-unix.tgz +21668825 5.3.1/racket/racket-5.3.1-src-win.zip 11235593 5.3/racket-textual/racket-textual-5.3-bin-i386-linux-f12.sh 11248024 5.3/racket-textual/racket-textual-5.3-bin-i386-linux-ubuntu-karmic.sh 11806657 5.3/racket-textual/racket-textual-5.3-bin-i386-osx-mac.dmg

~M}M;6&JEwVICl0at#t1Au|u3Zd59#MPP9pOC2{2i z%jucXs<}CiBIo$=gM`5}Noz8|sLvan4%tro=I(hzP7qpnUV}JJNRoufi3t%!lk?zuDma9En`696s$=yO6^ zpG@MZ(N=ISj9U|09<J7qh zGV&XfMyd3N7OgKE2*9Bss5V@Q&aVt$j8)1DWXdL;j$hWOLlX3gsw|aO) z?0@HHCW$A`Hob#O06NO+KPRR0)l%mzh5I%?jBPozq6mXPr3&+|3xojMwh#hbH$xOf z?0W4b8nZ`yW5O?0FKzjU_V%6krhhtJiPlxE)vho+eGx$93PXXLU67M9hc+$Z)@T?s zkL5eM);%PJ{d}o&Ret@35g_HBO&PX4xP@A^$}`{i4?M4r&dy6b{nvlYK)H>7{LT)3 zv0Ea9gJmg3HaXn3YMFWM)mJ8;{=%ORTy0X27`_*^#{4)Mi{fa^mr{JMqkm)gCV_Z9 z-?l72JiHOl^O&8ju=j$p|V28nprwWCeUs9@hyR@zS&HAyQc9hrd%((M1%a^ZVY-}8*6~&^# zw&(U%6Y%{IuVJt(_cz7rb$_2m(?g}uXeh?V#uzBwOts<*gZLKk$W;J<_We_@0c-QUcs#Ve} z@=_qV3ISTc*w`pqOP>4w9-jKd-%+pUaWY*wDXnc+=3nb|yhvJks?{2nm7!iw`PSFJ zOM6F#CqK2Fo62Q&?SI|Jf4%%BTEqH{Lp-weBly6x&wPjJseoG5Lu;4u@iw$pByosk z7eKJ+`T$0CNSOgZ2tlRd^7^iT#fuv>8cil#mkZ~|*!|xjMoWg4H<$`T>h(JBygkjS zQyCzOF%kg?G(rfZbP*kv8_NH#{^BE zG!vDUn-FSR`TfRp0)qG7m1AIjALXtLwryis7Rzs0$^#Dy zY+JH?#ZrthbaZxb*WHWpyp+9r#+jbZqO}5J&|0BVAB?HohyrJo3j2*w2qCz0?IIp{ zcq_i|BZNR}&418}rEJ`ACn->`*U?%dEsMt7OICSva$cl|I27^KC1f>GBF=ws| zpp|+-rQT|zlRQA2#9W%5#&#Ssj)M_`R;xv`(Le}+lgVI7NvagS?-Tew0*RD1TBjJJ z(K;ec>b}s)j_U$AmVQ|&|C>trKqq_OJk9BoHEtg2=6|01K8VqpAHVz>Q&TCKOv8&6CzWUb%0O;->9>6Yq-Lai*nQU2Q-JYVIDPh}Lz@X9=aqJOAm1f+kT4@^n zn@QuptW@5fxL)lW0(dXld)F;;l=%Z;x!Z(g4+=ylfI-g~m0naT*{LjkRG*srEWeTX YUw3=@i$pBkasU7T07*qoM6N<$f()S)Z~y=R delta 2619 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/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (make-cached-flomap + [height color material] + (define (draw-hash-quote dc) + ;; vertical lines + (send dc draw-polygon '((6 . 0) (11 . 0) (9 . 30) (4 . 30))) + (send dc draw-polygon '((17 . 0) (22 . 0) (20 . 30) (15 . 30))) + ;; horizontal lines + (send dc draw-polygon '((1 . 6.5) (26 . 6.5) (26 . 11.5) (1 . 11.5))) + (send dc draw-polygon '((0 . 18.5) (25 . 18.5) (25 . 23.5) (0 . 23.5))) + ;; quote + (send dc draw-polygon '((30 . 0) (34 . 0) (33 . 9) (30 . 9)))) + + (define outline-color (icon-color->outline-color color)) + + (draw-rendered-icon-flomap + 36 32 (λ (dc) + (send dc translate 0.5 0.5) + (set-icon-pen dc outline-color 2 'solid) + (send dc set-brush outline-color 'solid) + (draw-hash-quote dc) + (send dc set-pen "black" 1 'transparent) + (send dc set-brush color 'solid) + (draw-hash-quote dc)) + (/ height 32) + material))) + ;; =================================================================================================== ;; Bitmaps (icons) @@ -257,4 +287,5 @@ [recycle-icon recycle-flomap] [x-icon x-flomap] [check-icon check-flomap] - [lambda-icon lambda-flomap]) + [lambda-icon lambda-flomap] + [hash-quote-icon hash-quote-flomap]) diff --git a/collects/images/icons/tool.rkt b/collects/images/icons/tool.rkt index 47534a52d1..5f101bea38 100644 --- a/collects/images/icons/tool.rkt +++ b/collects/images/icons/tool.rkt @@ -12,6 +12,7 @@ (provide debugger-bomb-color macro-stepper-hash-color + small-macro-stepper-hash-color (activate-contract-out check-syntax-icon check-syntax-flomap small-check-syntax-icon small-check-syntax-flomap @@ -25,9 +26,10 @@ (make-object color% 128 32 32)) ;; Actual color is too dark after rendering -;(define macro-stepper-hash-color (make-object color% 30 96 30)) (defthing macro-stepper-hash-color (or/c string? (is-a?/c color%)) #:document-value - (make-object color% 90 192 90)) + (make-object color% 60 192 60)) +(defthing small-macro-stepper-hash-color (or/c string? (is-a?/c color%)) #:document-value + (make-object color% 128 255 128)) (defproc (check-syntax-flomap [height (and/c rational? (>=/c 0)) (toolbar-icon-height)] [material deep-flomap-material-value? (default-icon-material)] @@ -49,8 +51,7 @@ [material deep-flomap-material-value? (default-icon-material)] ) flomap? (flomap-ht-append - (text-flomap "#'" (make-object font% (max 1 (min 1024 height)) 'system) - macro-stepper-hash-color #t 'auto height material) + (hash-quote-flomap macro-stepper-hash-color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/32 height)))) 0) (step-flomap syntax-icon-color height material))) @@ -60,8 +61,7 @@ (flomap-pin* 0 0 7/16 0 (step-flomap syntax-icon-color height material) - (text-flomap "#'" (make-object font% (max 1 (min 1024 height)) 'system) - macro-stepper-hash-color #t 'auto (* 3/4 height) material))) + (hash-quote-flomap small-macro-stepper-hash-color (* 3/4 height) material))) (defproc (debugger-flomap [height (and/c rational? (>=/c 0)) (toolbar-icon-height)] [material deep-flomap-material-value? (default-icon-material)] diff --git a/collects/images/logos.rkt b/collects/images/logos.rkt index 10cfe4b5ad..05cb4cbd76 100644 --- a/collects/images/logos.rkt +++ b/collects/images/logos.rkt @@ -298,33 +298,10 @@ (lambda-flomap light-metal-icon-color (* 5/8 height) metal-icon-material))) (defproc (macro-stepper-logo-flomap [height (and/c rational? (>=/c 0)) 96]) flomap? - (define outline-color (icon-color->outline-color light-metal-icon-color)) - - (define (draw-hash-quote dc) - ;; vertical lines - (send dc draw-polygon '((5 . 0) (8 . 0) (6 . 19) (3 . 19))) - (send dc draw-polygon '((12 . 0) (15 . 0) (13 . 19) (10 . 19))) - ;; horizontal lines - (send dc draw-polygon '((1 . 4) (1 . 7) (18 . 7) (18 . 4))) - (send dc draw-polygon '((0 . 12) (0 . 15) (17 . 15) (17 . 12))) - ;; quote - (send dc draw-polygon '((20 . 0) (23 . 0) (22.75 . 6) (20.25 . 6))) - ) - (flomap-pin* - 1/2 20/32 1/2 1/2 + 1/2 20/32 15/36 1/2 (foot-flomap (make-object color% 34 42 160) height glass-icon-material) - (draw-rendered-icon-flomap - 32 32 (λ (dc) - (send dc translate 5 6) - (set-icon-pen dc outline-color 2 'solid) - (send dc set-brush outline-color 'solid) - (draw-hash-quote dc) - (send dc set-pen "black" 1 'transparent) - (send dc set-brush light-metal-icon-color 'solid) - (draw-hash-quote dc)) - (/ (* 3/4 height) 32) - metal-icon-material))) + (hash-quote-flomap light-metal-icon-color (* 1/2 height) metal-icon-material))) (define-icon-wrappers ([height (and/c rational? (>=/c 0)) 256]) diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl index 811fce839b..e4ab2ce3d1 100644 --- a/collects/images/scribblings/icons.scrbl +++ b/collects/images/scribblings/icons.scrbl @@ -45,8 +45,7 @@ Its shape and color are a visual metaphor for an action or a message. Icons should be @bold{easily recognizable}, @bold{distinguishable}, @bold{visually consistent}, and @bold{metaphorically appropriate} for the actions and messages they are used with. It can be difficult to meet all four requirements at once (``distinguishable'' and ``visually consistent' are often at odds), but good examples, good abstractions, and an existing icon library help considerably. -@(define (hash-quote) (text-icon "#'" (make-object font% 32 'system) - macro-stepper-hash-color #t 'auto 16)) +@(define (hash-quote) (hash-quote-icon macro-stepper-hash-color 16)) @(define (step) (step-icon syntax-icon-color 16)) @(define (play) (play-icon syntax-icon-color 16)) @(define (bar) (bar-icon syntax-icon-color 16)) @@ -283,7 +282,7 @@ Renders a text string as an icon. For example, @interaction[#:eval icons-eval (text-icon "An Important Point!" (make-object font% 48 'decorative 'normal 'bold #t) - "lightskyblue" #t 2 48)] + "lightskyblue" #t 'auto 48)] Before rendering, the drawn text is scaled so that it is exactly @racket[height] pixels tall. Make sure the font is large enough that scaling does not create blurry and jagged edge artifacts, as in the following example: @@ -329,6 +328,12 @@ Returns an ``x'' icon that is guaranteed to look the same on all platforms. (lambda-icon light-metal-icon-color 32 metal-icon-material)] } +@doc-apply[hash-quote-icon]{ +@examples[#:eval icons-eval + (require (only-in images/icons/tool macro-stepper-hash-color)) + (hash-quote-icon macro-stepper-hash-color 32)] +} + @;==================================================================================================== @section[#:tag "misc"]{Miscellaneous Icons} @@ -443,6 +448,7 @@ Icons for the Debugger. The @racket[small-debugger-icon] is used when the toolba } @doc-apply[debugger-bomb-color] -@doc-apply[macro-stepper-hash-color]{ +@doc-apply[macro-stepper-hash-color] +@doc-apply[small-macro-stepper-hash-color]{ Constants used within @racketmodname[images/icons/tool]. } diff --git a/collects/images/scribblings/logos.scrbl b/collects/images/scribblings/logos.scrbl index 8701378f93..11881f74a8 100644 --- a/collects/images/scribblings/logos.scrbl +++ b/collects/images/scribblings/logos.scrbl @@ -30,11 +30,11 @@ Returns an unofficial PLaneT logo. This is used as the PLaneT icon when DrRacket } @doc-apply[stepper-logo]{ -An algebraic stepper logo. +Returns the algebraic stepper logo. @examples[#:eval logos-eval (stepper-logo)] } @doc-apply[macro-stepper-logo]{ -A macro stepper logo. +Returns the macro stepper logo. @examples[#:eval logos-eval (macro-stepper-logo)] } diff --git a/collects/images/tests/icon-tests.rkt b/collects/images/tests/icon-tests.rkt index 2ffe7b9f01..f43a66d245 100644 --- a/collects/images/tests/icon-tests.rkt +++ b/collects/images/tests/icon-tests.rkt @@ -48,7 +48,7 @@ (λ (color) (load-icon syntax-icon-color color)) (λ (color) (small-save-icon syntax-icon-color color)) (λ (color) (small-load-icon syntax-icon-color color))) - (list x-icon check-icon recycle-icon lambda-icon) + (list x-icon check-icon recycle-icon lambda-icon hash-quote-icon) (list octagon-icon stop-sign-icon stop-signs-icon foot-icon (λ (color) (magnifying-glass-icon metal-icon-color color)) (λ (color) (left-magnifying-glass-icon metal-icon-color color)) From 7b0e86718fe7ec00570d51a2c5d892a5cd8442c8 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Fri, 20 Jan 2012 16:38:58 -0500 Subject: [PATCH 522/746] added rcontrol to key events and docs; robby please test (cherry picked from commit 1d9d0401df53682b5e5057d1ea2b94d8787531a4) --- collects/2htdp/universe.rkt | 1 + collects/teachpack/2htdp/scribblings/universe.scrbl | 1 + 2 files changed, 2 insertions(+) diff --git a/collects/2htdp/universe.rkt b/collects/2htdp/universe.rkt index 7a2858b993..7a31f1a956 100644 --- a/collects/2htdp/universe.rkt +++ b/collects/2htdp/universe.rkt @@ -213,6 +213,7 @@ "shift" "rshift" "control" + "rcontrol" "menu" "pause" "capital" diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index 8c2cc448f1..275fd09112 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -300,6 +300,7 @@ Second, some keys have multiple-character string representations. Strings @item{@racket["shift"]} @item{@racket["rshift"]} @item{@racket["control"]} +@item{@racket["rcontrol"]} @item{@racket["menu"]} @item{@racket["pause"]} @item{@racket["capital"]} From d2de2659b7ef04a9445d22d4f5e2e9357d770a76 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 21 Jan 2012 07:17:25 -0700 Subject: [PATCH 523/746] try to fix Win64 installer: "Program Files (x86)" => "Program Files" (cherry picked from commit 9d48858d5350bb039af9391cb8a734d6d013e211) --- collects/meta/build/build | 8 +++++++- collects/meta/build/nsis/installer.nsi | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index 840919248f..f050dc0ec6 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -1810,7 +1810,13 @@ tgz_to_exe() { else echo "$def RKTDirName \"$distname\"" fi - echo "$def RKTRegName \"$distname-$version\"" + if [[ "$srcplatform" = "x86_64-win32" ]]; then + echo "$def RKTRegName \"${distname}-64-$version\"" + echo "$def RKTProgFiles \"\$PROGRAMFILES64\"" + else + echo "$def RKTRegName \"$distname-$version\"" + echo "$def RKTProgFiles \"\$PROGRAMFILES\"" + fi if [[ "$pname" = "mz" ]]; then echo "$def SimpleInstaller"; fi } > "racket-defs.nsh" \ || exit_error "Could not write \"racket-defs.h\"" diff --git a/collects/meta/build/nsis/installer.nsi b/collects/meta/build/nsis/installer.nsi index 4759e8f398..2fc114dee0 100644 --- a/collects/meta/build/nsis/installer.nsi +++ b/collects/meta/build/nsis/installer.nsi @@ -18,7 +18,7 @@ BGGradient 4040A0 101020 SetCompressor /SOLID "LZMA" -InstallDir "$PROGRAMFILES\${RKTDirName}" +InstallDir "${RKTProgFiles}\${RKTDirName}" !ifndef SimpleInstaller InstallDirRegKey HKLM "Software\${RKTRegName}" "" !endif From cb92bd9d446c845822197c2cd6a7fefe4804c0c1 Mon Sep 17 00:00:00 2001 From: John Clements Date: Mon, 23 Jan 2012 14:54:05 -0800 Subject: [PATCH 524/746] Updated HISTORY. Please merge to 5.2.1 release. (cherry picked from commit 080b6095c4602128d4db183109cbc1408ba58550) --- doc/release-notes/stepper/HISTORY.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/release-notes/stepper/HISTORY.txt b/doc/release-notes/stepper/HISTORY.txt index f900a225ab..4e6e5b1f05 100644 --- a/doc/release-notes/stepper/HISTORY.txt +++ b/doc/release-notes/stepper/HISTORY.txt @@ -1,6 +1,11 @@ Stepper ------- +Changes for v5.2.1: + +Fix occasional race condition bug on startup, lovely new icon work by +Neil Toronto. + Changes for v5.2: None. From 034d647b1e241c69b2b1a962a1fa29e1b1c7921a Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Mon, 23 Jan 2012 15:48:08 -0700 Subject: [PATCH 525/746] PLoT documentation for new renderers and plot/utils (code changes are only to move code around so a previously public function could be public again) Many little doc fixes Closes PR 12433 Closes PR 12435 Please please please merge into release (cherry picked from commit 015625e732509d522f4135b5c53133f1f64d285f) --- collects/plot/{plot2d => common}/kde.rkt | 28 +- collects/plot/common/math.rkt | 6 + collects/plot/contracted/kde.rkt | 7 + collects/plot/doc.rkt | 12 +- collects/plot/main.rkt | 5 +- collects/plot/plot2d/line.rkt | 22 ++ collects/plot/plot3d/point.rkt | 3 +- collects/plot/scribblings/common.rkt | 2 + collects/plot/scribblings/contracts.scrbl | 94 ++++- collects/plot/scribblings/nonrenderer.scrbl | 37 +- collects/plot/scribblings/params.scrbl | 35 +- collects/plot/scribblings/plot.scrbl | 4 +- collects/plot/scribblings/porting.scrbl | 2 +- collects/plot/scribblings/renderer2d.scrbl | 51 +-- collects/plot/scribblings/renderer3d.scrbl | 129 +++--- collects/plot/scribblings/ticks.scrbl | 57 ++- collects/plot/scribblings/todo.scrbl | 27 -- collects/plot/scribblings/utils.scrbl | 412 +++++++++++++++++--- collects/plot/utils.rkt | 6 +- 19 files changed, 704 insertions(+), 235 deletions(-) rename collects/plot/{plot2d => common}/kde.rkt (84%) create mode 100644 collects/plot/contracted/kde.rkt delete mode 100644 collects/plot/scribblings/todo.scrbl diff --git a/collects/plot/plot2d/kde.rkt b/collects/plot/common/kde.rkt similarity index 84% rename from collects/plot/plot2d/kde.rkt rename to collects/plot/common/kde.rkt index b0b2784f37..ad4d2d4aca 100644 --- a/collects/plot/plot2d/kde.rkt +++ b/collects/plot/common/kde.rkt @@ -2,15 +2,12 @@ (require racket/flonum racket/list racket/promise racket/math racket/contract unstable/latent-contract/defthing - plot/utils - "../common/utils.rkt" - "line.rkt") + "math.rkt" + "utils.rkt" + "sample.rkt") (provide (all-defined-out)) -(define (factorial n) - (if (zero? n) 1 (* n (factorial (sub1 n))))) - ;; make-kde/windowed : (vectorof flonum) flonum flonum flonum -> (listof flonum) -> (listof flonum) ;; (can assume that xs is sorted) ;; Make a naive KDE, but uses windows to keep from adding Gaussians more than max-dist away @@ -130,22 +127,3 @@ (map (λ (p) (fl* p c)) mid-ps) last-ps))))) (values (mapped-function (λ (x) (first (fmap (list x)))) fmap) x-min x-max)))) - -(defproc (density [xs (listof real?)] [bw-adjust real? 1] - [#:x-min x-min (or/c rational? #f) #f] [#:x-max x-max (or/c rational? #f) #f] - [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/c rational? #f) #f] - [#:samples samples (and/c exact-integer? (>=/c 2)) (line-samples)] - [#:color color plot-color/c (line-color)] - [#:width width (>=/c 0) (line-width)] - [#:style style plot-pen-style/c (line-style)] - [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] - ) renderer2d? - (define n (length xs)) - (define sd (sqrt (- (/ (sum sqr xs) n) (sqr (/ (sum values xs) n))))) - (define h (* bw-adjust 1.06 sd (expt n -0.2))) - (define-values (f fx-min fx-max) (kde xs h)) - (let ([x-min (if x-min x-min fx-min)] - [x-max (if x-max x-max fx-max)]) - (function f x-min x-max #:y-min y-min #:y-max y-max #:samples samples - #:color color #:width width #:style style #:alpha alpha #:label label))) diff --git a/collects/plot/common/math.rkt b/collects/plot/common/math.rkt index 2886040458..9be557368f 100644 --- a/collects/plot/common/math.rkt +++ b/collects/plot/common/math.rkt @@ -4,6 +4,12 @@ (provide (all-defined-out)) +;; =================================================================================================== +;; Integers + +(defproc (factorial [n exact-nonnegative-integer?]) exact-nonnegative-integer? + (if (zero? n) 1 (* n (factorial (sub1 n))))) + ;; =================================================================================================== ;; Flonums diff --git a/collects/plot/contracted/kde.rkt b/collects/plot/contracted/kde.rkt new file mode 100644 index 0000000000..389549dfa7 --- /dev/null +++ b/collects/plot/contracted/kde.rkt @@ -0,0 +1,7 @@ +#lang racket/base + +(require unstable/latent-contract) + +(require "../common/kde.rkt") +(provide (activate-contract-out + kde)) diff --git a/collects/plot/doc.rkt b/collects/plot/doc.rkt index 0b73b06a1a..46d505a472 100644 --- a/collects/plot/doc.rkt +++ b/collects/plot/doc.rkt @@ -18,7 +18,8 @@ "common/date-time.rkt" "common/marching-squares.rkt" "common/marching-cubes.rkt" - "common/legend.rkt") + "common/legend.rkt" + "common/kde.rkt") (provide (only-doc-out (combine-out (all-from-out "common/parameters.rkt") @@ -34,7 +35,8 @@ (all-from-out "common/date-time.rkt") (all-from-out "common/marching-squares.rkt") (all-from-out "common/marching-cubes.rkt") - (all-from-out "common/legend.rkt")))) + (all-from-out "common/legend.rkt") + (all-from-out "common/kde.rkt")))) ;; =================================================================================================== ;; 2D exports @@ -45,8 +47,7 @@ "plot2d/interval.rkt" "plot2d/contour.rkt" "plot2d/rectangle.rkt" - "plot2d/decoration.rkt" - "plot2d/kde.rkt") + "plot2d/decoration.rkt") (provide (only-doc-out (combine-out (all-from-out "plot2d/plot.rkt") @@ -55,8 +56,7 @@ (all-from-out "plot2d/interval.rkt") (all-from-out "plot2d/contour.rkt") (all-from-out "plot2d/rectangle.rkt") - (all-from-out "plot2d/decoration.rkt") - (all-from-out "plot2d/kde.rkt")))) + (all-from-out "plot2d/decoration.rkt")))) ;; =================================================================================================== ;; 3D exports diff --git a/collects/plot/main.rkt b/collects/plot/main.rkt index 0f2115f76c..7afc1e75da 100644 --- a/collects/plot/main.rkt +++ b/collects/plot/main.rkt @@ -35,7 +35,7 @@ (provide (activate-contract-out points vector-field error-bars)) (require "plot2d/line.rkt") -(provide (activate-contract-out lines parametric polar function inverse)) +(provide (activate-contract-out lines parametric polar function inverse density)) (require "plot2d/interval.rkt") (provide (activate-contract-out @@ -53,9 +53,6 @@ x-tick-lines y-tick-lines tick-grid point-label parametric-label polar-label function-label inverse-label)) -(require "plot2d/kde.rkt") -(provide (activate-contract-out density)) - ;; =================================================================================================== ;; 3D exports diff --git a/collects/plot/plot2d/line.rkt b/collects/plot/plot2d/line.rkt index 15e761f40c..980ebde674 100644 --- a/collects/plot/plot2d/line.rkt +++ b/collects/plot/plot2d/line.rkt @@ -131,3 +131,25 @@ (inverse-bounds-fun g samples) default-ticks-fun (inverse-render-proc g samples color width style alpha label))) + +;; =================================================================================================== +;; Kernel density estimation + +(defproc (density [xs (listof real?)] [bw-adjust real? 1] + [#:x-min x-min (or/c rational? #f) #f] [#:x-max x-max (or/c rational? #f) #f] + [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/c rational? #f) #f] + [#:samples samples (and/c exact-integer? (>=/c 2)) (line-samples)] + [#:color color plot-color/c (line-color)] + [#:width width (>=/c 0) (line-width)] + [#:style style plot-pen-style/c (line-style)] + [#:alpha alpha (real-in 0 1) (line-alpha)] + [#:label label (or/c string? #f) #f] + ) renderer2d? + (define n (length xs)) + (define sd (sqrt (- (/ (sum sqr xs) n) (sqr (/ (sum values xs) n))))) + (define h (* bw-adjust 1.06 sd (expt n -0.2))) + (define-values (f fx-min fx-max) (kde xs h)) + (let ([x-min (if x-min x-min fx-min)] + [x-max (if x-max x-max fx-max)]) + (function f x-min x-max #:y-min y-min #:y-max y-max #:samples samples + #:color color #:width width #:style style #:alpha alpha #:label label))) diff --git a/collects/plot/plot3d/point.rkt b/collects/plot/plot3d/point.rkt index 41b3aa4f17..f6df3c59f2 100644 --- a/collects/plot/plot3d/point.rkt +++ b/collects/plot/plot3d/point.rkt @@ -93,7 +93,8 @@ (defproc (vector-field3d [f (or/c (real? real? real? . -> . (vector/c real? real? real?)) - ((vector/c real? real? real?) . -> . (vector/c real? real? real?)))] + ((vector/c real? real? real?) + . -> . (vector/c real? real? real?)))] [x-min (or/c rational? #f) #f] [x-max (or/c rational? #f) #f] [y-min (or/c rational? #f) #f] [y-max (or/c rational? #f) #f] [z-min (or/c rational? #f) #f] [z-max (or/c rational? #f) #f] diff --git a/collects/plot/scribblings/common.rkt b/collects/plot/scribblings/common.rkt index 3cbdb0e1c9..5ba0576f2c 100644 --- a/collects/plot/scribblings/common.rkt +++ b/collects/plot/scribblings/common.rkt @@ -4,6 +4,7 @@ (for-label racket racket/gui/base slideshow/pict + db plot plot/utils) plot @@ -16,6 +17,7 @@ (for-label (all-from-out racket racket/gui/base slideshow/pict + db plot plot/utils)) (all-from-out plot) diff --git a/collects/plot/scribblings/contracts.scrbl b/collects/plot/scribblings/contracts.scrbl index f46d45d47e..d352ab6760 100644 --- a/collects/plot/scribblings/contracts.scrbl +++ b/collects/plot/scribblings/contracts.scrbl @@ -6,15 +6,20 @@ @title[#:tag "contracts"]{Plot Contracts} -@section{Convenience Contracts} +@section{Plot Element Contracts} -@doc-apply[contract/c]{ -Identifies @racket[contract?]s and predicates that can be used as contracts. +@defproc[(renderer2d? [value any/c]) boolean?]{ +Returns @racket[#t] if @racket[value] is a 2D @tech{renderer}; that is, if @racket[plot] can plot @racket[value]. +See @secref["renderer2d"] for functions that construct them. } -@doc-apply[treeof]{ -Identifies trees of values that meet the contract @(racket ct). -Used by @(racket plot) and @(racket plot3d) to construct the contract for a tree of @(racket renderer2d?) or @(racket renderer3d?). +@defproc[(renderer3d? [value any/c]) boolean?]{ +Returns @racket[#t] if @racket[value] is a 3D @tech{renderer}; that is, if @racket[plot3d] can plot @racket[value]. +See @secref["renderer3d"] for functions that construct them. +} + +@defproc[(nonrenderer? [value any/c]) boolean?]{ +Returns @racket[#t] if @racket[value] is a @tech{nonrenderer}. See @secref["nonrenderer"] for functions that construct them. } @section{Appearance Argument Contracts} @@ -23,7 +28,11 @@ Used by @(racket plot) and @(racket plot3d) to construct the contract for a tree The contract for @(racket anchor) arguments and parameters, such as @(racket plot-legend-anchor). } -@doc-apply[color/c] +@doc-apply[color/c]{ +A contract for very flexible color arguments. +Functions that accept a @racket[color/c] almost always convert it to an RGB triplet using @racket[->color]. +} + @doc-apply[plot-color/c]{ The contract for @(racket #:color) arguments, and parameters such as @(racket line-color) and @(racket surface-color). For the meaning of integer colors, see @(racket ->pen-color) and @(racket ->brush-color). @@ -51,18 +60,61 @@ The contract for the @(racket #:sym) arguments in @(racket points) and @(racket A list containing the symbols that are valid @(racket points) symbols. } -@section{Appearance Argument Sequence Contracts} +@section{Appearance Argument List Contracts} @doc-apply[maybe-function/c]{ +Returns a contract that accepts either a function from @racket[in-contract] to @racket[out-contract], or a plain @racket[out-contract] value. + +@interaction[#:eval plot-eval + (require racket/contract) + (define/contract (maybe-function-of-real-consumer x) + ((maybe-function/c real? real?) . -> . real?) + (maybe-apply x 10)) + (maybe-function-of-real-consumer 4) + (maybe-function-of-real-consumer (λ (x) x))] + +Many @racketmodname[plot] functions, such as @racket[contours] and @racket[isosurfaces3d], optionally take lists of appearance values (such as @racket[(listof plot-color/c)]) as arguments. +A very flexible argument contract would accept @italic{functions} that produce lists of appearance values. +For example, @racket[contours] would accept any @racket[f] with contract @racket[((listof real?) . -> . (listof plot-color/c))] for its @racket[#:colors] argument. +When rendering a contour plot, @racket[contours] would apply @racket[f] to a list of the contour @italic{z} values to get the contour colors. + +However, most uses do not need this flexibility. +Therefore, @racketmodname[plot]'s functions accept @italic{either} a list of appearance values @italic{or} a function from a list of appropriate values to a list of appearance values. +The @racket[maybe-function/c] function constructs contracts for such arguments. + +In @racketmodname[plot] functions, if @racket[in-contract] is a @racket[listof] contract, the output list's length need not be the same as the input list's length. +If it is shorter, the appearance values will cycle; if longer, the tail will not be used. +} + +@doc-apply[maybe-apply]{ +If @racket[f] is a function, applies @racket[f] to @racket[args]; otherwise returns @racket[f]. + +This is used inside many renderer-producing @racket[plot] functions to convert @racket[maybe-function/c] values to lists of appearance values. } @doc-apply[plot-colors/c]{ -The contract for @(racket #:colors) arguments, as in @(racket contours). -If the contracted value is a function, it is intended to take a list of values, such as contour values, as input, and return a list of colors. -The number of colors need not be the same as the number of values. -If shorter, they will cycle; if longer, some will not be used. +Returns a contract for @(racket #:colors) arguments, as in @(racket contours) and @racket[contour-intervals]. +See @racket[maybe-function/c] for a discussion of the returned contract. -See @(racket color-seq) and @(racket color-seq*) for a demonstration of constructing arguments with this contract. +The following example sends a @italic{list}-valued @racket[(plot-colors/c ivl?)] to @racket[contour-intervals], which then cycles through the colors: +@interaction[#:eval plot-eval + (plot (contour-intervals (λ (x y) (+ x y)) 0 1 0 1 + #:colors '(1 2)))] +This is equivalent to sending @racket[(λ _ '(1 2))]. + +The next example is more sophisticated: it sends a @italic{function}-valued @racket[(plot-colors/c ivl?)] to @racket[contour-intervals]. +The function constructs colors from the values of the contour intervals. +@interaction[#:eval plot-eval + (define (brown-interval-colors ivls) + (define z-size (- (ivl-max (last ivls)) + (ivl-min (first ivls)))) + (for/list ([i (in-list ivls)]) + (match-define (ivl z-min z-max) i) + (define z-mid (/ (* 1/2 (+ z-min z-max)) z-size)) + (list (* 255 z-mid) (* 128 z-mid) (* 64 z-mid)))) + + (plot (contour-intervals (λ (x y) (+ x y)) 0 1 0 1 + #:colors brown-interval-colors))] } @doc-apply[plot-pen-styles/c]{ @@ -80,3 +132,19 @@ Like @(racket plot-colors/c), but for fill styles. @doc-apply[alphas/c]{ Like @(racket plot-colors/c), but for opacities. } + +@doc-apply[labels/c]{ +Like @racket[plot-colors/c], but for strings. +This is used, for example, to label @racket[stacked-histogram]s. +} + +@section{Convenience Contracts} + +@doc-apply[contract/c]{ +Identifies @racket[contract?]s and predicates that can be used as contracts. +} + +@doc-apply[treeof]{ +Identifies trees of values that meet the contract @(racket ct). +Used by @(racket plot) and @(racket plot3d) to construct the contract for a tree of @(racket renderer2d?) or @(racket renderer3d?). +} diff --git a/collects/plot/scribblings/nonrenderer.scrbl b/collects/plot/scribblings/nonrenderer.scrbl index 5ee1920d95..0a83a54892 100644 --- a/collects/plot/scribblings/nonrenderer.scrbl +++ b/collects/plot/scribblings/nonrenderer.scrbl @@ -6,16 +6,41 @@ @title[#:tag "nonrenderer"]{Nonrenderers} -@defproc[(nonrenderer? [value any/c]) boolean?]{ -} +The following functions create @deftech{nonrenderers}, or plot elements that draw nothing in the plot. @doc-apply[x-ticks] - @doc-apply[y-ticks] +@doc-apply[z-ticks]{ +The @racket[x-ticks], @racket[y-ticks] and @racket[z-ticks] return a nonrenderer that adds custom ticks to a 2D or 3D plot. -@doc-apply[z-ticks] +Although @racket[ticks-add] allows placing arbitrary major and minor ticks on an axis, it does not allow them to be formatted differently from the other ticks on the same axis. +Use one of these functions to get maximum control. -@doc-apply[invisible-rect] +@examples[#:eval plot-eval + (parameterize ([plot-x-ticks no-ticks]) + (plot (list (function sin (- pi) pi) + (x-ticks (list (tick (- pi) #t "-π") + (tick (* -3/4 pi) #f "") + (tick (* -1/2 pi) #t "-π/2") + (tick (* -1/4 pi) #f "") + (tick 0 #t "0") + (tick (* 1/4 pi) #f "") + (tick (* 1/2 pi) #t "π/2") + (tick (* 3/4 pi) #f "") + (tick pi #t "π"))) + (axes))))] +When considering using one of these functions, remember that minor tick labels are never drawn, +and that including a @racket[z-ticks] nonrenderer will not add extra contour lines to contour plots. +} -@doc-apply[invisible-rect3d] +@doc-apply[invisible-rect]{ +Returns a nonrenderer that simply takes up space in the plot. Use this to cause the plot area to include a minimal rectangle. +@examples[#:eval plot-eval + (plot (list (function sin (- pi) pi) + (invisible-rect #f #f -2 2)))] +} +@doc-apply[invisible-rect3d]{ +Returns a nonrenderer that simply takes up space in the plot. Use this to cause the plot area to include a minimal rectangle. +See @racket[invisible-rect] for a 2D example. +} diff --git a/collects/plot/scribblings/params.scrbl b/collects/plot/scribblings/params.scrbl index c1f5d304c4..0263c1f9f9 100644 --- a/collects/plot/scribblings/params.scrbl +++ b/collects/plot/scribblings/params.scrbl @@ -56,12 +56,30 @@ See @(racket ->pen-color) and @(racket ->brush-color) for details on how PLoT in } @doc-apply[plot-x-far-label] @doc-apply[plot-y-far-label] -@doc-apply[plot-z-far-label] +@doc-apply[plot-z-far-label]{ +The tick labels for ``far'' axes. See @racket[plot-x-ticks] for a discussion of near and far axes. +} + +@doc-apply[plot-x-axis?] +@doc-apply[plot-x-far-axis?] +@doc-apply[plot-y-axis?] +@doc-apply[plot-y-far-axis?] +@doc-apply[plot-z-axis?] +@doc-apply[plot-z-far-axis?]{ +When any of these is @racket[#f], the corresponding axis is not drawn. + +Use these along with @racket[x-axis] and @racket[y-axis] if you want axes that intersect the origin or some other point. +} @doc-apply[plot-animating?]{ When @(racket #t), certain renderers draw simplified plots to speed up drawing. PLoT sets it to @(racket #t), for example, when a user is clicking and dragging a 3D plot to rotate it. } +@doc-apply[animated-samples]{ +Given a number of samples, returns the number of samples to use. +This returns @racket[samples] when @racket[plot-animating?] is @racket[#f]. +} + @doc-apply[plot-decorations?]{ When @(racket #f), axes, axis labels, ticks, tick labels, and the title are not drawn. } @@ -103,6 +121,8 @@ When @(racket #f), axes, axis labels, ticks, tick labels, and the title are not @doc-apply[vector-field-scale] @doc-apply[vector-field-alpha] +@doc-apply[vector-field3d-samples] + @section{Error Bars} @doc-apply[error-bar-width] @@ -142,9 +162,17 @@ When @(racket #f), axes, axis labels, ticks, tick labels, and the title are not @doc-apply[discrete-histogram-skip] @doc-apply[discrete-histogram-invert?] +@doc-apply[stacked-histogram-alphas] +@doc-apply[stacked-histogram-colors] +@doc-apply[stacked-histogram-line-colors] +@doc-apply[stacked-histogram-line-styles] +@doc-apply[stacked-histogram-line-widths] +@doc-apply[stacked-histogram-styles] + @section{Decorations} -These parameters do not control the @italic{typical} appearance of plots. Instead, they control the look of renderers that add specific decorations, such as labeled points. +These parameters do not control the @italic{typical} appearance of plots. +Instead, they control the look of renderers that add specific decorations, such as labeled points. @doc-apply[x-axis-alpha] @doc-apply[y-axis-alpha] @@ -200,7 +228,8 @@ Contour surface renderers use shared contour parameters except for the following @section{Isosurfaces} -Single isosurfaces (@(racket isosurface3d)) use surface parameters. Nested isosurfaces (@(racket isosurfaces3d)) use the following. +Single isosurfaces (@(racket isosurface3d)) use surface parameters. +Nested isosurfaces (@(racket isosurfaces3d)) use the following. @doc-apply[default-isosurface-colors] @doc-apply[default-isosurface-line-colors] diff --git a/collects/plot/scribblings/plot.scrbl b/collects/plot/scribblings/plot.scrbl index 9ebd07f3d1..355ec21b9c 100644 --- a/collects/plot/scribblings/plot.scrbl +++ b/collects/plot/scribblings/plot.scrbl @@ -41,10 +41,8 @@ If you have code written for PLoT 5.1.3 or earlier, please see @secref["porting" @include-section["contracts.scrbl"] -@include-section["custom.scrbl"] +@;@include-section["custom.scrbl"] @include-section["porting.scrbl"] @include-section["compat.scrbl"] - -@include-section["todo.scrbl"] diff --git a/collects/plot/scribblings/porting.scrbl b/collects/plot/scribblings/porting.scrbl index 644b5f7e48..914139da23 100644 --- a/collects/plot/scribblings/porting.scrbl +++ b/collects/plot/scribblings/porting.scrbl @@ -18,7 +18,7 @@ The update from PLoT version 5.1.3 to 5.2 introduces a few incompatibilities: The argument change in @(racket plot3d) is similar. This should not affect most code because PLoT encourages regarding these data types as black boxes.} @item{The @(racket plot-extend) module no longer exists.} - @item{The @racket[fit] function and @racket[fit-result] functions have been removed.} + @item{The @racket[fit] function and @racket[fit-result] struct type have been removed.} ] diff --git a/collects/plot/scribblings/renderer2d.scrbl b/collects/plot/scribblings/renderer2d.scrbl index d4e76a03b5..a95515d9ec 100644 --- a/collects/plot/scribblings/renderer2d.scrbl +++ b/collects/plot/scribblings/renderer2d.scrbl @@ -6,11 +6,6 @@ @title[#:tag "renderer2d"]{2D Renderers} -@defproc[(renderer2d? [value any/c]) boolean?]{ -Returns @racket[#t] if @racket[value] is a 2D @tech{renderer}; that is, if @racket[plot] can plot @racket[value]. -The following functions create such renderers. -} - @section[#:tag "renderer2d-function-arguments"]{2D Renderer Function Arguments} Functions that return 2D renderers always have these kinds of arguments: @@ -191,23 +186,21 @@ Corresponds with @(racket lines). Corresponds with @(racket parametric). @interaction[#:eval plot-eval - (let () - (define (f1 t) (vector (* 2 (cos (* 4/5 t))) - (* 2 (sin (* 4/5 t))))) - (define (f2 t) (vector (* 1/2 (cos t)) - (* 1/2 (sin t)))) - (plot (parametric-interval f1 f2 (- pi) pi)))] + (define (f1 t) (vector (* 2 (cos (* 4/5 t))) + (* 2 (sin (* 4/5 t))))) + (define (f2 t) (vector (* 1/2 (cos t)) + (* 1/2 (sin t)))) + (plot (parametric-interval f1 f2 (- pi) pi))] } @doc-apply[polar-interval]{ Corresponds with @(racket polar). @interaction[#:eval plot-eval - (let () - (define (f1 θ) (+ 1/2 (* 1/6 (cos (* 5 θ))))) - (define (f2 θ) (+ 1 (* 1/4 (cos (* 10 θ))))) - (plot (list (polar-axes #:number 10) - (polar-interval f1 f2 #:label "[f1,f2]"))))] + (define (f1 θ) (+ 1/2 (* 1/6 (cos (* 5 θ))))) + (define (f2 θ) (+ 1 (* 1/4 (cos (* 10 θ))))) + (plot (list (polar-axes #:number 10) + (polar-interval f1 f2 #:label "[f1,f2]")))] } @section{2D Contour (Isoline) Renderers} @@ -220,6 +213,9 @@ A circle of radius @(racket r), for example, is the line of constant value @(rac } In this case, @(racket r) = @(racket 1.5). +This function would have been named @racket[contour], except the name was already used by a deprecated function. +It may be renamed in the future, with @racket[isoline] as an alias. + @doc-apply[contours]{ Returns a renderer that plots contour lines, or lines of constant value (height). @@ -256,10 +252,6 @@ For example, the canonical saddle, with its gradient field superimposed: @section{2D Rectangle Renderers} -@defstruct[ivl ([min real?] [max real?])]{ -Represents a closed interval. Used to give bounds to rectangles in @(racket rectangles), @(racket rectangles3d), and functions derived from them. -} - @doc-apply[rectangles]{ Returns a renderer that draws rectangles. The rectanges are given as a list of vectors of intervals---each vector defines the bounds of a rectangle. For example, @@ -271,10 +263,10 @@ The rectanges are given as a list of vectors of intervals---each vector defines Returns a renderer that draws a histogram approximating the area under a curve. The @(racket #:samples) argument determines the accuracy of the calculated areas. @interaction[#:eval plot-eval - (let () - (define (f x) (exp (* -1/2 (sqr x)))) - (plot (list (area-histogram f (linear-seq -4 4 10)) - (function f -4 4))))] + (require (only-in plot/utils linear-seq)) + (define (f x) (exp (* -1/2 (sqr x)))) + (plot (list (area-histogram f (linear-seq -4 4 10)) + (function f -4 4)))] } @doc-apply[discrete-histogram]{ @@ -292,6 +284,17 @@ To plot histograms side-by-side, pass the appropriate @(racket #:x-min) value to #:label "Numbers per number")))] } +@doc-apply[stacked-histogram]{ +Returns a renderer that draws a stacked histogram. +The heights of each bar section are given as a list. +@examples[#:eval plot-eval + (plot (stacked-histogram (list #(a (1 1 1)) #(b (1.5 3)) + #(c ()) #(d (1/2))) + #:invert? #t + #:labels '("Red" #f "Blue")) + #:legend-anchor 'top-right)] +} + @section{2D Plot Decoration Renderers} @doc-apply[x-axis]{ diff --git a/collects/plot/scribblings/renderer3d.scrbl b/collects/plot/scribblings/renderer3d.scrbl index 4585d22d4f..1acfedc7f3 100644 --- a/collects/plot/scribblings/renderer3d.scrbl +++ b/collects/plot/scribblings/renderer3d.scrbl @@ -6,11 +6,6 @@ @title[#:tag "renderer3d"]{3D Renderers} -@defproc[(renderer3d? [value any/c]) boolean?]{ -Returns @racket[#t] if @racket[value] is a 3D @tech{renderer}; that is, if @racket[plot3d] can plot @racket[value]. -The following functions create such renderers. -} - @section{3D Renderer Function Arguments} As with functions that return 2D renderers, functions that return 3D renderers always have these kinds of arguments: @@ -29,38 +24,43 @@ Returns a renderer that draws points in 3D space. For example, a scatter plot of points sampled uniformly from the surface of a sphere: @interaction[#:eval plot-eval - (let () - (define (runif) (- (* 2 (random)) 1)) - (define (rnormish) (+ (runif) (runif) (runif) (runif))) - - (define xs0 (build-list 1000 (λ _ (rnormish)))) - (define ys0 (build-list 1000 (λ _ (rnormish)))) - (define zs0 (build-list 1000 (λ _ (rnormish)))) - (define mags (map (λ (x y z) (sqrt (+ (sqr x) (sqr y) (sqr z)))) - xs0 ys0 zs0)) - (define xs (map / xs0 mags)) - (define ys (map / ys0 mags)) - (define zs (map / zs0 mags)) - - (plot3d (points3d (map vector xs ys zs) #:sym 'dot) - #:altitude 25))] + (define (runif) (- (* 2 (random)) 1)) + (define (rnormish) (+ (runif) (runif) (runif) (runif))) + + (define xs0 (build-list 1000 (λ _ (rnormish)))) + (define ys0 (build-list 1000 (λ _ (rnormish)))) + (define zs0 (build-list 1000 (λ _ (rnormish)))) + (define mags (map (λ (x y z) (sqrt (+ (sqr x) (sqr y) (sqr z)))) + xs0 ys0 zs0)) + (define xs (map / xs0 mags)) + (define ys (map / ys0 mags)) + (define zs (map / zs0 mags)) + + (plot3d (points3d (map vector xs ys zs) #:sym 'dot) + #:altitude 25)] +} + +@doc-apply[vector-field3d]{ +Returns a renderer that draws a vector field in 3D space. +The arguments are interpreted identically to the corresponding arguments to @racket[vector-field]. +@examples[#:eval plot-eval + (plot3d (vector-field3d (λ (x y z) (vector x z y)) + -2 2 -2 2 -2 2))] } @section{3D Line Renderers} @doc-apply[lines3d]{ -Returns a renderer that draws connected lines, with points in 3D space. +Returns a renderer that draws connected lines. +The @racket[parametric3d] function is defined in terms of this one. } @doc-apply[parametric3d]{ Returns a renderer that plots a vector-valued function of time. For example, @interaction[#:eval plot-eval - (plot3d (parametric3d (λ (t) - (vector (* (cos (* 80 t)) (cos t)) - (* (sin (* 80 t)) (cos t)) - (sin t))) - (- pi) pi - #:samples 3000 #:alpha 0.5) + (require (only-in plot/utils 3d-polar->3d-cartesian)) + (plot3d (parametric3d (λ (t) (3d-polar->3d-cartesian (* t 80) t 1)) + (- pi) pi #:samples 3000 #:alpha 0.5) #:altitude 25)] } @@ -79,27 +79,36 @@ Returns a renderer that plots a two-input, one-output function. For example, Returns a renderer that plots a function from latitude and longitude to radius. Currently, latitudes range from @(racket 0) to @(racket (* 2 pi)), and longitudes from @(racket (* -1/2 pi)) to @(racket (* 1/2 pi)). +These intervals may become optional arguments to @racket[polar3d] in the future. A sphere is the graph of a polar function of constant radius: @interaction[#:eval plot-eval (plot3d (polar3d (λ (θ ρ) 1)) #:altitude 25)] Combining polar function renderers allows faking latitudes or longitudes in larger ranges, to get, for example, a seashell plot: @interaction[#:eval plot-eval - (let () + (parameterize ([plot-decorations? #f] + [plot3d-samples 75]) (define (f1 θ ρ) (+ 1 (/ θ 2 pi) (* 1/8 (sin (* 8 ρ))))) (define (f2 θ ρ) (+ 0 (/ θ 2 pi) (* 1/8 (sin (* 8 ρ))))) (plot3d (list (polar3d f1 #:color "navajowhite" #:line-style 'transparent #:alpha 2/3) (polar3d f2 #:color "navajowhite" - #:line-style 'transparent #:alpha 2/3)) - #:title "A Seashell" #:x-label #f #:y-label #f))] + #:line-style 'transparent #:alpha 2/3))))] } @section{3D Contour (Isoline) Renderers} @doc-apply[isoline3d]{ Returns a renderer that plots a single contour line on the surface of a function. + +The appearance keyword arguments are interpreted identically to the appearance keyword arguments to @(racket isoline). + +This function is not terribly useful by itself, but can be when combined with others: +@interaction[#:eval plot-eval + (define (saddle x y) (- (sqr x) (sqr y))) + (plot3d (list (surface3d saddle -1 1 -1 1) + (isoline3d saddle 1/4 #:width 2 #:style 'long-dash)))] } @doc-apply[contours3d]{ @@ -110,8 +119,7 @@ In particular, when @(racket levels) is @(racket 'auto), contour values correspo For example, @interaction[#:eval plot-eval (plot3d (contours3d (λ (x y) (+ (sqr x) (sqr y))) -1.1 1.1 -1.1 1.1 - #:label "z = x^2 + y^2") - #:legend-anchor 'top-left)] + #:label "z = x^2 + y^2"))] } @doc-apply[contour-intervals3d]{ @@ -121,8 +129,7 @@ The appearance keyword arguments are interpreted identically to the appearance k For example, @interaction[#:eval plot-eval (plot3d (contour-intervals3d (λ (x y) (+ (sqr x) (sqr y))) -1.1 1.1 -1.1 1.1 - #:label "z = x^2 + y^2") - #:legend-anchor 'top-left)] + #:label "z = x^2 + y^2"))] } @section{3D Isosurface Renderers} @@ -141,13 +148,12 @@ For example, a sphere is all the points in which the Euclidean distance function Returns a renderer that plots multiple isosurfaces. The appearance keyword arguments are interpreted similarly to those of @(racket contours). Use this to visualize functions from three inputs to one output; for example: -@interaction[#:eval plot-eval (let () - (define (saddle x y z) (- (sqr x) (* 1/2 (+ (sqr y) (sqr z))))) - (plot3d (isosurfaces3d saddle #:d-min -1 #:d-max 1 #:label "") - #:x-min -2 #:x-max 2 - #:y-min -2 #:y-max 2 - #:z-min -2 #:z-max 2 - #:legend-anchor 'top-left))] +@interaction[#:eval plot-eval + (define (saddle x y z) (- (sqr x) (* 1/2 (+ (sqr y) (sqr z))))) + (plot3d (isosurfaces3d saddle #:d-min -1 #:d-max 1 #:label "") + #:x-min -2 #:x-max 2 + #:y-min -2 #:y-max 2 + #:z-min -2 #:z-max 2)] If it helps, think of the output of @(racket f) as a density or charge. } @@ -159,21 +165,23 @@ Returns a renderer that draws rectangles. This can be used to draw histograms; for example, @interaction[#:eval plot-eval - (let () - (define (norm2 x y) (exp (* -1/2 (+ (sqr (- x 5)) (sqr y))))) - (define x-ivls (bounds->intervals (linear-seq 2 8 10))) - (define y-ivls (bounds->intervals (linear-seq -5 5 10))) - (define x-mids (linear-seq 2 8 9 #:start? #f #:end? #f)) - (define y-mids (linear-seq -5 5 9 #:start? #f #:end? #f)) - (plot3d (rectangles3d (append* - (for/list ([y-ivl (in-list y-ivls)] - [y (in-list y-mids)]) - (for/list ([x-ivl (in-list x-ivls)] - [x (in-list x-mids)]) - (define z (norm2 x y)) - (vector x-ivl y-ivl (ivl 0 z))))) - #:alpha 3/4 - #:label "Appx. 2D Normal")))] + (require (only-in plot/utils bounds->intervals linear-seq)) + + (define (norm2 x y) (exp (* -1/2 (+ (sqr (- x 5)) (sqr y))))) + (define x-ivls (bounds->intervals (linear-seq 2 8 16))) + (define y-ivls (bounds->intervals (linear-seq -5 5 16))) + (define x-mids (linear-seq 2 8 15 #:start? #f #:end? #f)) + (define y-mids (linear-seq -5 5 15 #:start? #f #:end? #f)) + + (plot3d (rectangles3d (append* + (for/list ([y-ivl (in-list y-ivls)] + [y (in-list y-mids)]) + (for/list ([x-ivl (in-list x-ivls)] + [x (in-list x-mids)]) + (define z (norm2 x y)) + (vector x-ivl y-ivl (ivl 0 z))))) + #:alpha 3/4 + #:label "Appx. 2D Normal"))] } @doc-apply[discrete-histogram3d]{ @@ -185,3 +193,12 @@ Missing pairs are not drawn; for example, #:label "Missing (b,a)" #:color 4 #:line-color 4))] } + +@doc-apply[stacked-histogram3d]{ +Returns a renderer that draws a stacked histogram. +Think of it as a version of @racket[discrete-histogram] that allows multiple values to be specified for each pair of categories. +@examples[#:eval plot-eval + (define data '(#(a a (1 1 1)) #(a b (1.5 3)) #(b b ()) #(b a (1/2)))) + (plot3d (stacked-histogram3d data #:labels '("Red" #f "Blue") + #:alphas '(2/3 1 2/3)))] +} diff --git a/collects/plot/scribblings/ticks.scrbl b/collects/plot/scribblings/ticks.scrbl index fa8824e1c6..e1d9bfa565 100644 --- a/collects/plot/scribblings/ticks.scrbl +++ b/collects/plot/scribblings/ticks.scrbl @@ -21,6 +21,20 @@ To put log ticks on the @italic{x} axis, set the @racket[plot-x-ticks] parameter (plot (function sin 1 100)))] See @secref["ticks"] for more details on parameterizing a plot's axis ticks. +@margin-note*{ +To sample nonlinearly, the @italic{inverse} of a transform is applied to linearly sampled points. See @racket[make-axis-transform] and @racket[nonlinear-seq].} +Renderers cooperate with the current transforms by sampling nonlinearly. For example, +@interaction[#:eval plot-eval + (parameterize ([plot-x-transform log-transform]) + (plot3d (surface3d + 0.01 1 0.01 1)))] +Notice that the surface is sampled uniformly in appearance even though the @italic{x}-axis ticks are not spaced uniformly. + +Transforms are applied to the primitive shapes that comprise a plot: +@interaction[#:eval plot-eval + (parameterize ([plot-x-transform log-transform]) + (plot3d (surface3d + 0.01 1 0.01 1 #:samples 3)))] +Here, the renderer returned by @racket[surface3d] does not have to bend the polygons it draws; @racket[plot3d] does this automatically (by recursive subdivision). + @doc-apply[plot-x-transform] @doc-apply[plot-y-transform] @doc-apply[plot-z-transform]{ @@ -85,8 +99,6 @@ The @(racket freq) parameter controls the ``shakiness'' of the transform. At hig [plot-z-transform (hand-drawn-transform 50)]) (plot3d (contour-intervals3d (λ (x y) (- (sqr x) (sqr y))) -1 1 -1 1 #:samples 9)))] - -The last example shows that the transform is applied to the primitive shapes that comprise the plot (by recursive subdivision). } @doc-apply[axis-transform/c]{ @@ -142,11 +154,14 @@ For example, @interaction[#:eval plot-eval (match-let ([(invertible-function f g) (apply-axis-transform log-transform 1 3)]) - (values (list (f 1) (f 2) (f 3)) - (list (g 1) (g 2.2618595071429146) (g 3))))] + (define xs '(1 2 3)) + (define new-xs (map f xs)) + (define old-xs (map g new-xs)) + (values new-xs old-xs))] Technically, @racket[fun] does not need to be truly invertible. -Given @racket[fun] = @racket[(invertible-function f g)], it is enough for @racket[f] to be a @hyperlink["http://en.wikipedia.org/wiki/Inverse_function#Left_and_right_inverses"]{left inverse} of @racket[g]. +Given @racket[fun] = @racket[(invertible-function f g)], it is enough for @racket[f] to be a @hyperlink["http://en.wikipedia.org/wiki/Inverse_function#Left_and_right_inverses"]{left inverse} of @racket[g]; +that is, always @racket[(f (g x)) = x] but not necessarily @racket[(g (f x)) = x]. If @racket[f] and @racket[g] had to be strict inverses of each other, there could be no @racket[collapse-transform]. } @@ -200,12 +215,34 @@ For example, compare plots of the same function renderered using both @racket[co #:legend-anchor 'center)))] } +@doc-apply[contour-ticks]{ +Returns the ticks used for contour values. +This is used internally by renderers returned from @racket[contours], @racket[contour-intervals], @racket[contours3d], @racket[contour-intervals3d], and @racket[isosurfaces3d], but is provided for completeness. + +When @racket[levels] is @racket['auto], the returned values do not correspond @italic{exactly} with the values of ticks returned by @racket[z-ticks]: they might be missing the endpoint values. For example, +@interaction[#:eval plot-eval + (map pre-tick-value + (filter pre-tick-major? ((plot-z-ticks) 0 1))) + (map pre-tick-value + (contour-ticks (plot-z-ticks) 0 1 'auto #f))] +} + +@doc-apply[plot-d-ticks]{ +The ticks used for default isosurface values in @racket[isosurfaces3d]. +} + +@doc-apply[plot-r-ticks]{ +The ticks used for radius lines in @racket[polar-axes]. +} + @defstruct[ticks ([layout ticks-layout/c] [format ticks-format/c])]{ A @racket[ticks] for a near or far axis consists of a @racket[layout] function, which determines the number of ticks and where they will be placed, and a @racket[format] function, which determines the ticks' labels. } @doc-apply[ticks-default-number]{ -Most tick layout functions (and thus their corresponding @racket[ticks]-constructing functions) have a @racket[#:number] keyword argument with default @racket[(ticks-default-number)]. What the number means depends on the tick layout function. Most use it for the maximum number of major ticks. +Most tick layout functions (and thus their corresponding @racket[ticks]-constructing functions) have a @racket[#:number] keyword argument with default @racket[(ticks-default-number)]. +What the number means depends on the tick layout function. +Most use it for an average number of major ticks. It is unlikely to mean the exact number of major ticks. Without adjusting the number of ticks, layout functions usually cannot find uniformly spaced ticks that will have simple labels after formatting. @@ -260,7 +297,7 @@ Actually, @racket[date-ticks-layout] does not always space ticks @italic{quite} For example, it rounds ticks that are spaced about one month apart or more to the nearest month. Generally, @racket[date-ticks-layout] tries to place ticks at minute, hour, day, week, month and year boundaries, as well as common multiples such as 90 days or 6 months. -To avoid displaying overlapping labels, @racket[date-ticks-format] chooses date formats from @racket[formats] for which labels will contain no redundant information. +To try to avoid displaying overlapping labels, @racket[date-ticks-format] chooses date formats from @racket[formats] for which labels will contain no redundant information. All the format specifiers given in @racketmodname[srfi/19] (which are derived from Unix's @tt{date} command), except those that represent time zones, are allowed in date format strings. } @@ -284,7 +321,7 @@ Use @racket[datetime->real] to convert @racket[sql-time] or @racket[plot-time] v Generally, @racket[time-ticks-layout] tries to place ticks at minute, hour and day boundaries, as well as common multiples such as 12 hours or 30 days. -To avoid displaying overlapping labels, @racket[time-ticks-format] chooses a date format from @racket[formats] for which labels will contain no redundant information. +To try to avoid displaying overlapping labels, @racket[time-ticks-format] chooses a date format from @racket[formats] for which labels will contain no redundant information. All the time-related format specifiers given in @racketmodname[srfi/19] (which are derived from Unix's @tt{date} command) are allowed in time format strings. } @@ -313,8 +350,6 @@ The @racket[#:formats] keyword argument is a list of three format strings, repre @item{@racket["~f"]: replaced by the fractional part, with 2 or more decimal digits} @item{@racket["~s"]: replaced by the scale suffix} @item{@racket["~~"]: replaced by ``~''}] - -Note that the @racket[#:divisors] passed to @racket[linear-ticks-layout] are @racket['(1 2 4 5)]. This allows quarter divisions to be used for tick positions, corresponding to 25/100 denominations such as the US quarter dollar. } @doc-apply[currency-ticks-scales] @@ -327,7 +362,7 @@ For example, a PLoT user in France would probably begin programs with (currency-ticks-formats eu-currency-formats)] and use @racket[(currency-ticks #:kind 'EUR)] for local currency or @racket[(currency-ticks #:kind 'JPY)] for Japanese Yen. -Cultural sensitivity notwithstanding, when writing for a local audience, it is generally considered proper to use local currency scales and formats for foreign currencies. +Cultural sensitivity notwithstanding, when writing for a local audience, it is generally considered proper to use local currency scales and formats for foreign currencies, but use the foreign currency symbol. } @doc-apply[us-currency-scales]{ diff --git a/collects/plot/scribblings/todo.scrbl b/collects/plot/scribblings/todo.scrbl deleted file mode 100644 index c117d2ffab..0000000000 --- a/collects/plot/scribblings/todo.scrbl +++ /dev/null @@ -1,27 +0,0 @@ -#lang scribble/manual - -@(require "common.rkt") - -@title[#:tag "todo"]{To Do} - -@itemlist[ - @item{Planned new renderers - @itemlist[ - @item{Functions with integer domains} - @item{2D kernel density estimator} - @item{3D kernel density estimator} - @item{3D decorations: labeled points, axes, grids} - ] - } - @item{Possible minor enhancements - @itemlist[ - @item{Better depth sorting (possibly split intersecting polygons; look into BSP tree)} - @item{Legend entries have minimum sizes} - @item{Label contour heights on the contour lines} - @item{3D support for exact rational functions (i.e. polynomial at [big..big+ε])} - @item{Join 2D contour lines} - @item{Manually exclude discontinuous points from function renderers: allow values @(racket (hole p1 p2)), @(racket (left-hole p1 p2)), @(racket (right-hole p1 p2))} - @item{@(racket histogram-list) to plot multiple histograms without manually calculating @(racket #:x-min)} - ] - } -] diff --git a/collects/plot/scribblings/utils.scrbl b/collects/plot/scribblings/utils.scrbl index 8710ae1277..5305ffd8da 100644 --- a/collects/plot/scribblings/utils.scrbl +++ b/collects/plot/scribblings/utils.scrbl @@ -6,10 +6,12 @@ @defmodule[plot/utils] +@;==================================================================================================== @section{Formatting} @doc-apply[digits-for-range]{ -Given a range, returns the number of decimal places necessary to distinguish numbers in the range. This may return negative numbers for large ranges. +Given a range, returns the number of decimal places necessary to distinguish numbers in the range. +This may return negative numbers for large ranges. @examples[#:eval plot-eval (digits-for-range 0.01 0.02) @@ -17,7 +19,8 @@ Given a range, returns the number of decimal places necessary to distinguish num } @doc-apply[real->plot-label]{ -Converts a real number to a plot label. Used to format axis tick labels, @(racket point-label)s, and numbers in legend entries. +Converts a real number to a plot label. +Used to format axis tick labels, @(racket point-label)s, and numbers in legend entries. @examples[#:eval plot-eval (let ([d (digits-for-range 0.01 0.03)]) @@ -27,14 +30,110 @@ Converts a real number to a plot label. Used to format axis tick labels, @(racke (real->plot-label 1000000000.1234 4)] } +@doc-apply[ivl->plot-label]{ +Converts an interval to a plot label. + +If @racket[i] = @racket[(ivl x-min x-max)], the number of digits used is @racket[(digits-for-range x-min x-max 10 extra-digits)] when both endpoints are @racket[rational?]. +Otherwise, it is unspecified---but will probably remain @racket[15]. +@examples[#:eval plot-eval + (ivl->plot-label (ivl -10.52312 10.99232)) + (ivl->plot-label (ivl -inf.0 pi))] +} + @doc-apply[->plot-label]{ Converts a Racket value to a label. Used by @(racket discrete-histogram) and @(racket discrete-histogram3d). } @doc-apply[real->string/trunc]{ -Like @(racket real->decimal-string), but removes trailing zeros and a trailing decimal point. +Like @(racket real->decimal-string), but removes any trailing zeros and any trailing decimal point. } +@doc-apply[real->decimal-string*]{ +Like @racket[real->decimal-string], but accepts both a maximum and minimum number of digits. +@examples[#:eval plot-eval + (real->decimal-string* 1 5 10) + (real->decimal-string* 1.123456 5 10) + (real->decimal-string* 1.123456789123456 5 10)] +Applying @racket[(real->decimal-string* x min-digits)] yields the same value as @racket[(real->decimal-string x min-digits)]. +} + +@doc-apply[integer->superscript]{ +Converts an integer into a string of superscript Unicode characters. +@examples[#:eval plot-eval + (integer->superscript -1234567890)] +Systems running some out-of-date versions of Windows XP have difficulty with Unicode superscripts for 4 and up. +Because @racket[integer->superscript] is used by every number formatting function to format exponents, if you have such a system, PLoT will apparently not format all numbers with exponents correctly (until you update it). +} + +@;{ +@doc-apply[format-tick-labels]{ +} +} + +@;==================================================================================================== +@section{Sampling} + +@doc-apply[linear-seq]{ +Returns a list of uniformly spaced real numbers between @(racket start) and @(racket end). +If @(racket start?) is @(racket #t), the list includes @(racket start). +If @(racket end?) is @(racket #t), the list includes @(racket end). + +This function is used internally to generate sample points. + +@examples[#:eval plot-eval + (linear-seq 0 1 5) + (linear-seq 0 1 5 #:start? #f) + (linear-seq 0 1 5 #:end? #f) + (linear-seq 0 1 5 #:start? #f #:end? #f) + (define xs (linear-seq -1 1 11)) + (plot (lines (map vector xs (map sqr xs))))] +} + +@doc-apply[linear-seq*]{ +Like @(racket linear-seq), but accepts a list of reals instead of a start and end. +The @(racket #:start?) and @(racket #:end?) keyword arguments work as in @(racket linear-seq). +This function does not guarantee that each inner value will be in the returned list. + +@examples[#:eval plot-eval + (linear-seq* '(0 1 2) 5) + (linear-seq* '(0 1 2) 6) + (linear-seq* '(0 1 0) 5)] +} + +@doc-apply[nonlinear-seq]{ +Generates a list of reals that, if transformed using @(racket transform), would be uniformly spaced. +This is used to generate samples for transformed axes. +@examples[#:eval plot-eval + (linear-seq 1 10 4) + (nonlinear-seq 1 10 4 log-transform) + (parameterize ([plot-x-transform log-transform]) + (plot (area-histogram sqr (nonlinear-seq 1 10 4 log-transform))))] +} + +@;{ +@doc-apply[build-linear-seq] +@doc-apply[make-function->sampler] +@doc-apply[make-2d-function->sampler] +@doc-apply[make-3d-function->sampler] +@doc-apply[sample-exact->inexact] +@doc-apply[2d-sample-exact->inexact] +@doc-apply[3d-sample-exact->inexact] +} + +@defstruct[mapped-function ([f (any/c . -> . any/c)] [fmap ((listof any/c) . -> . (listof any/c))])]{ +Represents a function that maps over lists differently than @(racket (map f xs)). + +With some functions, mapping over a list can be done much more quickly if done specially. +(An example is a piecewise function with many pieces that first must decide which interval its input belongs to. Deciding that for many inputs can be done more efficiently by sorting all the inputs first.) +Renderer-producing functions that accept a @(racket (real? . -> . real?)) also accept a @(racket mapped-function), and use its @(racket fmap) to sample more efficiently. +} + +@doc-apply[kde]{ +Given samples and a kernel bandwidth, returns a @(racket mapped-function) representing a kernel density estimate, and bounds, outside of which the density estimate is zero. +Used by @(racket density). +} + +@;==================================================================================================== @section{Plot Colors and Styles} @doc-apply[color-seq]{ @@ -133,9 +232,11 @@ Integer brush styles repeat starting at @(racket 7). (map ->brush-style '(4 5 6))] } +@;==================================================================================================== @section{Plot-Specific Math} -@subsection{Real Numbers} +@;---------------------------------------------------------------------------------------------------- +@subsection{Real Functions} @doc-apply[degrees->radians]{ Converts degrees to radians. @@ -145,45 +246,209 @@ Converts degrees to radians. Converts radians to degrees. } -@doc-apply[linear-seq]{ -Returns a list of evenly spaced real numbers between @(racket start) and @(racket end). -If @(racket start?) is @(racket #t), the list includes @(racket start). -If @(racket end?) is @(racket #t), the list includes @(racket end). - -This function is used internally to generate sample points. - -@examples[#:eval plot-eval - (linear-seq 0 1 5) - (linear-seq 0 1 5 #:start? #f) - (linear-seq 0 1 5 #:end? #f) - (linear-seq 0 1 5 #:start? #f #:end? #f)] +@doc-apply[polar->cartesian]{ +Converts 2D polar coordinates to 3D cartesian coordinates. } -@doc-apply[linear-seq*]{ -Like @(racket linear-seq), but accepts a list of reals instead of a start and end. -The @(racket #:start?) and @(racket #:end?) keyword arguments work as in @(racket linear-seq). -This function does not guarantee that each inner value will be in the returned list. - -@examples[#:eval plot-eval - (linear-seq* '(0 1 2) 5) - (linear-seq* '(0 1 2) 6) - (linear-seq* '(0 1 0) 5)] +@doc-apply[3d-polar->3d-cartesian]{ +Converts 3D polar coordinates to 3D cartesian coordinates. +See @racket[parametric3d] for an example of use. } -@doc-apply[nonlinear-seq]{ -Generates a list of reals that, if transformed using @(racket transform), would be evenly spaced. -This is used to generate samples for transformed axes. +@doc-apply[infinite?]{ +Returns @racket[#t] if @racket[x] is either @racket[+inf.0] or @racket[-inf.0]. @examples[#:eval plot-eval - (linear-seq 1 10 4) - (nonlinear-seq 1 10 4 log-transform) - (parameterize ([plot-x-transform log-transform]) - (plot (area-histogram sqr (nonlinear-seq 1 10 4 log-transform))))] + (map infinite? (list +inf.0 -inf.0 0 'bob))] } -@subsection[#:tag "math.vectors"]{Vectors} +@doc-apply[nan?]{ +Returns @racket[#t] if @racket[x] is @racket[+nan.0]. +@examples[#:eval plot-eval + (map nan? (list +nan.0 +inf.0 0 'bob))] +} +@doc-apply[ceiling-log/base]{ +Like @racket[(ceiling (/ (log x) (log b)))], but @racket[ceiling-log/base] is not susceptible to floating-point error when given an exact @racket[x]. +@examples[#:eval plot-eval + (ceiling (/ (log 1/1000) (log 10))) + (ceiling-log/base 10 1/1000)] +Various number-formatting functions use this. +} -@subsection[#:tag "math.intervals"]{Intervals} +@doc-apply[floor-log/base]{ +Like @racket[(floor (/ (log x) (log b)))], but @racket[floor-log/base] is not susceptible to floating-point error when given an exact @racket[x]. +@examples[#:eval plot-eval + (floor (/ (log 1000) (log 10))) + (floor-log/base 10 1000)] +Various number-formatting functions use this. +} + +@doc-apply[maybe-inexact->exact]{ +Returns @racket[#f] if @racket[x] is @racket[#f]; otherwise @racket[(inexact->exact x)]. +Use this to convert interval endpoints, which may be @racket[#f], to exact numbers. +} + +@;---------------------------------------------------------------------------------------------------- +@subsection[#:tag "math.vectors"]{Vector Functions} + +@doc-apply[v+] +@doc-apply[v-] +@doc-apply[vneg] +@doc-apply[v*] +@doc-apply[v/]{ +Vector arithmetic. Equivalent to @racket[vector-map]p-ing arithmetic operators over vectors, but specialized so that 2- and 3-vector operations are much faster. +@examples[#:eval plot-eval + (v+ #(1 2) #(3 4)) + (v- #(1 2) #(3 4)) + (vneg #(1 2)) + (v* #(1 2 3) 2) + (v/ #(1 2 3) 2)] +} + +@doc-apply[v=]{ +Like @racket[equal?] specialized to numeric vectors, but compares elements using @racket[=]. +@examples[#:eval plot-eval + (equal? #(1 2) #(1 2)) + (equal? #(1 2) #(1.0 2.0)) + (v= #(1 2) #(1.0 2.0))] +} + +@doc-apply[vcross]{ +Returns the right-hand vector cross product of @racket[v1] and @racket[v2]. +@examples[#:eval plot-eval + (vcross #(1 0 0) #(0 1 0)) + (vcross #(0 1 0) #(1 0 0)) + (vcross #(0 0 1) #(0 0 1))] +} + +@doc-apply[vcross2]{ +Returns the signed area of the 2D parallelogram with sides @racket[v1] and @racket[v2]. +Equivalent to @racket[(vector-ref (vcross (vector-append v1 #(0)) (vector-append v2 #(0))) 2)] but faster. +@examples[#:eval plot-eval + (vcross2 #(1 0) #(0 1)) + (vcross2 #(0 1) #(1 0))] +} + +@doc-apply[vdot]{ +Returns the dot product of @racket[v1] and @racket[v2]. +} + +@doc-apply[vmag^2]{ +Returns the squared magnitude of @racket[v]. Equivalent to @racket[(vdot v v)]. +} + +@doc-apply[vmag]{ +Returns the magnitude of @racket[v]. Equivalent to @racket[(sqrt (vmag^2 v))]. +} + +@doc-apply[vnormalize]{ +Returns a normal vector in the same direction as @racket[v]. If @racket[v] is a zero vector, returns @racket[v]. +@examples[#:eval plot-eval + (vnormalize #(1 1 0)) + (vnormalize #(1 1 1)) + (vnormalize #(0 0 0.0))] +} + +@doc-apply[vcenter]{ +Returns the center of the smallest bounding box that contains @racket[vs]. +@examples[#:eval plot-eval + (vcenter '(#(1 1) #(2 2)))] +} + +@doc-apply[vrational?]{ +Returns @racket[#t] if every element of @racket[v] is @racket[rational?]. +@examples[#:eval plot-eval + (vrational? #(1 2)) + (vrational? #(+inf.0 2)) + (vrational? #(#f 1))] +} + +@;---------------------------------------------------------------------------------------------------- +@subsection[#:tag "math.intervals"]{Intervals and Interval Functions} + +@defstruct[ivl ([min real?] [max real?])]{ +Represents a closed interval. + +An interval with two real-valued endpoints always contains the endpoints in order: +@interaction[#:eval plot-eval (ivl 0 1) (ivl 1 0)] + +@;{ +If either endpoint is @racket[+nan.0], both are, and the interval represents the empty interval: +@interaction[#:eval plot-eval (ivl +nan.0 0) (ivl 0 +nan.0)] +} + +An interval can have infinite endpoints: +@interaction[#:eval plot-eval (ivl -inf.0 0) (ivl 0 +inf.0) (ivl -inf.0 +inf.0)] + +Functions that return rectangle renderers, such as @racket[rectangles] and @racket[discrete-histogram3d], accept vectors of @racket[ivl]s as arguments. +The @racket[ivl] struct type is also provided by @racketmodname[plot] so users of such renderers do not have to require @racketmodname[plot/utils]. +} + +@doc-apply[rational-ivl?]{ +Returns @racket[#t] if @racket[i] is an interval and each of its endpoints is @racket[rational?]. +@examples[#:eval plot-eval + (map rational-ivl? (list (ivl -1 1) (ivl -inf.0 2) 'bob))] +} + +@;{ +@doc-apply[empty-ivl]{ +The empty interval. +} + +@defproc[(ivl-meet [i ivl?] ...) ivl?]{ +Returns the intersection of the given intervals. +@examples[#:eval plot-eval + (ivl-meet) + (ivl-meet (ivl 0 1) (ivl 2 3)) + (ivl-meet (ivl 0 2) (ivl 1 3)) + (ivl-meet empty-ivl (ivl 0 1))] +} + +@defproc[(ivl-join [i ivl?] ...) ivl?]{ +Returns the smallest interval that contains all the points in the given intervals. +@examples[#:eval plot-eval + (ivl-join) + (ivl-join (ivl 0 1) (ivl 2 3)) + (ivl-join (ivl 0 2) (ivl 1 3)) + (ivl-join empty-ivl (ivl 0 1))] +Think of it as returning an interval union, but with any gaps filled. +} + +@doc-apply[ivl-center]{ +@examples[#:eval plot-eval + (ivl-center (ivl -1 1)) + (ivl-center empty-ivl) + (ivl-center (ivl -inf.0 +inf.0))] +} + +@doc-apply[ivl-contains?]{ +@examples[#:eval plot-eval + (ivl-contains? (ivl -1 1) 0) + (ivl-contains? (ivl -1 1) 2) + (ivl-contains? (ivl -inf.0 +inf.0) 0) + (ivl-contains? empty-ivl 0)] +} + +@doc-apply[ivl-empty?]{ +@examples[#:eval plot-eval + (ivl-empty? empty-ivl) + (ivl-empty? (ivl 0 0))] +} + +@doc-apply[ivl-length]{ +@examples[#:eval plot-eval + (ivl-length empty-ivl) + (ivl-length (ivl 0 0)) + (ivl-length (ivl -1 1)) + (ivl-length (ivl -inf.0 +inf.0))] +} + +@doc-apply[ivl-inexact->exact] +@doc-apply[ivl-rational?] +@doc-apply[ivl-singular?] +@doc-apply[ivl-translate] +@doc-apply[ivl-zero-length?] +} @doc-apply[bounds->intervals]{ Given a list of points, returns intervals between each pair. @@ -192,37 +457,78 @@ Use this to construct inputs for @(racket rectangles) and @(racket rectangles3d) @examples[#:eval plot-eval (bounds->intervals (linear-seq 0 1 5))] } -@subsection[#:tag "math.rectangles"]{Rectangles} +@;---------------------------------------------------------------------------------------------------- +@;{ +@subsection[#:tag "math.rectangles"]{Rectangles and Rectangle Functions} +@margin-note*{The @racket[rect-meet] and @racket[rect-join] functions define a @link["http://en.wikipedia.org/wiki/Lattice_%28order%29"]{pointed lattice} over rectangles. + This fact may seem esoteric, but it allows PLoT to combine multiple renderers with different rectangular bounds in a way that is intuitive and mathematically sound.} +@defproc[(rect-meet [i (vectorof ivl?)] ...) (vectorof ivl?)]{ +} +@defproc[(rect-join [i (vectorof ivl?)] ...) (vectorof ivl?)]{ +} + +@doc-apply[empty-rect] +@doc-apply[rect-area] +@doc-apply[rect-center] +@doc-apply[rect-contains?] +@doc-apply[rect-empty?] +@doc-apply[rect-inexact->exact] +@doc-apply[rect-known?] +@doc-apply[rect-rational?] +@doc-apply[rect-singular?] +@doc-apply[rect-translate] +@doc-apply[rect-zero-area?] +@doc-apply[rational-rect?] +@doc-apply[bounding-rect] +} + +@;==================================================================================================== +@;{ +@section{Marching Squares and Cubes} + +@doc-apply[heights->cube-polys] +@doc-apply[heights->lines] +@doc-apply[heights->polys]{ +winding warning +} +} + +@;==================================================================================================== @section{Dates and Times} @doc-apply[datetime->real]{ +Converts various date/time representations into UTC seconds, respecting time zone offsets. + +For dates, the value returned is the number of seconds since @italic{a system-dependent UTC epoch}. +See @racket[date-ticks] for more information. + +To plot a time series using dates pulled from an SQL database, simply set the relevant axis ticks (probably @racket[plot-x-ticks]) to @racket[date-ticks], and convert the dates to seconds using @racket[datetime->real] before passing them to @racket[lines]. +To keep time zone offsets from influencing the plot, set them to @racket[0] first. + +Does @racket[sql-time?] work? + +@racketmodname[db/base] } @defstruct[plot-time ([second (and/c (>=/c 0) (seconds] - -@doc-apply[seconds->plot-time] - - -@section{Sampling} - -@defstruct[mapped-function ([f (any/c . -> . any/c)] [fmap ((listof any/c) . -> . (listof any/c))])]{ -Represents a function that maps over lists differently than @(racket (map f xs)). - -With some functions, mapping over a list can be done much more quickly if done specially. -(An example is a piecewise function with many pieces that first must decide which interval its input belongs to. Deciding that for many inputs can be done more efficiently by sorting all the inputs first.) -Renderer-producing functions that accept a @(racket (real? . -> . real?)) also accept a @(racket mapped-function), and use its @(racket fmap) to sample more efficiently. -} - -@section{Denity Estimation} - -@doc-apply[kde]{ -Given samples and a kernel bandwidth, returns a @(racket mapped-function) representing a kernel density estimate, and bounds, outside of which the density estimate is zero. Used by @(racket density). +@doc-apply[seconds->plot-time]{ +Convert @racket[plot-time]s to real seconds, and vice-versa. +@examples[#:eval plot-eval + (define (plot-time+ t1 t2) + (seconds->plot-time (+ (plot-time->seconds t1) + (plot-time->seconds t2)))) + (plot-time+ (plot-time 32 0 12 1) + (plot-time 32 0 14 1))] } diff --git a/collects/plot/utils.rkt b/collects/plot/utils.rkt index 066fc37a58..30b9529448 100644 --- a/collects/plot/utils.rkt +++ b/collects/plot/utils.rkt @@ -13,7 +13,8 @@ "contracted/samplers.rkt" "contracted/legend.rkt" "contracted/plot-element.rkt" - "contracted/date-time.rkt") + "contracted/date-time.rkt" + "contracted/kde.rkt") (provide (all-from-out "common/contract.rkt") (all-from-out "common/marching-squares.rkt") @@ -28,4 +29,5 @@ (all-from-out "contracted/samplers.rkt") (all-from-out "contracted/legend.rkt") (all-from-out "contracted/plot-element.rkt") - (all-from-out "contracted/date-time.rkt")) + (all-from-out "contracted/date-time.rkt") + (all-from-out "contracted/kde.rkt")) From bba824e1c6a82a45afa5d7020a7acd497108b1dc Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Mon, 23 Jan 2012 15:54:56 -0700 Subject: [PATCH 526/746] Removed test byproducts accidentally committed in d020c75202f92873d02998b81bfc4085506df5cf Please merge into release (cherry picked from commit f966ea8876ded12b896e23afb63d0441882fe05a) --- collects/plot/tests/sqr.png | Bin 12128 -> 0 bytes collects/plot/tests/trig.png | Bin 70211 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 collects/plot/tests/sqr.png delete mode 100644 collects/plot/tests/trig.png diff --git a/collects/plot/tests/sqr.png b/collects/plot/tests/sqr.png deleted file mode 100644 index 15de9a7a26114df6d9137d5a1899595d2905a3bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12128 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 JSIC;Z`(H4MQDguB diff --git a/collects/plot/tests/trig.png b/collects/plot/tests/trig.png deleted file mode 100644 index e2b219a544bcdf3cf5996c50097cae66c8c8ed8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70211 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�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 G4ETTJ0J$Up From 9ee130dc49ea41f7c4649e4b2b948cab5f6dc9ca Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 24 Jan 2012 05:17:52 -0500 Subject: [PATCH 527/746] `sort' now infers properly -- test passes. Please merge to release. (cherry picked from commit f70c1b213ff5861630a5d10a3d38ee3a4cea3156) --- .../typed-racket/{fail/sort.rkt => succeed/sort-infer.rkt} | 2 -- 1 file changed, 2 deletions(-) rename collects/tests/typed-racket/{fail/sort.rkt => succeed/sort-infer.rkt} (51%) diff --git a/collects/tests/typed-racket/fail/sort.rkt b/collects/tests/typed-racket/succeed/sort-infer.rkt similarity index 51% rename from collects/tests/typed-racket/fail/sort.rkt rename to collects/tests/typed-racket/succeed/sort-infer.rkt index 0e61eaacaf..c53e3c82db 100644 --- a/collects/tests/typed-racket/fail/sort.rkt +++ b/collects/tests/typed-racket/succeed/sort-infer.rkt @@ -1,5 +1,3 @@ -#; -(exn-pred exn:fail:syntax? #rx".*Cannot infer.*Please add more type annotations.*") #lang typed/racket (define ss '("one" "two" "three")) ; (Listof String) (sort ss string Date: Tue, 24 Jan 2012 07:23:06 -0500 Subject: [PATCH 528/746] Include the platform in the windows installer's "human name". (Otherwise having both installed can be confusing since the uninstaller has the same name; also, it's good to make a reminder for people who want the other one.) Also, just use the platform string in the registry key uniformly. Also add a comment about detecting Win64 if it's desirable in the future. (cherry picked from commit d21e646327e499dbb056fafeb97c681ce4d7bba2) --- collects/meta/build/build | 8 ++++---- collects/meta/web/download/download-pages.rkt | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index f050dc0ec6..b2268d4ebc 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -1795,10 +1795,11 @@ tgz_to_exe() { show "Writing \"racket-defs.nsh\"" { local def='!define' local distname="$(name_of_dist_package "$pname")" + local winplatform="${srcplatform%-win32}" echo "$def RKTVersion \"$version\"" # this must be four numbers echo "$def RKTVersionLong \"$version1.$version2.$version3.$version4\"" - echo "$def RKTHumanName \"$distname v$version\"" + echo "$def RKTHumanName \"$distname v$version ($winplatform)\"" if [[ "$releasing" != "yes" ]]; then echo "$def RKTStartName \"$distname v$version\"" else @@ -1810,11 +1811,10 @@ tgz_to_exe() { else echo "$def RKTDirName \"$distname\"" fi - if [[ "$srcplatform" = "x86_64-win32" ]]; then - echo "$def RKTRegName \"${distname}-64-$version\"" + echo "$def RKTRegName \"$distname-$winplatform-$version\"" + if [[ "$winplatform" = "x86_64" ]]; then echo "$def RKTProgFiles \"\$PROGRAMFILES64\"" else - echo "$def RKTRegName \"$distname-$version\"" echo "$def RKTProgFiles \"\$PROGRAMFILES\"" fi if [[ "$pname" = "mz" ]]; then echo "$def SimpleInstaller"; fi diff --git a/collects/meta/web/download/download-pages.rkt b/collects/meta/web/download/download-pages.rkt index a0ba3c3d66..ad4c46a66b 100644 --- a/collects/meta/web/download/download-pages.rkt +++ b/collects/meta/web/download/download-pages.rkt @@ -148,6 +148,11 @@ Solaris = /Solaris/; if (p == null) return []; else if (l("SunOS")) return [Solaris, Unix]; + @; Note about Windows 64: seems like the best guess could be done by + @; checking that the platform has "Win64" or navigator.userAgent has + @; either "Win64" or "WOW64". But the 32 build might be better for many + @; people anyway, so keep things as is for now. (With the `Win' filter + @; which will get the 32 version first and the 64 second.) else if (l("Win")) return [Win]; else if (l("Mac")) return [(l("Intel")?MacIntel:MacPPC), Mac, Unix]; else if (l("Linux")) { From 25e59f69b4a4052c683d7f1c16e30658c8aff3be Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Tue, 24 Jan 2012 10:49:11 -0500 Subject: [PATCH 529/746] Typed Racket HISTORY for 5.2.1. Please merge to release. (cherry picked from commit b839b03d4b450072376df0a537bcd7f956585eb4) --- doc/release-notes/typed-racket/HISTORY.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/release-notes/typed-racket/HISTORY.txt b/doc/release-notes/typed-racket/HISTORY.txt index 2ad33e3472..3e66e3aa08 100644 --- a/doc/release-notes/typed-racket/HISTORY.txt +++ b/doc/release-notes/typed-racket/HISTORY.txt @@ -1,3 +1,7 @@ +5.2.1 +- Inference of functions with keyword arguments +- `typecheck-fail' for explicit creation of type errors +- Extensive documentation of typed numeric tower 5.2 - Performance work: delayed environment evaluation - Support `racket'-style optional arguments From 545f4187e61e2c057d3be518eec4c4a48723d36a Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 24 Jan 2012 15:19:57 -0700 Subject: [PATCH 530/746] db: fix sqlite3 #:use-place for raco exe (cherry picked from commit 0b3691691abfe73944f5209d9cad68a90de13257) --- collects/db/private/generic/place-client.rkt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/collects/db/private/generic/place-client.rkt b/collects/db/private/generic/place-client.rkt index 9f373a0fd3..d4fccad936 100644 --- a/collects/db/private/generic/place-client.rkt +++ b/collects/db/private/generic/place-client.rkt @@ -4,6 +4,8 @@ racket/place racket/promise racket/serialize + racket/runtime-path + (for-syntax (only-in racket/base quote)) ffi/unsafe/atomic "interfaces.rkt" "prepared.rkt") @@ -15,6 +17,9 @@ (define (pchan-get chan) (deserialize (place-channel-get chan))) +(define-runtime-module-path-index _place-server + 'db/private/generic/place-server) + (define connection-server-channel (delay/sync (dynamic-place 'db/private/generic/place-server 'connection-server))) From a4a30200e5f78864be65481196adc08250748a89 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 30 Jan 2012 14:01:06 -0700 Subject: [PATCH 531/746] tighten bound for Mac OS X 10.6 localtime() hack It looks like my bound for last time was too conservative, in that I looked for the lowest number that didn't seem to fail in 10.6. The range of failing values is apparently not continuous. I've tightened the bound to match the lowest number that produces a useful result on my 10.7 machine, assuming that it works for a continuous range there. (The new bound is higher than the number previously used as a lower bound.) Merge to 5.2.1 (cherry picked from commit ef846caaa14c185ffe4e46a1a4f119a35ff37c34) --- src/racket/sconfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racket/sconfig.h b/src/racket/sconfig.h index e101001619..dad9257be6 100644 --- a/src/racket/sconfig.h +++ b/src/racket/sconfig.h @@ -768,7 +768,7 @@ #if defined(__x86_64__) /* work around a bug in localtime() in 10.6.8 */ -# define MIN_VALID_DATE_SECONDS -67768122973193999 +# define MIN_VALID_DATE_SECONDS -67768040609715600 #endif # define FLAGS_ALREADY_SET From 260ef1e43d6ef2834ad69b369f9ab1e5c37e15e4 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 20 Jan 2012 11:39:41 -0500 Subject: [PATCH 532/746] Move the dmg build to weatherwax (which can now deal with it. ) Also, remove attempt for a smart use of `fmt' -- the problem is that now "$platform" is not set, so the conditional didn't do anything. It would be easy to get a conditional using `uname', but better to drop the whole thing. (cherry picked from commit 2a1464b49ee06a85a269dfc94ffb8abe590858f3) --- collects/meta/build/build | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/collects/meta/build/build b/collects/meta/build/build index b2268d4ebc..f2f2c833d1 100755 --- a/collects/meta/build/build +++ b/collects/meta/build/build @@ -53,7 +53,7 @@ workmachine="winooski" maindir="/home/scheme" # machines for specific installer creations -dmgmachine="kauai" +dmgmachine="weatherwax" nsismachine="pitcairn" # list of environment variables that should be carried over to ssh jobs @@ -479,17 +479,10 @@ show() { if [[ "x$1" = "x-s" ]]; then shift; write_status "$*"; fi if [[ "$verbose" = "yes" ]]; then echo "" - case "$platform" in - ( *"-linux"* | "sparc-solaris" | *"-win32" ) - echo ">>> $*" | fmt -t -w 79 - ;; - ( *"-freebsd" | *"-osx-mac" | *"-darwin" ) - echo ">>> $*" | fmt -w 79 - ;; - ( * ) - echo ">>> $*" | fmt - ;; - esac + # It would be nice to use something like + # echo ">>> $*" | fmt -p '>>>' -w 79 + # but on osx fmt doesn't do that kind of stuff + echo ">>> $*" fi } From ebeca8914510870c80c30a34859b5daaf1eb856e Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 31 Jan 2012 21:09:40 -0600 Subject: [PATCH 533/746] added in smaller size icons in an attempt to see if that was the problem on 10.5 and 10.4 (cherry picked from commit 5db88e3ea7b29f4fd3c05408becb8114c0f14a6d) --- src/mac/icon/Starter.icns | Bin 177382 -> 90858 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/mac/icon/Starter.icns b/src/mac/icon/Starter.icns index e4c38b4111532e76301e574ef93a237929d57a0e..066de4a498bffe67ffbc56ffb67539b6ef18b9e7 100644 GIT binary patch delta 41530 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 delta 127919 zcmc$_WmH>T)HR9~mjcDzLR(x46ff?S3R1ji3j`?=^gyxV?vNB{p%iy_cXtUvibK%g zd_3Pf-f{omANS_Z+2f2P=d8Wgo@>py*52)Y@^1&9`HKbk8yZH{zYp5-%xGw6)L$(4 z#n8~&FCVY3(a=viD*yewZs+`;aoAfeWg>i9{KxMRsj4WvLqo%O9Acp1Vn1HaAXC?s zB-tXE08XscyeFf($^Mem>m#kDwBZOM{a=b9vS?U=%%FrI&G)}PYFIxH*EJ|2Q+-eP zl2SD+vFLMHj@7&%Udlm*Dt})x?$dxa?4a($&!_ucS&~vh%Tf&RQ`FtV)zRINFRIy3 zN5- z_pt!R|4Vy|!f`+7cIzh787QsJM7Nz^N`T=DEZnsvk!`yXZRgZtx~3lnd3f2JtVru9 z9vBD1I+GX(et)D1uwx7`bZ)Ev_lAq^IhzykgcMSFKchQwm=RY5j}$32LnVQ%u)xi@ zMV3x==QS-$If58^G8lS$j=Nv4>aPvw7T2dWw)H0Uj!aS}1ThNvF+}&6EAc%(*7u9* zW3BYTN0Jsy3YM$!m+4f;9Fq^K!xeXGBil5o0_YrM>vu5p-60noXkR5Ihh9Q{l9wtl>j7lZ3AV_O+`owd19Lw-Fibhn3o zquQh=pU=c}b0vD6aA0MIhOgCcuyvW7cA|Zu7e?cubQaz%S;?#B14-3sI_& zf_{{DFWQ4?J8=beq8#A}4YZ_n9;vbchq$*e>Tps@V;6iGg9s-2=BK-oB%we@BH z{Y7C)^~(Z54AC!GUPRADcR)$YCYz+&sMNzey{@CsEjP)LW#{T0R+wU=6dW9<1+6tA z+Xs!F!f~758G_|k^5{ybV1itV_Zqq#f*7?5SS6PJbsQp1OFs->V%*X9F1vlL_OQW$@S}v|hW5>PlQ_xIJw^sf1G<)79vWoZ@0zgJqtj*zW=vjJf5S4BBf(`VHm{*6 z3=NitV4yFkZWx>$< zRt6z&FctBPP%^7uuTX(*c{bo4bqg7ga<4gy#+p7lM%sOntYbp2YNdXLn(@4&bedbP z6dcJFpeUj!2`0K~w#=I(@G{_&Qh5 zL@n32KzQ*$P3VJsc5i$Y(}Yj`k1Oc{gErl+cJX_y zyf@AI9kDB3xi+cXHQQ=zh@jJ$(CmH z-eeaf@YN7``aL=YYQh-kW+k zXLo8OQF{_E^i@R{Q=ESz^nX{lRxKxo<8^H27SBv&|NgCK0?lX?4t2238PW@39jy#n zAb~GZA$o*tTcR$?sI+JzYW1`(JYIVOx{bdEaE$_Si#GUBw8EwhMvA2Rhx%Oc-X^5r zCf2#At*b8I%|oQC%w>g0R8M+#KtR?_;q`$CEd$4Z|V|Gu-8B;-q!)=>`$YHxn7BOJq-x!3;Uy7YC+wlnG4YL_p zm4dIIy>}1>gqGLzDLeS?urN!TA^s)Y>qXF2{=xyx z)O&3$O{oXkoGw6N&(05H)vDPEdudS00YZA#Bx$0Mutl)Qt^OFR$pZF7(~S}iQ?wjo zanHn~!!4mUkpJeO*yWVy2wQ^8bEIdGNK~JOq2aW|%VDxn-eIF$&8&mOO=O|DjBd8l z2z~)BQGK)b3{2-!Gu?0|dU_BDtd~69;6(Ra;JgL{VjdMKG|MDs;#~&Yg?a{BD}yzO zNue4ul71XBg4IkCY*jV1H^Xo&8 znU@wZ!2@lLFS8rW>+dRW`-ZGbZ0h|Embu9>_Su^9>X6m$c88Vf>NYY$LZ?eYkg}&u z>|r;6s()|2_f5f4d!AkpT}*6n12=Zk1e_Jx@7=GFA7q7f9o}|M_u_h2tH709;n5dC ze5fi!GqaTm*p*K|ajd}cma)u$iKc!X>gCXBF+DKWSjIczJAN4M(S5>J<*-5_IzC+% z{>m2{dpBFRF!(D)A@ZA>!pu zh^YJ`glnGZt(e741Q$E@AI0QV~ zGOEiFjg0O1UQERwaAeRX-Lh`F8m3?Dz&elV9BZo26)J}l-cHOZ7#W~NS6?GZBCc0! zK~-Svw|aj+HffL9GM9@^iqCb4W61v@UyZ_y4$ej#kJ&~#1;|vr_IKYcXSgm2D0vg& zzUXEtT=hcCb8ZIz8-1NW#lObzi)!FgyU2$#^P88RZH3dG+e2?W7}HY(4C?49Df2p~ zrn>okcU)4_p?H&%mF8amTvE|9>m}*_{i9r>G`4fKx*;~4!$0WeETe4CH!Rk>_p$!R zPsLU7%Q04Ba$Ql_Q@1`YgihGxKZiB2g%_X2yH&opvch7=;JQ(N5m-aZRt78y{5L61 zB;JTbijUUnqoNJCUMAl~X``;q*4sMIuX`NvlCnuCIPXjvXB!;EBUCB~{(Pg(!ZRq3 z2Q$MwJ6wWyY|O|1828S5=IV65^w*qv!+!2&?&?}OrSy#pvMB$}jAWOxN&qd?Xjs&k zw=bC}-iNVq&vXBcTH*I`6Cinw5Jp*QBPlneY1F=fp70$Xgj+q}`e(|Tf4B}S>&qF6 z41{GPARxw+$Ez8-Q(&O+j5n}{9i2Q_eU+y=JZEjmR3LrFQk!oZ-P)GG6kMAx(_D47 zYwB7rXeN=ua3Qv{`EpT|p)=y=V=&4#uANYy8P3}%J;6PDNGTt{1gh~xfqDxzKG6kc zd8H*=k|@V9R~~aZ*w`r{ia#bHIb7irgDpMekBR(5DY0MQ;T9*G)%UV1@Dt9^gTd_J za1IBZa`qPPgi&YMvY~-_M+sZM=q^z~^|kFEQDwPG=^zse13&I@_*YSM=L_&5QO=7K z+Ng4V!3qL54{AC%KpqlW?!|f?!K<5-wq=Z>VOJ^9)RM6k@-q7Stdr$6yv0 zjJmLPqWi1{!kK<4!^Tg;tHDT;udNv(WWyKqZHq7D^v~((?CwDO3ElTj%!Gg|K14Bw z7WVywCN}pD-A3FLQ9idRjrckRqKC~gyM)iP!8C1_>-drX>G6M0deb=lxI6l`Hy^Q8 za%lZm<45)FM7l$BM$W8)&dx@6(LD(nodQCj>Ro|@5jd11_r+76BW%Y60mNumkR#V5 z?^dwO;?M^wDn_S&E3ynkQU6kna%Kll>l9)X_)_5Cl2zlQ4$0EJI@A-y4FAsJbY7pw z1Vz!oDX>EU5q4GaW1vmSW$q6EHLgN3=~6xo`@mr#mWqhrJa=Q(l@QPSw>DV4w6M*D@o+ z#v7ZA>errq#e$5^g&XD62iaTyS;m*sUnvK-dI7MF31KwHTtoAIBPsvONWP~$rU|Ey zD?g&AzP+*KoQqeS4jsp!i#pEE4!~q8nV!90RyGVt4ZI&UHCaGcm<^pAH9P^ZR$1_BP+pGFBC?Z@wwi@PdR8lZ+!m&>NY>OfB>P z=vdp904h~JD{H#phv9KDB(5f5ghR5dhm$yn$B+@TNj<(LW&Ec^@x4!psIi?2=d&-3 zJt#k^QKWFcjl-r^*bDSLFN3CcSv@?#s*+<6-YGkqxz85DR}b^sIRhs5_{C9%IsC zlLKr25mhvBgYqSgakD&nW!KY@UTtCSYX3Yknj{pD{U&a_oxLCjHVag7n`7|16)^Cw zhF?wn_P^N@_Z(A*iWU4@PKdY)C|;C#D&pw%>~7M@P)?hfEj-@jg$hGz^nfDI)p3PJ zZdlLBj~*$9(W6kpk;L%NlEIM7@^G#v=aZ?_neAP>+)x%V24V(jif9H23N5G@xpis3 zeCQXTT5o8IK)c#7SBNPjBS^5GmQJlfgz z>}Y!}o#4Ai#=CR+rt1EXQ-~!xnmDw257ZG7wQjzi_e$kH7uZSWxQ81B^&`nZ82Q@4 zPKJcprTUKOVYxgQ&;NxJI?s;m^EFJi?^faCE{z8KSOh&+l}6-yT>BRvt=Bc zMrcim4m`GzJQa2HMID()(?VYqMRc%aYg14_rU#$_Ate>CYRZ-+AKTThys^P z)X&{NpS&)9qDY)hsntKXCRqq>~wpj-2st`74S> zFWH9^8Y=fB&Cbt{F$J|nR)?0}u681*J+AVi5qT}q6aOUCNjx~!^ z_fCHIb`K;_idA{`Otfd37?HgrW&ggc%O`4J6s>#OiU)Cn^j_X9swYo#7Z{3TJON5- z&n}YbQb313+$X)?^NBcz)*q8UuYt%5ejp~HX4muwm5=>CRGBu32Uhd}hwhZg z$o?iblWJ>}`pp4jpv0)YC(Q4_D|6W~6*nVxzt`z?D_l@oIw15w1hLyDUa&V)O!7|D zJ{AjJ3QO8HPL*UDS>wLw+UxDK3ndO=3nfNCMYZk-@I~)#=iMQ9ZcPO-Qx+1Tz~7~d z1Bn%ei~TDx$f)Ri(5d|4;280!h|1)^-qQifdBAOy;7F(kD}>*S0O+_QyQ6WyQ$8=p=h z!MZM<0y?-Y2~WRAVDhb9RF9JdWc83_*3J$>Mii|e(AYl-g`=L;MezY`@if4q>6`Oo~*r!V_0+mNg( zj06XbNhTFw5snASAF=>YUE3B?vZlFR9n)NdE6SMtF=WC?P951Jv=HC4L+vmYFZHF< zE-=up2Rp;#zWI~Yns<48q)BNA25io8J^r37;hqdu-I05`4B!h+U0&MGH8@z*Ic(*X zfqh49FuMt0f42vexv{2Xa4e2XN`#o>d6dn^CqyuFAmi z5b}S{6UiHz;Hox60FNOyHp;i+6U~i#9esc_KGPbo-h3Nz@)Q=i^m6;M*sR%mr4?S| zD_`fkWxW)-rRKS;{>_YkU-moP`Q||7d!t#U`r)!iZQU_P6AvHgy!8eSTzlyYDrEy}X1&m!z^)M6juLmC%vVWx~rw)%i@>oq` z4JF`@9>E#@n-C^Ej1`fm%c*OGR6i2!TvsiB4)nK~Bcp@$Ow6Uixwvggu3rWplwBsd z?+qOpH=O+*HM`+C-eU3AU^HhGg@(RWcO~Mq%!X3L(2bh$rR^jlDZ^wh_)aM2|F{UT zV=P}3Z~d3coIa9go_6mgvc}`c8U^hIB!Cr7XumK{l|4jJB;^CXZ>%lKUgJI!%4A zClPdT2<`DYWW+d!W_2peU2L-io4=lfsDy+><^)xqvzoUtv=ZMUcWy6veIf>Yq4X%1 zrRisR){lG3;g_Hys(JV>_PFtl7Jd`A42z1Dz75OnLXiJ3jkeji zA2o2b%!kqKkY9byevk+J?w)Lwkhr^B<4=p@~HpKU*x9*hh$p6(cx^P!siw z1NS$EvHfK0)NDexnw4N3bAbH=u9Un}dsVl%Dg%yx7;=m{sUx8xj4Zt8rKUntO?$0H z(@L#4fk(`GE9wb;7lI;Z34-F{WHt8dcek1+Xr?LjY}cKTll$m9oQ^CHcwiSmrMupF zyGF@PSn=!-T`!tmn(TgG`{BrGzt6mPx)4n{2C0d)9QRBlT^`Yn1K^jPKtR~|@vJO?o-FKG$2l;xq3enFBz3{oF zUvN*~3W6!NiEu z`Bh9x2Z(!qxXBLaYm@*Vt{0bUEM1WZug{xv?-x=y=K^a7FulnS+hw3Enm^< z?wSaJ7Jp}qTB375T!_N5$}srldwNQ}vCsbJn|CYnYBc!as1&%T=i2^FQim99MQkHP zRzNBiZQ8i-Z$}>M*}cj^U$QF)@0HXO>aCl&&!49oOz3#QrT2b>rF8%7b#O5w$5fxl zvk>XgK0~~R%vmQ0*oJR$VonLrIN5ZTiqCxQ6`+AUL1N9&K%^v3hYAsHORP_A_Ek!X zAn*JgNw}-E9)QECDRR>gF3=S?DK01S(N>Zi1@NN`B)Qfyre^>i$F+R829HM>J;|7M zkn!?k6it8R1~piYF6u~-(1O`fmnjni18vLE&C8@75?&t7s5OawYN1Bh4hh276S{e{ z)LgwK@1uc~KqlU2c`P#=wrojD;*{-AJk)j}+I|9@-kLRi?&b}i&~LjN{m25DdlHD$ zQ%Ay7H2E9VB{DG&T?g(kxErcAwAmY;Yr-~ZY5B55OVYG?wJmOh<|EeePsaCpCHyRg z0zR*w+uV+)fLzbb>fX2i=Sggk ziyYuaU|9N0g5^&YRZHER_|+mrANj(aAt@TKSnyL<1heNAzHWz5=A$m8D+!kD0Q;1_ zUlTRJvVUIJ-(c)MtN3$K`plX9`1Zt`m_$ge3*#{<1IK(4?PHT_(m_ifZsZ=rYY z&R3rqNy#2TF)@GC)TU%Dbr%DiQz1@acN*5hG63=DlT}T0uFMZomt&~)s2`z0o8&DVD4(^_$$#qRHGlz) zpgM0gWC4WVb6SSWm;Utas9p_B^+YAtHCP6kNdb>+Y5Ow!0tMn4MtTANN8+bSrMpZO@!lKaJUPwKMBz z*`wB>49`LEU5m$}2hYl{BG&%91I91*W{WpaSj1|RO@DY*-`WzB!$Uz*1$?JzV$$L{(?{^^RoLn-5*Dv zJ3GX~}86ILz1Ao#z%7$m-%esf$`6KU% z$R`?=mwAD#kQ~_QXg_rABfmc zU1HQX-^qMhwY6}tBa@nSH}N1Q!zVYroq(SbP*#w>jp(Wo6IhmQQUn2q}fX@YP_ZG!7Rn>SNpDxet zMVfMfo04M4Pe)@Q-b@2rHg6juK}?T}l0i}~&9-`f1o`&Jxj;bSG&x6IN5#Yzui76r z;di9c&$~9`tBtzWzH>$!YPIQ6ejP?0qHd{^Nn51q_Z{(8n0XHV%DS?(4JI8KDkqzV z4^XJjSsDtW>W;ZRGm2(|+FXZGY9P!s%b2pU6isSDL3<#gkCiZKu#Oc;2Bm4%fo}q+Ax#R=PUf{(wa;?wzZLH7Dp%cW@>t{Mx)F75rF6 z64k+~0Fp#?diBipybrkegdWjT?}G!zs=4&lR)X}V^znM2=XuZE7$)4H(BTrt);f~p zVwew^1?;*OOdr%b5*_)>Hj5cn99p5+TN`Q};pj~n_h^SZa4y*7@Yf>V@HZpYm-b5) z&s@8i>2is)o=XFVJ`{=_ifCxeXsQZtK3wL?++uPIWkP>zY1M45%Y85>W3r77LNy=d zmtm~+Y`l_rFtd^#-`cU)K1sZY?4P94UQ}RF1y*%Z#Pd>md0tQE_e& zw*S~jpNi8+yGljHNLfr=zbwITqNe;e8nOkIqHejmE!59>-KZ1@zwmQvYCVQ+{WG~v znx9W0k#AjO_b12FRT^SG229=-Xj#%~}5q5v@`90A@?)nZg3PdNM5r%MUFdlgw1y-2Fyl|#y z@%4Cg7uKD}K;avZa--*sh*r5s$Le&?RsyL9aALo#gcCE6T2k=XH7 zjo@zKXe%Z7B*?^QLM46K4#SrRT zX)%=ARB>3AS_pRJ^!v}J0^`aVIZWBttLYTivbhsFI4|m>($pJ`qsYHgmgFH{2iVBM z2({P4+fLzS&4${YK?_G0S&Y5&y zR!4i^`2-ieqv;}R+3B@2k@5P(ctJ<40UrcV-f${Lzr9>Yh1dD=qB6bEZ@rV+tfeop zF8FSiA+oC6I$v;2f#(}`38oJVdU3I5L#_~NIEn1bI5&)+wRI30Q(7N^{e|7d3ft ze?%Qa#mN%h(Ycz{>cM%>NQ`KP9m(h@lSGl!G_Qn_2+IUou*+n2X7^-Q)J5I%2AGLp zzHW}_JFEe`wx}x6iI%f#i-AFvN{9-5XFigU)A)lY;pKwfT4|`)H~am77?M}02kUA< zWbz!PtW7%|fJRMdCw4P_Gt86unL)-+WPhQV=Zb%Hkgxfv`@urs=!rYc#(gYz*Y0sEF(8cn2Tfv#IoWJ-*LTvu) zVrSeN&rmHFY6X^O+~sM9xGOnx%^r>r+5~?NYrn)efYe8q+5=pd!+-9SOf!<{%d&_&)3Cji^+bC4|nMx>{xSHeJJklLG!|;2*uVb5-fDinZLcii+ekkZl$S9dda4SomQhYQz1OT z{i-dLfHwzuz%Ff3&K1LOyOf8y%gNc=+Ut`2r)-ZXp zr|BkxFBDlEa-!CS2~_fm|6RjO#G?((vge!0=KK1JSAot@XC})Vw544 z*8vHi&?8Jh|3MrjgG z_~}+EJna6o9u$Ycmc3EIO!uUc@{r)ovx4^sWSl%=4$+C2E6;_r-eG|lfSo})u4^Qps9e6TIg{4`4&UIq5;^5Z;?WInmCR~DZ!Lc)zP0UDF3Pt~ zXYrO?EbCi-%Zy~z4L9}I&XDeu&b#7%ewKA&C73c3zC+WZ<7O`W`T&s?)4bRRMY8MG zd2jxv>MSg6i7Z`irsOp}1kjVa$_d>r&9My;pyS;(zaniUl*9*357!;Ud!ty#HX%|O zW%FD|quJWB!yUla+5T@^T)tf2Zz2IQio;e8g5 zH1&KzFAm|?&}{79m#AXEj9B^LECYjg7MsPtMYtUdR{GZw@%I{{H;ellN(Zjhgs zAQp+6@VSLLMs+Eiee_R8-y3pKDfM3+-zpMe>eul;=R=a!i1&ByipllZ&FWtYJpo9^`e#IbD|el?{!YpILO@)7n{~f`^=)uX^eefKlRL4CpAW+ZB@(ro_6yJ!gkHKKjbr;PKC3}KV^6t z8hbpk0X=De-gWX$*LIcap#zr+(!SRN^3(AWSBxkP&W6Cd~T^Al}N&1NL6++!x< zl7Mz5OV;@2kY-WBlRifwxmWe(v$SMs7yK9QMs&Pr0aan;Jh&Wn3rK>6&0AbLSqA)K~02e*y(p;fv> zfNmCnX%RQJQP{N0k#V*g{7&_~5uTGDi?PCU(hbtc3Ht+H*XAGvAR4`K5yDNq+SIqmha$ z06#BFAH;>5!ZWrhzWrbP8gYh6>UQG!R&O}=uh{09uQAT_DqqM5>bKre34AXN+z%gY z@Z!2X>xe^!5vcU3Qdx-3f6k>%{+fimIY@I7Y~dPKKRQ4)b5@Bu9xn4@x9-+|>r+y> zv>9F1U`kPb?V|QM?+f93jj8z5&+dN#79q{m>z+>rnSNKNBersrR7r z?|cN+!w zwuLT}>JAOibGG0-zjJO_DBBG)-tzT^8S6Lk?rq_*m`Srjam+o%S8LYk1iICDh3`XW^nY$P?t2e zK{GfqPdkEcXqiLtC7*q4C%>N-%EvUB>Lu8vFI+V+iV#qdeUk(>lPf1G#9s-)YW`;S ze2LhH!O4?{sDYw!7LLBdIgqt4Rsk>kGrB6$HE1Lc8-A-DS61a~sJ~QApuzLevhk?r z04)Q{Y0LIOP-TGCFcJ76_L1Y5F1W!{iDN>N^{bAa6%DHn-#+06!O(UVFYa@pGzZo&~; z_wh_P?dgW|4}4Cvsme9ybyD|r?<}&`5YoQ;bK}kswONr&N~Mk?oX-DSen=xCqy^)_ zsu0OYj&Wt6Mf*M~JKHToDIJA~2TplnQ3geJ1=q$&1;~gkQvwuXMVhI=0#!!*Q&v5G z!a)?>4CBt;isjadt0iG{NMMZ698;Q1Sojyoc2@Vi^pWp7B@ga+b5KUTJicJHy!Gp99m)dvsb8T*zKl3==yrX=wWLN%+wkJ#uH!~ei=&ijFv0%`)yGu?4 zMms%Y{B0Ke+6E%%`|f&hqiYKtmnKKag5T!|b%y~(OetpW#cM#|!xFk0Ua#>Hg65m6<>j|I$) ztXnZ{&W@;Q@tBx0aGB^}xG2mm8W~PZTFsik*l~VcUtZ=3MM0zjCnxz$pJAW~V-F@k z?$5Wb8Kf9_QB|O|PK24sSj%jI$Po`EX$B3_?{T@xu#$@~ zy5tiT1*T|ihGd19A63aKWCD~N+;Yl&+?>LVv=q<2!ap)$NIpwQ%D-YIN-ToB}t>V-Izk zis+!V=U$Je157({6UqJUsF$`I7TXW5LLPYyg}nK@(<<%j5W@=87zkYi-F9m4u^g<# zbRB2ydpc@X*IsauloZ3$1TfxrKk^sDl-ROyW9U`o3DcLrh8NBWYgn>M7SXQMNhGV2 zm7GpV$HLmP3PdtN+=8^a9cX74QyGZy00eRzQI2%TT}QOPFbxK1jU@HDVjUJbiOZ(3c%a3FQ<>Y#?MV&$a$Uqjo z(Tt>0LwHDEoI7hY(UXpDA@g2h-pwYHYZg34hQH=8ft`xAw0`#fQ{8}%A#-{)be+7h z_fk9!tMeD(kp~}u`d^M8nSC=DB{Yl+XJCn=Y{_amp}uTdjN$X7w8gP6qfZ5t`dJO)ulIB; zM_os^zAv7J8R?4!-q=;_l)qP{{_Kc#7O&I35klwiHgm%d@alK@%i&qg>Mzq@VbqE1 zD)C1O?nDx{#TD|~lC|wFxl|fKw-R@09;$v%SEETNbE&UNxg zz@Zum%1%8wHMTw()y7r8kxHoqqPyt(S(_SXa5YyA|DKm&&ws{ZyZn@?B>i1|h>4Mw z2p&*6F7@3TxN1BegF+FVGW!NR?Q}zt3yJE?i$D<8~f&BnY878x^!R>{n@ukpe_@GKwiZ2{zKivy$9>KP@YO( z1W>zfq{`76$$?e#{Tyc)!`)j(&%fmBtk(oRxFac89Td&71?j6Y4ul~qw>K@*4x>Lv(IALrHKZ| z;u~quekoz&QLbY-~xc@7%CwI>CZbOCd`T|L);` zLarTFJ%rUvN+-H#u47Cg0=FcmrNIsXN9@3!Y+j&&ANhv?(+u1y0kZXTTf((5O(oZb zxT2tCeJooU5C#gN@nFvGHzVcqnJMM$_3FS+u3Q#-`u$a9c#r5Gk$v~Cu()CVo2LC&&n|cXfIe*{Yv%{11Wl zp@DZiC-c8QuoR||ju!>$^yPrUU*t>MMbS#HH?c{cvop$J8p;JS@sbZYX;=j0N72;= zN70E4mT+jh3;oNTks;?O}t7c`-j#!G5Q7_dI2J-=ToyNpo{ouGV>2s_EJq zTa7$D!M`8xPl=+p*&8f>{@_gwN?z&)K-V7_#HVt+($D7o=?$Oa!NztJh0WiE29wjS zP`=H4d-Ia;c8pW+m66dxh#Q7`$T%Xx{AlHsxgS{IQ6cOu#gC}o55DbK9mB!FaXpnd@2#7q`Rl-E2w?1w!?kK=29aE8*(EVGIDFCYJp#oi%^*$BtJdo( zRL~v&)gm=QxIRR=Pe&8mUe-J=8k5cP!pJ`|b}DK*z9Q>5!LdmaEV6v*TA!)4GE=+h zpvY(a=Nw{7s?8Uq=X^2x4v_$S*6;n*}HWlJU3UsaLiz_n07iLa08l z-_`}PNG0of_mYezWZ)Zj{x};`NL@l3oXaWQ+KDZX+a#~h1ghG-YA}M*f zYH>NhhT_MS2kFO7*HZ=>#FzA%r8$dyv`N4($7=)1Erb9I{(ia=xWZ$9Cub?nDmd&wmd#u69gq%W+g*wObjm7y*nLFtGXI)vF*hz9* zmCvyA;ta#*Q6~XlM@Z@8{1HD3iL!vz)!+NXQIql7ISjJ=%!3~c=3NdsvgwK*FYJ%C zA*%%1LB!gw?Gbexx}|*9XDl}G1>DV!-k5n@B0qPsp9kmZSYovk+Slz8*jVp=@q|d! zsDh3^bnaxQoD$SY*VZwPVrztCNr;9-P~~-=2~(}FiP(MwBEYQ_OTLCTVb&I>>|i`e zJu_=CVLID{V)tnyVr66x;umJx{a=1jNHqk;DSB+4W^vXfZY*Ntba=!$zXaf$&)Enn zQW$mrcz9@z*p!P`ll>N!;UjW8v__hy=_EV-c^UM(PVHUG?#o$M+^hRm=+5Lb7XkE9 z#6bSgCGbMS@^gv!8dk$qn7{T&SXOG8j`P!-Sck#djD_x+BJCl$iLEL}pP5xOC=P@^ z%#XBIo!!%%qnXkaGtv=6-!;*LT1LrI(~PSIxCb@TKG9Ur*jXw)`{b8Xk-%wB{u*0H zS&6IHDwo+JnrAEugx1+9ukxI#Q%7>Pt;2GJ1i&umr_a}BARv*trKU_M>G%651vFyF zKK!zn6aT4+`&=~h?KSpuJwoOx3&qumP^v2wQbNup6K2WFXJTkuZ0w5l3pRUU@@ORo8itE51p!rM0#u{j1PCKV) z8Vh4>{v3f^%Kb(Zd_4*OJ}4VxU003X#9xrL)TB7(ckH-t46CaIM7<*w;*FPLpDp`0znN3Eeg0>#RZWkvKh$~v@FLwEcco#kku=$|BluE{ZD9Ljx_Pp`dMBz9m+c$9oOJI)~Aebdm_E? zBu?f*3B_kP;@n+#N&Z1Np*bl_djOT&w4U&JXAL?I;yy=UG z{Yn*M?HAr>e((L4NA${8YyFff%MUD~7TU-kHx(>4x$bvZ+MoQjAV+Z4^Drn1u^B=& zpI#K?$d94HZsln~T81fh)O||yUtNN}qsXQ8Dd&(L$h+|B<}Uu$t{M>sxUrEud@dHh zAl<%rK9i-DL^4c|_i%e6dTi1P#OsrbHWqijIB+FjL#B`QXlH-g;j`z*i`|!{Qu!5c zxx)qe=#@lDlAA*qc^mhsEv8{te)IdJ>gW6m&z6aQ8Q8+kRh?3%NM3TZn))XsSkMd@ zLGLAvloEmV!13SEW?BdyP>WZm)Yc+FtTI1IGw{F71Q``O;cmATdix+MTrch?C}rW(UlSQw4DqHp`Gc{u_=U}@a*Y}s|E+~Hg~yI$eB z!r<;=bMr6nsTrgg+z*zRNpQ7H#%w;mYu1YN9siW}XJ*F7uu}T^Y^h_fmu-=-Xb}6< zC--#hOiH*Z1Ng6d!;u+7gV(D5@l4RSvUFl|olR3G`i6Ksv@eHrfyqdsPive!s!VT3 z?lXqVU+pO|UQd5@+b&)$E?eENZl?CT@AyA7eFayQU9>gbogyhIAuS-?4Tn(a?l^SU z1Coa>X*hHX(%oIslF}WL!l6Ijd%ruz{s(icwdY=I&bfIunNnhV^RU_6k{nP_6%_^E z=nh0Vt22cP<`%nc1(SVig145+f+YN=XpyhOYf8XUGyl|it~@Dm`49Lietme7=s^+p zenkVA9=uBmNLxM87xNbr?u1sOZ0R9uJE%Nrl@y=rY+lcc8zL{(Ss7^uqaHUGL`6!| zg-P!+Cz!^YN8oT*1P(45{*wMf`ltc2{q}ylam6Ey!~f8+kJbn=5QXquLqFWo#s`yEc2TAA>neShdfyY$I@&CP zPKj?ZQllh7v>h!&_N8)mMCKxeV)b z#WuAg-|sF#e&G6x(~@l~zD|~`p=@huTCBv8*XoMfe{&@xiT_sp7~j5Yo_cWlbZ&-t zXYtCR2fsQpyMA)__-55J01B`Kl2?Lox(De&4Jgnclh?`$lI*guYTtRm5#BwEa@TLO zMI>#pneSl(l=i)gp{prl0Y$h+18%_WKgqq{Pwh_#YlBmFS=>QD#J;rkG>IdcKW$@uU3q%S)vtEyU0Y zvA39J@fzeV8f>5)^L(-fXE&}LGCe`o_j3suG=>U5y8gTPm5a+L4oLjSQcA_{UUv7F zKsjoEPitOp;_hG91N09ba1Y-r?6ZU$>ACYR5Qi>_L?5gK)#K_H)x$*+spompYY(Ib zT0sS|i_-9}#Y>39iPhT)hZb}2DkM=b#ChjKYHlt37@4m4BT4U8FOL+Ct9oQT*Wkh1!yu#^8r$sjVM)JyjIX@~+0SJFBak zRy@CE!)jy7GwTVn9aJpi-%{O@{DB#k^gl$u(zXL0wNDKWsIML?)wCflb9Z_`={h8t ze4-FqEqXUb9Jtvt(Kd+s_h~}0$eH|FOJ5Y=b`^NUVZU>X_k3teFUic4ss!s&I9c#$ zW}jFlY50@LVLHMauS$g_)_EQfxQG)A#rkpIGtUL_U50?1lWQIz0g+NHe!gmIk8)K1 zCPZr{uJWrIu_bHEyi~y1V)yCYO>i)Spj7saPZ%C?x8u%(_C`2aeYHJF`;%c0e*qvc zC0)}013ImFmsB9yMHVr4AJ~gz1H#l99X@fbhtu9ZSpj$Ai>V}d zB{7sObZbix9^C~0Y6bw5xuN<{dCSr`Oz<{(L>5(RGJ zPNk}1@u9FN{=`vUKvHth^r#(y2H;)E7l}MTWci^y$)lgVD_4zI=tjzBlZ>WhKjo>6 z++x(hz!|q25+0^%O7K%Q1urM-n(%c`%=3l76_$64jbmT^>sN=R5#$nu>K3QM0H<@3k4Ftnbwm0U+XtssGa*pt6CZnl4AM97m3A(*8 z1KAkWzq*V>G^0sGh4`t*3L<+YbZTe*Xyz0{;WC%Zp}(eBn=ZbKgsg+!wBy#%(F3@K z55BuIp-$|KBN#^56oce&fR|eA?#@UOOnYkZr^WHtyt`nkK`2%tq?1V+TCM=0pwRK? zX2?efSzZ-B(}ds@Ym=v1-2`h#-nHz*iqr1Twcvl{2vM$G#NN^z9)Cbk*b=DqzB6P( z^jR{b+LJ;>qV2rIg0tDUtb}`O{!$sYitN(@zw@0G(yvaTuEXDDplVi&=uD8e_Gx3-pryDf~JR;mHl&7(sc?? zJ&p>O`|W9K=iXwc?%!-dHm^*^_H;MGE1JLMb}+;@9G!R;&G@+)Z`@3r-b_z!dy}Bc z)N@$`@3DZ$*K4YAUuIM}$q8o!qcV^bLIsr(@BNWFGyMr1<@dx(ydHUAsxBwC+ebpsVF)%bJ zWpu&ZKQ$5ph1km#{f!rZGgY1dbnXw*|(la~ygV&i4n@ z<YhMgtYvFg)uMnr$e^@iH~4-lhCzd*d4$U_DF8MI$OFP!1NX8@%YA83r)7ytk{x5eY6 z3K!?2$0OY%8O{#5o&(hXcy9B2($Wa+*w^rqndV`N9TQ28ID0UDx5s0m_L4na`dsgFIo*Xd6Yso<$&N} zKk{?S?uE%L5;0;%GJSmO>bfro`|-SbCNGo^??@eC3V7ibi#na^%K4lsKPHSYmb|FM(CMmB15%ssQ1~^OaYEX7iY81?Pnv*y_P5 z&V)KjnEk#99sZ#g0=Gh=O4&!;v(^J#T8K%oF>ps$3ue_veiuKQri}a25GzWnV6X|N zuKy-B;_PvM_ay2~;n%y6s+@^*y^opM4TKhRM#p)R3-e^hPSb!K{xY$5))I?4;;Y`mb#p3JNFsn_n-OWG&}L% ztMnE>$OU0aE`^G#X|@vXIk{)Rl~ae>)Cs_df=WXZ=f3)v2GkR-90+YCuY5t4oGo#Tv(uYq3Y_{S zCrfo_7``&1g;-OmD-bq`I?FFczDh-j*?glIw+Wjr*z5_X9`x4<$Wm_vWMRxHCPLWd zG9MUKYFM80Qmh%#{&7o7LUKI&PA}(2ydJhNp)Xm=rsLZLofe>fN~BDE2A+RN8P7*_ z9hyMbVPmKvG)c{H_j+*L@Wvcw{N9H~H`r}venI9N@=<) za~}^>vZVQ(RfeJkDL1tMiGJ@LO}a7CJlhTao0+9_eeKs`drV(;WiX+Sfc^X2X>{k2 zs!Qjkv=Ph6?e=yO8EYFej%V{y8Nfv~jRRNA^L62({xjlWH_VFdn8hA*Z+NXg?^g1^ zf4nGPAF39#YH7kLH9Fue2h`LH^oO#r%0>5RZqUkv!act`qnZcxb;TXKBXmp3k z4Ck7H3@L(8GyJzV92N8kC9dDo0k*8^fg+ruGUpt;52&5inZk_)F8x6+qqOVSp+fqp4H^L?UEmS2?0?62)?ehZWHqDa)!@hD~_Q%}!GI*#L z;aqD9Ga62k0)oi$k5V}s*MSNOigu_PZyOVgg_w<;!PHOA2>HLOlfhuM#CzsTW{mR< ze?_c!)|(&T*(v(9kR4anx><9SHn#?t!D?@kAY(W}hK9b3WehR z{e1@$u#=oV2I@_@dubjM={L?J7~M9O0_t1E&>tpntOzkClOu#;f@qN7>BSUZbp! zjo5vPAA+36T5LB3al-YMf^Cs@(Xeqzo$D%hs)@SpnR~6QtcC7VWlHiaB~=p!M!3>O zytx2uU**KaaBKZqAz`jv;(E&jaAB9jTLE-M1Br!B=TfX&1CV4ts+w{s+#^Vrk8u1@ zz8{VJIsKfX^p=pR$cj4UVz1$HA@%1E>=#zB;%dD^YBpuC3M$?&jZPJ!`p{(PQT;{B zFCDgb`V}gn6PcuaaGh@6?0c?*>*a1~**8Fu24%&?sz_7Nc{G7pzztk;MfJWuRU}7*H~*$Lx<|P{+C@pJaVQ5;!nv2WdOjY z`>dZgV@fwdZ7MkzVpZVBJu`(|7<=YCYTiG57!{M&+f_%buYD5rp58_2k#^*+j&Jt} z@tzft^;J}Py1RmZTjMVn>bJ6}?S%rx&e;cIIUT{WX_zfe)#{tYyBM9jFhwfP0E)l36y z{H0sO_xAX2m~y6RzLu~K1zJsm9-RH$a)b0xA%o~r!1GDYXuOiGvJ*==sgl>KXDuT3 zl-0MW&$o`fL(gF~hw{|@|E+KG ztXS2(zv)9qC7+oZ|8>^esf%^Ipc?uSR!*~yx8ch2wUn7y%w_lu-Di~J28iR2c_zaw zs91o&k>-&SM+WyFFL3Wkd(2SO&LFEv+<&vutqmed{kdzuSG)Y*cVQnB2z49!&o*7G zUSjh0V67je9Phr{TKv4Sa25d0zBF>Egs!(;yETi9GiIL_K~tAdEbm&=S?W}Z!}iI+ z5*py$!5xTiKiH2i#VnQqag+{!`n{Xq1rj3E%f`&FChopmiu!2bI3hG!pM^)LX5_-g zstKtdmC|L4wm49I-7TMHGYVAFWn<1OOeR(~Hr@6usA1v@f_m{!?I~apCh)hspbzjtuVruX|*$>uEP_H zK~A9ZU3mD1MJ=rIC@7J;n%HSTi6_OQN|1SPhCnC#endGUBFf}hS?dZNAk_1czffH{ z;655omRuotDW-lxC@u%+)CQ6SuBYFwA!t;7YG&2#_3H&Q*b9yYuW=7vpXY zI9{Cc?+WvDxa|#)v3S|KJNMO`bTe2T;xlGY)g&(lt(g0$3Gb$lACtu`_ZN_{-(3oa zBIYxEAxPN>w>}uo)lKkCG3;dnRQ+?P7`nSA2##wdZ+2a`&MAOG>*8rr5(A1s&+60Q z^Tau+NEz>Fh>hl2UO~?WuhFvOY}-MPo352k6rlU-;w=jy(x2o78}8G zw1h|+M+)3XQZ$yK%5Jb&0)lu(9wiSJtubLB?zB|60iTjLzNt=nSxgM9>9u>s;v`4t&Nj_B01+NoRGj1Enin|?0$a-I_LifRW%Af65>#5*h3deug z-DkDCd3TzdO(js=0#l*&B~D+ zc~AXXR3dtaQ*O9bM>!l_qa=I<0q_me!jC{*)c~B-o(%FH4e!pLh#J3RT+X9@dSFFr z+Khftf>kN9#%|o}(uk5rbBl?^q3)CPJtLwPlJ_Q4AGT2FJTU-E5&gottP`RG0SO87 zyh#-NiK~7|Z+N3f2yUWY^9Jevm`R8e*@kio2@z8Hor4LK96XlWM_aCjff8KFPYR*g zmuNlF^%B!#=U&X@tz9Y^@18hu$kvVTzy$to z+!ay`&Z*lKV2{kp#^NML&ld0uU&D+3Cnw4yM!($)wZ(d8Y{S$3%bvQ{`+}Rw1Fak8 zXM2=2$QMM^*AhvMs;313$wB12UqH9Pq)TMgAuaz^hrReCyd}XTPu9=Uo6JYD+x#8q z>J>GWev`Z3#$O{jj}z@b)ukrKY@4W-v0+Bp{^-^Cg}2AUO}_}wn%tVy(PwA}8NX5% zM3ht@=z^9!B9kJw$<)s8sL5nH@w;OoKh`mC<8GfkbFZNYxZx}PtOe6QaYk#wZDRxt zo$GEO;)=eJZMMxNTIwZce3|3cm6HvdSuCS})}V5yJxU6Y{U~R@)GA|$zO#VyS9gYc}8RV>@J9w*wI&78@h3rHdAYLJ+($TMz zj5-XAyH+M}tPWqbQdtS4)!URb->Xsj%xKVCN$u3(vBa8v{OBsM67fKDWEWgt5cD@q za;2YNZ^omr8o$Xuvq42DVK)j>e&xBI9 zPnxe$oeZajRCRyfuM1uqBvpqQY5V**E;2b|IPOtu-PR#5;{B(KE1#Zn`B;4h&L1l2 z)QP9r(F5SFX=Fzy=?xhb@yk0|X6l8+=6l4^M92gWgZWNaoteiT@W^LNI{FC3VmVF| zih(0VhAFFP}_Ru$hVW^lVd;4xr_lKE+7sy%n(0xU{>G8K zujT36(s`7N$v2u_D_d-a=)z&)WIBsR`s4AvO#p&ynB2|-Tr1u1ZzOAlA*n5eUe6>1 zrDxiG92o}o(s2ZP?hP2;5mJzF@ymOjHm??mN40~UJ!ntuPIdD=o%GLcJn0Ln)g;YYgKc_ON zkbN>$?a$z7`ufpD0w(iavMz}&K6s??aZ-BS3#)0o)25=WwlMgh)0mm83;@&?Mq9@f7YsPkHvwLPYH)NES2|THNF41ERQ_@U0^e(pI9l=EIAhBpgBt$7$Yi}D z(@b!SzRrH9SIeKKe^Wi5A@$$h=FIMUkFW8HXW8cX_C6C76X2%-ApN~2y;>`1Nwy0HyF{ei_;R3e+8wzZWs-huZ*zje=5ujPQ>)FB zlGfj%CHH07+R{K`yf3WyYA)OjPK-GYtS1(cA+~*t#1wMs<^NYl8IJve1a98a(uvp@ z(E)Ofhw(;u)!Hj=RiiB1HOB=NpkVlv97oP6?mBAgQtBCPb97; zuDxV0)xq0pRwlXRF<^G*;);K)AqbaM?qzWj7HsTij1e%{?n_UTqgHOk{|=GZ(mOG0 zt3}jU{~2FAF~#Knondf>`V<4K(Roqm-%Jv&+L;biBX4~TTpGT@OMCP4oTWP$SByy3 z`LMmT)KSsYmn>R(bkg=yBulAqd@8FtF(HvPqx5T$6qPxhZ%C+{lAaTYYuGl(F4pa< z7JnEq^%<;4g5TRuD@ZCFEbKp<#ar$dC;WohdQM;g$(gz#k*Ig|xpw4hcj+dO*bjkk zT~-0Wa&9A1HKK2*_~l@O1+kmn@40Ve%2`+(_y%W3LY7KI(_t-y0RvU^YN{ef zX<~izjz^#;qPv10^+=>4KRmFt5NHS5|7iZ4^Q$woWas9OCD;(Dy5 zi>8UB7sE*VNK22WtGY=HO5*=#YG+EfY`hEG3qFZh(P>u2$~QP^YNYl?x+XnMY@7z5 zNF3HH*Yj96Qwb{Wtvf#k?1JRZL%VtWKHwGgE+FtbC@${|dA#N?87ACOAF7{_B+Den z7cR!Kh7zTDs0q#EBsZoPLaif0W|XtL!I%NmfuUTc2n+lO2!;$oq-)QOx9a&2^t5*D zAbPsg3wZCcbuC6gcIiH8dIcjlrvspW$B__qS&Dw%NQ9F@rG*|B$mJQK&SIln$)!qO z!imbNxxzq6my}|3MF+2Ysb@`(4I8T(l~HXMfxW4m8}S@kf0y24W25Ne9;7SqTP9RZHHn-?WT1-n9Z>s9(Tmp}bq4w1 z*+Y&c_>^fezM96YhCMJEgM681)3c`jtaEA|QQ%kbr_(^e=JPmRJ2Ad8!uh{96+V0n zG~azDjcItDOU@S)cAysEo&{Pg5vE%SvOQs@ngqkR!H%@ilI z)A(U72H_&lYY+&^S~2k`Zu4+@FWgfB$3|gM(<$muEX5I`$pi|MTff2a$jU5QI4|i+3*?l(?JKugsWyMSG_7os(z!3S0nbBQxRBo9E|{{i`nbk+UwU+ zGIF^eZKvD@o%ddZNIUU8jNQdZMzvlgH=Al3c8=sgQgOW1a|&ZaDg}3hI@9Yi7p;by zCdv>Qjvb<*oiRqAcW5q7$mCus+qS6N-$1sluAGfV$SZN35;#Ja%!)Xu^f^e{Xr}6x z^{-~jfdqSTh@sZEgv;L>|GG%eGgj$E36+IfFn-$b@MDgsit)DrFYq^v_k?rr-xX$u zWNR=3vL=OaJ`8}Z1!0$yhHq=+fRga90U!r3TtM1T1g=~&POJxa+%~$O6lkpkc23?# zFtRhU4q%TW1}0dI=q0x7sjD1ZQywzBUy=?IweEBLqennQ4FN0nCxn$BTr?L_MZp;8 zX{W|MGfxw9w{_?|ybsO+L+^KpaRjwG8nxxsUX$KBndxEo#XM{T3U zv<80uE^OA9@z4gsR8CKD2qx)u{~9%J|151HMAmAQQWMb#v7PNah?8Ei@jZC$xb6GoPw9Ks=#GnmJxT!G{r% zVGTt-iP=lRwCLM%q{oh3elb>PC&AMJ&!zbcfll!dEAC8Vox+JXrua9BqDl_CF&IR} zUTJ4$q1j?1&iFNiB3rbG){?yn9iV}t;%x3f2sbIu{FJ|_Jvl6^?8W4Q(Dzti+P&u^79Ng|UVUxxAn4y>@<__0R`nzboS` z`R0h8$!TOWbmSfqE3A+)oHLjdLJm$bPHqtq7hP6^X1EpM9-t8ZJTK6<25wL>_`Gwg z=xsgpl0_(+kOQ>ee?{|kV0|;V-B=o}cvvXcD0A|8;Tru1R1p6#IkU@}9qj!e&5q%$ zCv;vPH)BbA>&M+Nd2)90czUVa4TDAdNgq5G8a|o$emzO!LVJjTC7&ZI{YV0qY(Ml{ zr`-@s0op!~k(6tZVY^6yfSjW))~hCpvdC?f{+F!+R3J(CFn`BUK`dyyPl)Ob<>Eg~ zb!y|g8S5+8&dCtedsr!GEfcJrvmRymD-5__Du;{*d1`1%=@J| zLefVK)i71YKZkRU{xcNyx+c7%MPL{0;iDI0rh&G)R7lW(lbO1JEgG;Ap-&-mRIAR* zb%bR4B5Tg(K&OT)A^RQhG@i~02900X!ikcO_kM>*MGZSYUv+>Hk^~Sb$k+bJmR4j` znnN&t6NT|Ha`OI*-p<^iEk&q$4MdNmy2AsHI&qr+^Fd~2e{BdV!tbi3=!q3Zbe5#K zcUCS9qa?fbhF%$flde)m#Q3koH8dGVvwK@Yi*pHp4XjFo zM)+3X#lku%c=DzrfPP0OoMQb~DWQ>is#_T8soxeV>k`g@0kl6Z)yiV6X^Z9TIa;D7 zi=4$@29Pt@1k?Hvahx)nK3^AUye!22T-dgclev8UTT*@ z9bwR?rFFwg!`jMJy)<1gVc?_cYvOmv9g7XBpJYWerE?~d_7)S^>M7*wDTcVKz4ch< zbk7U4ogb)WYx&jpw?fO;UF&Rig-zta7$q1Chwvtl2K`&6WFmtGx5@}3G0v=|Hi3l> z(TA{I&JS{c0MR4rBQDHSuUJM#n;SkJP9g!06plyR5~c2Jc2?=1hVR|OuMv)`RlnO0 zU$Xv|IhcRxbiF)D=U*4`PW3!{dLbC<6==__+(_M=5bFayiLU6sRa4tQjK&WkFWO$8 zGyQ`)BPNn1In9ZC5Fe<1jf8!d`}gn-g0f3t!A>DAuu9OlV@6Bl&|Zj^G3+pT$fd4l zkCz`uVWm-`n%rP4Xx&21+<8J&%a#CI!}7?ubMNspqd7yA2ci05c4gh4#0B68eLZ4{ z4`j%+Or>t2*MU=At}-P^ANe|?(0lro1}Cy{g09%n|0+|~Y?b_2_`?~*+|2BU_w_W> zV+7SRpjbQLA%pP6luZ7TxrOIYZHOkxz1VkV5+XLuoN1#lNs8zY3|U;>nKn!`xtwgi zI9DGS!)Z(uk}mDb51D|qe<%$p_lQJPITkZ%Okl_EcGTw-pq9Kjiz>*MLag5mI0$Vg zp+-=>`at0wdt52EDMz+6j(4NQ|JQNvJS#95Ky9+u16^hX8am!ThqlZPRabYMqt<^k zfy@%*R4C{ztE(2bS#Le5i8EGEr_40e$VA0^8MNqCRuG7p_+M8SQokdGtHX31`YT+2 zKKv5BbJlf%P(u`|{=WD57<1k3*(ca@7^D`aM^^P{cr>^0yz~{H@x9O89wQE+j-qS| zFsosD6@p1MfS`h&5${&3GK>$Zm8D%zQ&r-t#c_}Mx?{~F+8tiAH->O6={;K$Mn)~? zO07WEddH0*Uvhy*BTDHM<5`t3R0r?H4mT!<1I48l-EqWV>)_4tFBH%qB{ZP?C8fJl zApQ1CSUhNmc_#l8$ zfx%_-<8|ib`~8uzcZBpSyKbG7p|gyK5#QNiN=U)7s5$oWBuQOkG;p64XMe zFwiI7SE$A}w1va+RK7MQ;HBEluJA5fuN0S8G@t(%a4B^QlYA=N-mf-AUirK`bahy*@; zNED{QWLW+aEcF`Zc%#ef`8#ozHqfR1YCIG(*|gFAZM#5eI1_+U+a9xz;I~%?B0FH}FhY-paNsqQH~qTN{q0oRCB4Yisu|{u0V?T1(@!Zp(9#X|(9P z+-Tr}x9-i1FAFTuPr_B3FXK)_$wp{$uz`Cw_48@%WIB8H{lBhr(VQw#C%%F2lG%Ye%e2{O;Nv_eo`NS=sL zNOLX$Y79<@GZO1AT(F8oXh5V^P9z(4)m>}$#aPqZeb*OmA|#@|Pjl(B6C+7XU@9_o zzGP8? z%QUB!8nz1zxy-&?TZL$D`EP=VYSzlN>~_4s0W+lT6f@j(-KKsZG6dE8j~$IjlU5=i zsw7Uyxx$wvOG(m{=`_lyyE8zq)OuL#m9M|ogJDJp;=CtPiFZaLb$bgsb0sf&CZB$o zOS$Td&X?$YPuy0mne5FQOd4q8!B7(0;p{jcu{Zl(x# zv5=#pr|AQYxYfqrBqA=N5H>Fz{;_jL=>@{cJfv~=*bkTa)N66Z>l~V9 zM(rft<96x1RG&_@>5STyc@F0QN4%yc(u{_fx{0lm+Y8kwnejgrUUkMk>~4vtXTgA;&}|INmerui`*7h0d5g}3d(r$;tbKJq=e?hmSa6o(Wcpw0NOG5ts2KaoaGq2<%^pzjJZUNzYI zatDJT>a-@$EJ>QlP)_c7V)=RmBElq?;# zUaRwNxm(ccTo~tH>{Heb(_=+}#X#H%C~eMU8-Hldc&liwgsj1r!5yP*`TG@X8eTO5Xg_{oeI9W-r*(rZfhnpP*2lKou zj5nR9rIE4WuA6<@LvXnF#pal-sf}Hq%ohBPnBK>MNaeK=w5m#ygkFCRb#2Fr$|RGi zFvi2c&d*ENg(Rk>oFJBbIJ*x|NzJSd_*W4xNsiz_1_weh*U@PS$%F^y2pSmdrqWK> zBzlFCAj`lvMb2dYPooD|a8B7dsSY8^bFH7)si%_|p>zDc^51(zZSu!T8YT=Q@!=JI z8PB}_-XpSN?s7X#8#i!83l?}cOK9XA#XcPHvs5L`nMcuxy>F3$RW}8Ep-01#|B<8Ly2`GcN=FYfqnu8uQ& zs?EHupjoA?=?Wott=U#izP(EE@tZCj=g1Ip_fI-t=5!da**wTb-T(Wda&oyur72t~ z)L8YgtM1ax_2;HLHwT9Hslo=m;A3OIASBlBOg2UCiNbQB=a=wy?eC`_3|awc$|cQK z3h9GD=b+Cm;Zo4`IMxO9>uo>&A#Mk4AAK>GOm1j6o=C5|-6oCm zJLPIrQY>8+?+uq6&E+0qzQf8wrZI{_M8nBJmLFNM=Tc|vn&Z*E?6Jb#*`a*wWhAsw zF0M@=eKQ?9fPoNc$~eaw1Bu$lYYdudYNAuV_{LkBNjops^ZQ{FfpEso8-Nn}74E_uf7QuPZIwztm3J9?HBe*;grNhH59yxJ&9}j)v3jc)SJY3o;{G^R=Q_bZ z+4V<%S0#{5p10#Vsrz`Lnjcs6+SqkxSp5vDv_VL6F*%}7di9;`x9zdu$Q*zW$)^WF z$mLK31Ny%1?mzCHZ@a8a1IXY;7P$$M0;)fG{;f&QNt-WWC`BNmj7`Mpa-5bdJz{V)_u zSto~>DQfR*P;iS_S*dSL1w0N3qnpIDEpgfCI`lL%tP-#%v9s=KH1sQx;dyn4&N3hx zKF-4t7Mo)+K6K`ywJYED+bB?DG;(qRt!KHg!VVY$?Jc6H8BqGfsOP-75tU_(i)e}N zFRtZ0C?hjfAWWIj34iA5&}Khzd-I-(VP*;Wg)!q#WA;|+Q(XJ}zc#0WW8(I$dxRYL z=^>qWKvJ&KcaW;wd>Pf>f{bMtE;)HCPvbDW5>+(GMT**dt__KVBX*-q*QxPR)T*cf zc_Wt$Q)NYB01!e!KHm(dHp3Jn_h8=?`;5!+=V7P!ni2rv^ibyj9XboXLzI&0Bm6>me(#uE$!&uo~-NTT+7}@keP=Y7#-h@5qIyW^L!H9j$1iYkXgd&jkTp# zEhqZ}7ofA0-{~+@p#%{lFLCOLOQH@^d#+?6<)fCSbtA=Vd9am z9JBtOa-G=8bHhCg>e3LG_A;Pt!?ax5wKUilFiZlkT#2XF`LD;a+>yx(baT$or_gf% zXt0mxL#;!=_`_QZPDL!~F;JVhVof~_6L0js z)t_`gxxPir67(+rs4`=zJCs^1%iFm z@YX#y2P`#vF}t7On9k#KcaHx%-g;ej9+g;kWsVcy(S^XuN zV!YA682vEnfU&qzT1Tt~ZAw zs^+|klEKsHe;5nv02K{`1#EMnbVFErsy{?7?RtXdA#w<*dOZe;DjJ%JV3qNmRSVoc z>_Ga9h{H?&9M#Ga=gAoS^pBcel6juGFagWgTQD7{FsL@8hgh<1$I_Tu0J>g4c#r~Cn_+7o0snADs zYZC`F+njiSl=xM?5lQ>mD4l|)G{r|5OT1%~Kimt#PuH_v?A9GKnO03Qjjoo#O_Vm|daljpy{~XYeG(SB4uCr}HeZmngVHfgPp_Biin&0nP^fa1xr}jg`9LH6Qu7XzgB5)lshl&%cBCqwN$F?~TYaNxp3`dWo) zcO7xQgYesr?F~L1-jtrtb=SYYX0E04EKLHmRFr;a9k)7uwRYc#_m(GeqN6TP3+p3LN16 z*EL?| zl*Q#i=XT^P+d9q{oX%NI!q-_MzmQ1iKB7JDDz0%A3_lW;2+eHj#=MH@_RX#y#9xRF zP8MA0LtWT-qa9MI_=taWV5DI5Qx$k_{tJY3-M*Y9aK7hJzhffpS`d!Re15d+uKu>r z%9He_?Tfo`St`|$-qF*hm0qu2vI|vShj=(+GjUICJ8ME#$Sh29LOZt&H^W6apF4Ml z)#x%}+kt7CDcL-3!gNmeOWhc*iolz}0C+Q;O)W*&b|A%iNh$FPU@rMM}ogZU2_46im2JetD7`(z# z^dJU_87MFc{QPP0f8Hp%1Vx7ShzshiOiT1u+&SkkO=&7;tCqsaX7e!`(zid)&<%x` z#L1)Ia{!9NwwQ`vqmt}N0fc}fXncVALSFVed9G2}1QQA>J&4i0YDw%>guvvAEFUx! z1j%Ot{#>eyExNn>RPx;j4gjC#SUUgp*2mEvdO+Zt6+%puL_PTDCDsk;llqH#F!hF} zXpP)|v7S<`H5={q6-o0qD#8`S@b*I6Y>P>h<&I}$U#44`df|x_pnlkYMS$WOG78#m zeOX@$sL=e~6?Pbf0_hkZ)l(?R-a;*_p8Y>D!SQehW!b4rV4NnEyn{Mc?*3=nUD^D* zK$mE|*CXFK$k!7AthxJp=PfY3kW?4(&UR(g<@Taat_9%GJ{R&#?2RfZIP))VA zMV)v6vWxvCH20RPKj&b&WbAwvOma|DzaolwP(2l#qrN1&ub!ADLCryNSH1R!Z2}-q z4J-d@RzA98)^?745TRVWL>(=NV?Hn@NGNCllrTqk-#r-{o+1tA$KnV=!>W6-AB?z z+b9)1NhMk75PFo6Z@BbjmXe^UPgn60l^1dP+=_oL1Eik-9#}qzM*}~YG#$82k=$GM znUUOW2s*Lr=-)V5hhG~nnZzc^B(#WuMtbVZMcmZ*{PWL)fG^riuQ~s&KmC&PVPWA= zbM(mF#%m`!BOz&YB|(^mZBO)VzE1x;-{o?`?^qa=WDHs4t1Juqt>*y1AZ@Zxt|We^ z7dwAEW58b`P+y6hIOFw%Pn@=CgTE&5c5R39u17ls7fn$5Y70Uc8^A9c)H2=?`epGr z(>SJ$R(O&b2Inta4`XF}3CV47L1@$5qS5SQMDmZ$hvBq=*m=X(AOGDRdO~5M9a&+5$;1;%NtjHQB|#S%$r9#-3d9m1 z6iTvWlJZ35I*bdQF+IxFHYv-PqmF-kDCrYYk21LQV9yuml6TwjEJnA#5Cg}_Y^T1M zk7Osu>b|%UT$b%L&Pk^5Bx9S*;uX&!lf3IfGVvp{$RK~D`(`tZ zhXh@}jyGYNWuKR{;+BleR=OYH^?$p)jfq3&?GoD&Z%h3UwroSzZbVy_fcF7B`Pm=EUG|)+Ud(6t zXvdHON&pIlP-wLsww>FODQkk(NdU^k$}zD5;t{;r@T*__3aP;7spkUT9>f@gem zrX*t8qHMcT&X4lRXM&7LpFGA&*j_BS|6()7EGo% zw|Y~@XJ$_Fet@qenPh*>rcY5Dj!9k;9=ImEsAW1A$}NoDiVFa3m^kdBX+DrAyiWYX z7644-s!IBT+@lh=MF4;Ae{|u|e~#-<$3UB?{LIQr&EKxB`zygsWFQHtqr-GKi|aa0 zr_0vO*J0G|Rpa865((QZh0?}NUP4JwO}kkzDVlv5Nl>TRxxarRNtXcPO2R~KaX{nk zlFS$}8KAchB=O0LBej zVCle#=Fp*2)=hs;6mC%XAXGB)p&>seO>5f`w(~vt>-2tkP*ANSKe~)SzAr9{AITKR z#RdH{(J3KPUbvtqJn6ab!fVruejQ_3U}!O;J{BF>B4m;+?Y2K~z~kI)(_OwKeV60b zbUEp9E9J$4alP&OWgEF1KNFwZopGUUi-3)DxD@bhoGE|evjR48c7zA_!wT-p!TkVp zGY4N>U4P>_NYRW+#7V2$lB=PnxM0n{<=eNz0zexlLgK1j3xIg!&!o>bA(OmdPWYh3 zqyM?%2R`thPfs0~_`3hSn-`nkOxOKkYiLp88!FJjP^UXsnZ(&1>m)i^IUzSk$B+Bz zQe(lmg{OZ|TEO{*WNm(^DDVJ_&7v)~B_E7d;rK*qf5LcL2oya!9MVb)0q#ZnnP~@451bjnE$)&@R_;`ic1%r zOsbMUCF<%1NoC(zrutLOH@^N2!~6Xno(-^t$HIR)m$Tu_nGdE!3K5V8PyJ(5k!Xij z>Y(x(eoUIe1wA>rER&bhu_#E_;@NH|P00$DWNEUN_?^ejmBjBf*)yAzWgk+k5o(bV zX}TXl_aY3)n5_~|)OFm?I21Z%m6(&B#mty=CV_lE$_Ev=>`PZ|?}zm{ZRPH>04~ot zqQ!p#$AZP-PP4Je=K~zYO@ZHOW^uWQmjWc~l7pX9{iP>+{cHbjW5ZrKnJk)I#HH9p z6R(D?DGz4duH|ou_N}%6s0Tf^iFZ{U@kgiyKurF`mHY+c830=ZEH9pXXmRHBuOwe# zBgaq*nb-aQ7rXB7H#il}cx+VS8>ZbIMO%NGvp&{IblMj7Hv1>@!^kA*Bj6O#Jd)TV z-%HWWKMy1$31=N3rej$RSjuiW$tAjek1u_=RC1r<^5_jR?)3$tt-OUs2BSWOE=M`5M&aQGWZf2F4@kGdU`L z`tXH8mDux`(T{kQuk<89Puz+JiZ*}dYJ1{Vzr=IM?IStamOdriugmh2GSncXZqfm~ zwtf`P2Uu(7W?r-RU97IHfjY9x^rsG;!KHwIpQPNeH-_QSV3a9SI!fF|`0cU)h`Sl# zT}S?;DftV=#IJ-OVLtlrH#2ibmmc}`UT^yFBy)i2>!0Ad|04}f*H&dOGwXkLTM%$a zy2pXvLG{)p{9EZe2k8iEXkEi~ZFj<*36J1#PTMq*4dbPN+P|mu^8Kg%RwN);J1r38 z*C2SUMMq+`VoceXHV|5?@9w8%v9lq2udc2(Z=+hlsnMx)+Mmx-fAFD)a0h*QMX(f- zx2oBS!6K^SqJ7h`kCN?cI|F~5WQTGlTPuLhK2PBuhL>J^sd@8Fe;hW?0-VQX083!# z*Wn{~;NtA`BBWop9!EXD0Dtrq{mUu(rr+hocb~3a@3=?-w z-fh18xqlsjw~yMLSM;nu76WEF{MTm%O1t#euNfh+23a_qJSXHZdo7gXpM&{qw!k(+f|pt-tjW zGJni(_sYaVX>4_d5({q z!j*>WvKM9{EdsF1@grlf^N}%>OFbW9{Q2u!^&3+A@?>0XL0 zr=?i3STaU=?mO*H^c2($yc>W|1;h=4EK7?Anui~LxZQs*Z>3KNrJzb|g-~c_ zF4!rYj1@H(mY*yTY$OQ*^=J!=mT!LZn?|0&&jH`X&jEG0cd9?roH+4_B{XIcJ5pq# z8(FcHlwbwnj6=AE%;`7Vd0R=oTtkO$lI1CHPn<}L^q2f^<;w!3xgFyHu3-_t`vEXNcou+hk1GACr4Mavz4L!= zZ?AE+AmL$fl&P9m&1`*>YO!0ReXA@0Mh!Z7T~&!cLiT^REBVJG{)p$J|Ao1OCl1fw z``=>6jVV|h4%^K4Zd`1BWA%9i#wnfmx5LCc>2;?&g({*YyoxriIf)qe#W+2cS`Y8B*ZC;06r# z_8?}=y6t}`U^8(5 zvP^Pk?ebyNER&GjPTJM_DOqX*jS?>d{QmF%e%`6Cu5LG1uW`SPo&D-cbMD-erpROv zEA_bvy)p?3#}-9HmC2h)#S)9j00%Adr7OBa+M|CQkDB4zbmXJJ!30Yk@);BTrbL<- zBjWpbw0#$!?mOwW`o>t2f5F7}7~L=JW;ryxU3^=gAOlMl2>C<_P1f2jugNc-!(uC$ z$hwMM^5!Mj&i58TQDc;4fUqAdHg+BdtvDC~+I$xB3Er8%7&PI1@hcI`Olu3sTEWq)l z5Bzd}YW^H-w2GVxlDUNI{=bdu{s+Qy{yCdsrTlKo-gI`aHHk*-3-L*G>i$lqgB?V+ z?#Ipa7IodfqKNWskG*s(fc>&<3ttF857~c;TIHx;wqn2NF)bc~SxQo>_L>u*3j~cp z)O*twZ#{mjNKTxw+n)IDUUW zZUS4*$%O_yu`tmI9}i11EV7X%T$cyxO9CaS`GTNMf^{q<@nd#`L|x)n96IVRiCebJ z20qkoLE6Nh;%@OUF7<+?-KM4&>a}gSKMK?~%NSHV+a`l?(gXXz0q_MFW$2s6efznL z>rz(n7!Kwp2`Jasjy7}Ct9V@S>o|Wyw2i9wsKl9OqW012%|71mZT^S#O?zRGMUl8} z5U$XUcv0@gM@U??UI4I-Aa^iTcU^(DHj6Lmz1?Fds9$c+AFd}hSb8-!h)0%t@9~asFCIz=kn8e zl9)<6KXKSpRF`q;`~`cIE_#k5qW-yiz;y2MsiT-abeV9!7 zFtRm?B_y{aHxkvM)IW+v(zSnU*P8Es_q(P&J3EDY0yaExfHK`*z$=9Bv&2A$9D}ZE zHWRO%&?H}UV>0CB2Fce@eumLKA#y?B35@beVwUtn;wR5zRKllD(Q{v=o$a*x>wJrc zwp;eQ7X#(;hQ=Yp$aq8S9z&7qj!)y5VnwH1kNtAq@P7KFF!`**{{!flaT4b4WuNpyc&2GH1>&hE7)(NI4koJ4PUpJ-`xA6=p?Q~R_w1&I)1rdU(7 z4j=8`>HAI!Vguu?q)&@9mrdp%Nb#aYh_$d2%OVm0REXHiwfNlU(bodb0{jUc3Y2Xe zK5S10l!=c$@r2d`$y$gxIc)ny%l~DFBR z>C0a-S`UMB?b>#;dYz|i_;R3Y&Dpb`umr)xr%H1ii(HuuRY9*`l*2@)N}cj(Ubmq{ z=*iv_nP}NZ@aJ+#H_^8d0G|$6k}eZlT@^Fw!V6^L_vGKrHy!qqf0QLYV8<63IewEx zTqalSx-Q$^U&enL?YaKoSeOiN7)*Bc6T!j0QrG=)TOw3wFkZ!w_(t=7=u*ul#*qsE zD^lE?!Yi?taVg+CxD?QDHn0fbOjAwL8DPJCc5eFM%Ojo*AP>}uxNJmPoYWDgY~7ar zzJ`9+(Ebgv9#pjjW8|cDRV@aX{3EX9UqdbcNV7%3p{0L&eg+SiIEnU%;&Wsg)B9Ji zzBnKkXAqfP!PiQh@3AoOai#V{`EkDZ1+Gg;WHrazgBs)gQ1h?eCwksSpUP;EQu>IU z3I1w7-0)t=r7jXGb|i$>o`Md3kB&VHW(X}#;dTKgUC?0MEaJ%853XSyi0Ltl8`0&g zhbG5}TyB3GZCLXlA-@CEjZy|r@k=)7mA3q{1b9g9JF;&+KmxRP5CC!~c@i%NTE>lk zJQKhSu=5rk5q!*_P4(P!&*F~hO-vtPjSx65ceXK4 zjL(GcHa$5*-kvN-IoDNUm96%Z2a^n(yB+zZP0@-ExXS+2-y%m{=_F`TL>o~rnmo7Yn8v^fd7G|Hdr(VXV1iH4Fun($F_mBV6`T4_NSzWz& zk=9VT0l8ZsE=Zh{hmdAuN)ROD5t1f3LKV@~-uJNV8~0zRao`zUY!k05Hy&w(tn8a0 z_kwKK$v!7~@GRj2<{SSO=MSA;o;&wn!R&uT*68%J+eOFt4T!)FBoOD#}2bm`9^3J1<^xYdNj+Om@ky>(v zrwFlwgIL>Mtw#a3@0{qH6!0p($$|D3o(lLnZu(>CVIeSe&)tUescDZq@^EtmH`sr9 zDZNXC>?HP+ytLlPVn%C!7%%H3WLQ6=A#S@|LW8=O@F?Two_*HXbGQuf`s?c{IrOlj zKZrLSdfzw{U6md3#G|Bw6ln>qv?IUf#kO#Vema`Eeq@gff_Y@cw-hj|RCZ=jfc<0XF__B^SkcJd#O@I5By*YtQ6L*rob7N=sZV^ll% z%8_&4d@oWEd$axYg`g(c&&gRI0KSy$J@W3En0Mlk&I5n}TUYzM4 zUbwdQ^4HLWL8}stZQ?9~-tte<@|2H^TN$4yvAs_ntOr|d+omZd;xX~7&3=C=`4eZ| zRq}`Y?1`mE|I4Y~>>1!=%dze2xa zqOJ@TnqxR%6-yy_+t`fD<@^)PLh=v?Nw)tkJuJ**f1&v!yc>W8CqS?u*lO1B zivX5Q-0XPj^ha{iutby$3NOhWHo@zvb&{h@O;cMp0h%3z(SpH#NsfQjy#Ue)vL&XF zAi-y0@>4SOqiV{;sy-zebf{_-AGGcIZQJtc{Tjui4PRuGKDk}90Z;U$@iBk7k6auT z*@$}|Vtn+0`I=)+3maJHSqk=H1GdZ=fOiVe?ssJbn0Z^c!4-34VfF=kmIR-FF|zdL z9-Z#@zPh%7_i1~fAyt1;h_eWKYxt+8zn~=Rw&?p3GAZuIQV*iqf{dBC+QKmKb~-T9K;RIk@Vi;xCpH{vTV5&_9VuQTZ3@=yv_1rS z_&v8}KFAp@$?CK}h^_}6>eKc)-sulHM#r*)SM2ug@GDj?yzsme!zblnWk?y$HBQBD zH8sS+GD)3f2;+b3*)z?NBS)GGc+4?vAH`*Wix>S@4wo;#f}aFlZDwW`%_O>Bl}MoW z_<~_;6($}Po^|%ZMCA<0cR{CNI|NxKIhL3Jy-gaE9=1MA6EAeO>q@&dEw+dAI}8ti`=&ZO_US^xxP2w@y8URq;u zc;UjQ@UDPwH8cJ5cx&J^7Ky_b0kA$bJ9GDM%``9mgAHF^&>}01v2wQ{oRAw&Rc(-R zA?=ngeyFhjy5ZlP5|`TAAT{L1i&cr9us-r{UE>G8KJ`C0Gc&hzbn!v{=6|7f)V2G3 zeC?g)mo|T1E71Z|z%AmK#%^>bk&UytYX*-A$Jmqj>9T{d>mrY&jnk<6!#1vf;!oa+ zg@S2!(RN+NLs&Yp)*4O*#D=;^wwp)|TNh*oeXs!~?Bx`dze*g6C)%zT3*LrbYz@lAew8-ks(F-Wzhlg)|JIijkMT=iH70iFKa)OW zEk*M?nHK0}uJ{DKynd`Xy!cI=^qTTZ0V5_L7WF5lXO`bxU4Q*M>{6;UNt{Kn#*LXi zqKpR-zdkM`deqyO_;H zQx_Y>6RRZ?@=~I~ zcH_ZxXU)k7e5fc9yA9HK`rdhMK4pL1emg-H|B9n+Q~YAn5+!`o{^&~GwhRZP(8On4 z!VBNy=;FngoFDsKY^6&X^qKsYzIW--w-!3kHJmgq40Ob=`zSol;@1~L>e~h!l4pf0 z0tUbZK>m(7%Rj-~I*gsNGjW1#;X}QhE5Em~b@dvprb>Tv5ocS4 zbd`vUCgXyl-x6@YUIG|4cpT(WRf_<@xB#eeEeNz2urmP%=8xVv-#`5MVFA?izkcDR z=49hHVb#3Yu4m39v!&Ldy-|9#{3uz)rtg~C9Jq01FMhD=X_?JO$1Q5R(bgEB+H8lb{Zet zW(pSxkR-fMPUmU+9xoFlc{>`ysej$|PyalPZT7JDi z1D*Uk@iL%q(FP;sGf%iTr4GvT&pp>1KZ;)lXh=ZwF)((=N8%0LR@*eWUK? zgX1gtjDS}9#U#eS9J;J+6H=3kc%>bAh)$*Th)@mR*B4r!B zbKwik!rZf%7rX?AZOVXJrRZVwmlx(9{>N9>-ui8b$T|gB*%mIS2~J+u)TUflq3keT zm;C!eV^Z8tr5<3l2_w#p!ghr03oRKlEdT%@07*naRNJh>l0AQuz9squ^Bw)CSf0`pT$8X zIjX7sEo9g)0N&T|+Uu|37XYuD;>^qx+IaRmMUa>m7EYp`7@B0L6cbAu#{vm13rz_$ zCNM6Ctmt9XuHG}ZFoNd zkK>1`{zboWOk~3@Vlqs^vO&m(Yh7_42TPfCEWG@M=O`Hi==-y_(#&8O0NgzD}$eWlCRWF_L9fk zBsn!&v_zb25kMpK&Dyp?&S1%VbytCaNA8jwgTMHTzpw^h4)o@m>$t(ocj|bs3mzKu zkd2cP9tF8=x~mf8Aitc}F1&W)YbQeS1Z#h?=f566B7#6I)7_p_P6=Pho^exGm2LL7 z*yDfLc)X-(EDArzgDv1U;tlfJNBqt=n>Ox}XW|teeR@pf@hG4Ee0*G%IQ??0Y!h=L zu+jk)cw=l{g^MW&md!WV+B{=t0s4KsdDZ$)nW3fEpE~g9#?~AEW_#Pb`s8xYQjAVS zqrr#|b&wd7d>O{sxS{<0v;e3FOKrlg8WVp%@tFK0t_1*-J@L-#{&Uj{hYl~^|7$p2 zn}ZCB+oJ6N<1oooGQ{1~L`lc2=rgJ9x z?lRaXN~f7Xgu4kS8;yIiWXWxk0UG};+uH8{To{s+&Ke8=4U0n%q+B{^W*Q&-k%4~| z8cT(XfFIyl02k9;(0nUkA9vKVT*IS+f9%J9qM4q;SHg5EaBhmBc<=#&D z{`-wi*#~f4{n)YN6P*R1QroAu#w`L`dTj$1hkc}2i3has6NU%4H_t!+eDluRZyTkD zn*ra%WdJH|Z*4S7OLyVHK!>-?z+ z4b@c|qN}|dsNi;^bJKrh_sasH9wfC1yQ&huj{F6+5Ma`eivT5lK`j6*`7h2c-?2P* z*Dqt|nGdi=ZGm67@Iv$92G?AN6wMYvb!Le8Q1V{%ZnVxM_SJ8}Np$K#*qhEUEk;sy z6U05Xbd*j4ifg;9Q$%BnyDcwvD&KZipdpdlf`H7F)Xk2yU7mj^Cuk|$Iq?`u@j?P^ z?)TiIADlbZ0WMEgUs{YZW)nL2!o)0K6E8X98G`;U>Tb9(d3%L71UptzZxg zjeusxB#Qw0Q;9abN8*fz99sT@;pwNIGQs(I{2cI=RZAWu@J6qL2OqF8RN~|y33oV{ z^f_Ezm1AeupTU2W4JJ1~h3~YI9C;+)K0+3+4Vm<0Pf3=#iXomI5UqyP7p=V@;5ax> zGHrg*D+>`@fDDY2>=4S9Cu};<@AJXMpUbijZ|k3H>B;XhKaha76FWdc6ph9 z6FB9qAqV!RU(Fs8RfKo(TxMhQF1!WvFYtYX5s6EE5YB&2Pc7jsgRlN6Sd?bZScnhP zuIaI@zy!@0KI*pU?>pR&3jhsPgv4379~D&67gX{Wtj_>2`Nz}$mi$4RJGylL-<}Dt z`jxW?A!p^x=9T8x)?Y#pWxG>uRH0;D$LVz0+mAYv#Pt64y*oOm`lq&{$H=5ye_Las z=2oF3w?2P&fNZ+DR`7N!Aqf0b|jBeMx)uva_H0i5Fh%GH%5 zh%X9Wt~0f~Y@VjD5cv4VKVi77Q5>^RezfeRMvE5Yce@D4P9{Wb4~%{u!Mg#z^rbIm z&sXtspv(9*0L%K?<>uINz8uJ!28p*Tw@<0uG)jN+HH>;CLAyO~Gr20s`F59_V6@SN z56aPw+g0Knl!<+Ezg@NqO$!YU3~hUI&Et^fto-@{MLyg;KidE|S{ zF*d)RZ!uBb?C}zZ786YVNc{NVX@AD%Kl7uLP=R^@-%33rMJH1{(x#iM*O%;NLE@0B zN?Ly`{i)f9o1K;4-PpQz9dsIqhSe5~s>Gvg&ATPq`(Xi~t)~G~TiYzcxBy`6UCBQt ze&Ran*8)IC|Acdk^UEg>&EEC*lP!Sm!XW7EAK}Ko6OBKdq+7B~$6i zE+29Ms+P$bgG6WeQa}<(i%sJrMzf3G{v)$LwRXL^#yv7hZ*H#XpE_mub-Zf#^FR3o zr&BjOawIn?5gGwCT`?^`v_%tt?|@O~Ap$--H`6@x?Dv}s@A^{#`Jk8A)2{)xwl{z5 zfj~2}M=hCna%bZ5$|z_{N3Ut9G-NF}Ea|rCJep;)N_Nxr`Zi6xZYW)g3!POv+He{Z zckv}TPv*X0@cxx#@A7Q>7IPi6(>N3x#jgiY+LWO}PUu5)U8XBOAA66Je6KvaLfhOn zq}kaP^q)un=F@)T4`-SHLr?ufCVziZh}Q)Mb2*8VaWCQtfqeH*yKsbJMQgg>KRAQ; z1pF~rG}2XNBsvj|Q1tkfiFlOVSNMKg0BF!6B+knG8y5h>l0W+t7XexT#KdpOA9AzD z7VrOs>8bgezW6Dc1&e%_bgk%z^wcJrc4B`0-*#kG3CFT4>?5FwSSatsLO}cd z;t_pGg^zZ9>Zzx#wXlH80Iz?pqA%oo3dK*XEc!P$UU8pC&vmwLX$OXQqOb~-}Y(T1E(TC=W&PC^Bd{x6q4u6 z!{wgV2OoN{If0i0v6#Fosa5EPwaA0KilT)8Bg$q?ru)N^K3IRD3rVo_iG-uLaq-Kz z48Y{VvWi~=T)w2s0GIHPpeI0OqQdA5ttFAs%RUc*TQ`jSky`dhC??)eXgmF8>C`NPSR$G!~R5Pkss67mte!+0xB^ z%=h;5eg@2jO$2|;7(z?_sUx{ZY;#6YAr{Rb@`$rg#td5vuL)|du3f{s0$xk)QJ~kK zo;tv{1%5RdkufQ$O~@kXt@25F{0c<8NbMtRKP><>SP>Fuk{49MCse|(p-%e?b|rsa z|DQX)bpJ2(dvj-jk1aoS@zv&uX7H3!t*GE@`ndKuy*PgZg^$ze^0^;%CW%RX7Mw(< z?tixqEqZaje>zo(-M{gXLyc%paXB5WuwODc+Z)18wGg0XEjPFewjyKDY5Slo{3fxy z5J{{Enkv>1bOEg#yW=yhGxuk=DlP-{sivuEcJ9jD-BMO(p3$jQqlL znd;=yU{GPOuKiaKAf$TBi63~}S z?HZnL7U#Z!vjF4dFk^bN5A=HL|9*WF@1!1dr~v37;?W`Lv9!M!&gr5>otuuop9_F` zFw`cjYfStRkIBD2@@Jc;`s)RN-Tb#Sf8^}J*)xAP`2rYT7Irq9f3*5M4DqqDyDv9N zM>Bs>@J9Kmdwiq)Ok!Vs7Mw(9ct2!?5+&)^^4NtM$$b$g)=tuFyA)Z#c)geu{F@$W zwg_-ZPvSI7DfI#}C@xPH^}!{XC>TVw5CDp@gX>+>^u3D5Mh>aV$}?i!#P0+D5HPxE;R>hn&w;I`lbob@z(%&InYK*7~6Qm z&%px^Te9I0vG`D7EP<3N`gj-z1$ZSYb>grx)$cDY<1E0J zAt1*!jJh$Hh({UX3b3Z{i#C(#ekd9wLB+&&SB;B+h}R1Ow&TJ;_{^cXGd~C3ME(EC zi?20H{xa%;nV~>O!BMklnBHD=_|<=jb(rl)-;19ct+N;VvERaDKfCbS4^L_G{Jlfs z*s-NQA6aiv!liJ;lqKZVty|kWxwuGtN zPxY73w||Mr+a)ePQ=vBGV3U7mPX=S74aG_Mgu{QimhbaQG5Ixp$_3pNugyQ$;NAXf z;G-j`7#yzXIKP?v39S%WNy&Kp5 ze;y9(Dy$rJ4aCyU29Ew;fD=vDE~!GJt=*Ozr4zpv#BY?Jy1zHW&m=zf-hb@q(5W(J z#T$-us*z;7?3$>_Nm+{X%>q%IMnH&L#fQy8Hp@}IF_TRDNZ;jXzeMFUihmz3%UR(b z88)YI(_jBizrwY;y4rty;R`=SwShA1OaKL=4^tc=9oQ#O9RJ|UvzW|RA#=;HqQ?a{j z;TO8>Bw5p;y;|4XKAvqp^Eu_o zcwHGglfD)MS^$5<jW&whI>uJ4f9>Kc&0`IIU)_?l=0qRG z`b6R;bfa{-X7i2mRrmHr`nf; zX}XjMbnRonwnR-iiV|2A;`~?eM8G#t$;1QC@kGG;Xcm7*q+9-KV7zIstL$nKKm*>X zE>nA>u}@VIX{tBX{H47cU;Ly()>@+;lWj~QkV`IVC0)SDm zXcDPSn(!{(Bz($9mpIF*W^tB}2=*IDo!0${Uj&@%_117NzzR>FF_^kiQ8eL%D(ZmR zU9b+YOXjA~m^5#88P$36R2i3W!Fmy(wiW?`S{Q$5QIH{?`geS8YU#tJ)AjbED=!Cj z)|;Pg&a0WHrU*q+ltEZqr^GnDo2A28>UB5=bX=+98`mG&yU{v(u|HYgT?)H9Y&X95 z(R=G{rufq4mQ{;5j)80_r@}dbmL9H)@~mjnhgCj<(q=O*0RZ3PSpn1@cKW1GAw%0c z21tLS6K3orLlL!)QmC-Cg>HtK&7Pve-jO9E*#F{yhH1d-?TvY-IhWQ&aJ zsteNhg@fxcN^iSum!X|xmjg-}lZ!GDr+jP|+%7qQr?n0tuV%6O8VBP{oSSPP|B}Jl zRYvhBU-RQ6tZmLVZ(sgobMo+)yByWD-oor%zjWpLtG@#VCkely+`!B&Y|}W~3V?r( zRY{A1plL;P!hKcPsheHm011zfI0smecwLp~33GB!c-M`8`Sky>#dAM5J+*KSvSZ8N zxcGAONQ1Xa?V_k7yHM$zG2`@alpoD%!5ihL?%$2}Gl_lmS+K1`D!>0q^4(s*n&uo7Z7mugy zu_<-h-*E6i)KR-%X5bBRq*GRq@p*Nb(ssJrQQ|IV4JOg4ZK2J9LeX53-O`qh?nB^$ z!B6X#@zW8%FD5u1Jmqhf_AOPiLvX@3`dRXqSMyBosBt#c{87AGmo{UGx}=|K7H08? z;2xfnF{a=wzp}UPMs%;z5#C!H!g{n76u)`Yw2@ z_a|0YB)m#;SX3KxFfk!}F@nGU7<#?$>p?Vkmx!|4e^F&uzg0*iO=ni8hN)@l)b88Pjz+4rE(LiC*yuCOIsA&42R4 zxY$-@;@?1}O}#$bCK=@H$v@Vh*RDb(Ru;}E;YR3ai(bP~vvCUd0yMZ6;DuVLqm8En zP90dgzW(Z;gQ?)y6XAl?jkwx`U1d~&UGg`aHZ~F7zz8%Lf^vVw_NW>c25}+Kg}2TQ z99lT_WUn{Hp8<|7pTG1vPA%~4Pbr)Mu`rNvg|j1;y0eidd_U{FUt_?r88>$IxQ)}P z<;U5lJ@3CpfhYHw&V9NvwYyJR7R~n%&T)FVG*DzHRTc(FDjUw@`7K@^up@d*I9?vG z)d7w&ZIOVFZKHqDWv^L6or4>m31EBc;>D(qX8^G1MmpPNq0N&H!{)F>TDl2oQdk&Q zDWVoiEfG1zN}C#6l|{rr$^#EQ(j34~8n0aOGjgX-&o>t?*jr}6%Z3&VXr~y&cRi0;NuP^Vp6a((`SLOcmE?ePhr3UkLuABx!?sGz zGX*g#*u{(6INGIZ^vU)|u|WG8&M4th(wNfkANcwC=>z}A>gE;pf|dD&0ni~06S6H_ z9g)*I7>Iuk6v|E_H=y`l5!k7lSu{BGDV(sb9NbvDk~?Wi@MDkur>CYDjxFB%_i-I} z>;hm8zx)5S)fZvBYr?^6D%^6hszc&W0{62H;~y7a?7#4FI$h(kA9cpZ#2sbYS*Ecn zNt|QH5os5<>2x2j_^Sb@7r$t83S#%OV~6C)7WRM2MFxIsFYP==^9)WQtk@lD*lR5; zH2u5oGI?G@|4I8LK+)!YyR_P|s%5Sj+JN8yK`Oh1-tU$Y`ps^sZ~=7w{Q2gUmtQv0 z(o(;9?zyX;*g%=;E#T*Zr;|=dWH7=+IC+(>`_D(iLHZZYQ$@Pj&K4VJ^Cm?GX@Ayd-+!5&u^4X}SK3OrXhko{V1skq zqMZA5{uaiu-EFIEVq!EFFKdC;)F2x_E?gCMenW72eD<0I}o31vLn4 zkE)X_3gW^*3xw(A#nVsVcnz;d<1|;P-8=ost8e0wznej>Y&~gq!8k?5XTYOMiKR$& zM^*SYONSn7U*lq|H;5f{_Y9`CG0O)CBW21TZ-Sc)MAlVij z7^BVvP>Q-N`GIPAgNoz)$-X6&t@VYUM`xRN-uANq zSFb+PEG~U48LBP#Sdxi#L`U(Y?~H$X_7?FvpN(oe&j$)A)Qm`8(B?>5sF5amCrn-P zg$&K5g^G15&%BU3JL}FKMLf7NS zwkA%^1FKd18_^=Q8gv*-+^Dr}`IJ20BKfD72lO$@4t_`8Km3c+&Gf(7w19heq`mLuW-b7RbyfqWL5pqT9N1Bn8$(qIe_#=CVEWkS6o4FQ zo0MsQx2j<~{me$W^ItkeMwGIZ3uO=+HysBx6jkArcnht@>iG7P&h0V=7s#k^UKXz0I-vF8AcPGFxEKm#Fg~B zpcVpzGlv&XJ=*W#HsK*f4!LbUdi?<@52FA8AOJ~3K~(ML$e7pt%1qp{q!l}o7=-n7 zWJku8z4+PBI=9joaN7*quJsrfS?^(72+)cj!BdKwwN)(y$R&S|wa~UQje8s}8Njd3 z3iwY6d(9!7v*#a0wpWoL@nRrkM%cpw;NrXFkd;bm5ul7a8{ksj16OcLu_uYqFu5Bo zRB<_~ANlY{nlFF(OUAkL&iUq>-@I(6n7CL_xax39zTP`TigwEnPF~+5Y?l6gD8E^Z1ke4 z@!>w6@Uhq8#!%bt@Mk>KkKUkt*0)jp zn^xpJ!q}dfI?k8HeHm4GhJmpvAJG}xbW+!PKg0+c5e=(ufEePvwKQP(ZqjnWJu0)l|FG)O8f z(%m9Mcm6@7yGy#IYv@qAq;u%*?wUJ3&%N)x_v8F#zML~>@4fa~>+BPgfGd6!lqf8= zx|yf!P0xW~aq5`8(Px>)e`Z9RbTFG`MM5G5S{G+>Ji~w{Bhas)3K$sBa}cww%{=CA z{G5yWC`1mi`Jm@mb6lgaU$Y@st$Go}@U$7?`b{5_I@Xkvp-jH4><4hG4^%Swb{up( zrTeONp?nO@pzKwNQvVF{qv-1=#p6|~E9>G5znzHWA(o@byUlZ#O=B&+Su^n4$>r?I zBf)H29^ODFJ@IhgS_t>%;Jv`{8m#x&R5jcvYTI(UN)B_kH*of;-@Vi%imW3oV2%-?-R^Oba(zE1}sXzL+I2$2jvqpT% zxAIIFolJwpax~K_D(k(!HLP8wnb*) zF@3m?J__Oft0nsyuwf9wt`hb_|BJb>GWYy6HQm6tOuq;?x=`DD{{>VOyj^js4rn!&E>F$*kJ&zq03`gyJ z0rCL*NOx2K`VXKAHSTeb*9I)TAlb?zio1Zu!&6j2)lq|DWI!RMmA%4xBkoKpZFlve z0%${!s|xRxNPux|qZJ1@PiT zp|;sq5DTZL=w4oom%puhC4~$9%}uwrl<;;bMWs!=VKTc8+eKyr`K>SWm0z_!e$~PP z!l%n0f?G6adnF}%^LMFT&Ag3X#0AS)ORaHPcab{ivxS|U^{slUK`blZ}Zq7BSO6_}KIz{r=W)kCU zoawj&rWUl?*1y*XTsd*t`|Sg|=~ z@`p%FCN<_`mUDYhs=d)cJP9jt3syrJkxzF|5$I0UQ24`sH-$%c9_UO<=FFb&kYWdj zHOn;!Jh>!ECOL*76%UFGN_QD)iiYzD&>s1)Dg5NG>Bhq%O)!M}BfibTCyUcKu%Y0v zb5K2Wewpl3hRGysJ~^@4MG~A_5uv_t&YyM{p|(rF>i|{TclIWxzl4sQUl>Fn_JJ4q zemz`h&YtyqNM|kI?YQB+Bl6tfP}2h3e>IGK`l*L-`x>dJ>953L*~;%q6nELhYjpt3 zUar@yXF&Lq6mgHI>0Se@Ci!JOlvu7=LHxKvzG`yj$Rfn^v6~t`vDGqt)}We3h|g`Q zZL0MVD{CQ4ufFNKGy-Uy*M}uNA{p_$PM&=FiD{JTJI8ccA*Ez#_76XZ@AtfbqFW^C z#Yd+Wsj)Zid`mLpFQYI2ILQVwW=d{bCA)M)aRa8J*~T7J?QcgX6Ugbi`7F|r$~cn) z7TNPs?qw#(uy>+PDZ-Td>DwF5TWbps!(_>B-1D5Rmjkp;-||kXJ^D@wFR-orNG<6C zkbkU5tG65P94vOP7UyG4eL8FfzUte5Zem{&8MnPeGSX6^p#6|E7v(O}33fup_-0A~ zi4%j$Pxgr+zK0BNBz9zh*>M#RQD@DwGuiXZ3V>SY{YngUYrQ7z>SsXI<|X=PMIXJGXlQ3ny}ZRCXF+ zgwQX{WEF{hXSR0fcuEWd%b7+EIkqgmxTmqv+o+wX+)g7nw%&R>2RkY=8XYSNY)h)S z#gRXfZ(iht^cc(zTIuDzxBvL2TBxT4Lak89;Ia`e0g|$zOUCKRSJtcQTpAn10k>^}1zVV3J z4>{B}aa1m{XUw|LsFh3A=Ct@@cJd|Pr62eCphDP19?g@MLG399j3*N_o4u?OMw{izQ3T_(CBqle zk2<*X#TEOIX`#vH+);?HZ>BQs=tEO>r1qNu+E zs%C#a*1trdv%HXlhB=Qjypkh7d;KcS?3-NspsjmCWZ<(&Wb49laHm-qxgkm6=%b?C z8+1;ZY4xVCstQNi=7kg1R&7g!IjfhreqXEE^ajN6s?gdKca0N#XvvU(qXg;-rjmdiDa%>Bo6fEbMp z=){Tf&KxO<9Z>IFcaFS~p!Be_(f_^YU?D3sxbk}vVa4XSdB=9r5j*G}ed`OOASwRpd7Y3Vp{?3`pmJXR5BqdVl_rMF?#r#dS(gRvnZKgu%auy*98YL?VR+j58vC4m58=pyCO)gL!f16h+Lk;|PdBy_NU#^<-Ub zA-&5V>Xs+-J1W6&QiWh*Bc8vIPm=FvaB@oUwc)UA38RD2^lBp*A{_ECDUa}8I6ZCO zv)l~4kI@H6l$~ypY0ZVo88pf3Ee`!#od*PzyEcd_poM`p2y{Ch-l|HC=bT5O8j=IR zZ2^K1iTHW}?I8l+3kQ}}T(=hrUklv5p5@AH7Sx4+G`L$9a zMRhLLzID16#bRMJ9!DwchA^XAo|{~x-H5>yp|%2K>>D3nn=Rc|Qa{6bPeO5~{7J;K z=9z#zB^9OjW9gdSz}fPHY4ARg6$KeEh!Gv*P@<@({;?fKWMT~`O8r^(H@wJstp)S-Ce8tC8_xT4 zjAyk%)H3VI7%?-|ks(h0s~REI>_reeX?qSsKCF!ndxKG=7|Rp&mMxx#ItBo#qDIw7 z`pf->(G+=S@NF1hK^J^N=$UFi^P{knD4*;kRU0pWAv5+OG4oveWE-4y5&nSTfI# zS2~H$+($cHCBgT~s6$8J*#o#@Br0&e*yw)KAa?wrjiD{ArVAH$l!Yh02@l3p(hEq8 zqe_#$$WY<=-A~z<9Az|hm5wN_x=#2aqiRL$auy*aIwgSqOH|y#JB<1#HQQct1iT+% zXa%<6O8x#Xrn0|f2fy~6s7FXKNE6ZUy=PKJbfoL#3a~b9y^B^$#OnoK&a!;QanzfS z{A+8rbz`w-A7L^-}_rr1b3 z>=`}XGV?CeWoOwd*>3}2iiQWR!!qRo#~L}}P2+-8C0gNE(2Ldj8y-;^(B_?LQ%k(< zo=Fp7bSrZytx13I9`GpHrzzn z-7K}Z^+7k5Up2KBXn~qu(4rvX$QacniFl%Q?jEz3|7{O>6n+c56%nSd;i|2nFukf7 zUQ9^WbuaXia(C|p_3>^M)tFHul}=EB2=%j5VDlRJ zrjS9!n~_&0rci;bx|ps2RRx3(<9Yr$%FM9}%+;A54j=qn8JuN7PbWMUN`Wl(t@0O! zgF#k%VWh6Q``I;IRk9(n+!mUBg;DGWb$qMIJ=4*VBc%J}!9VHn{A|>;@$T!ZJ?2`e z@?-OlWM1HU91S$L1O;K1jl?bv{)6ho`^Q{`;br(4_T`Ak>FS(!BvP5$WeFqF?E)|l_ zKHpGHX=}46*M|Q7*_P;9B8uj7pHTZ8@xrHiE5c9kD=0mM^3*A)r2J9YAMI^$)r>Ja z4~H3Y=5!9gW)^|T(|KK%BFq?2nbN8S*{>oy)iyUQhNh%8UZHa#-a4tu$ic=8hUZ5O8%wi{%ag$KwLk`a!7%lc=-2n(tvUW0ywL6O(Adm@Qc;(E9{6W$W~Z6BE5(mzPEgrJr3D4{E&@+(U79I{>9A{wkN+~5S?I= zW4wrbvt9t*N`)N?Z?D>L4?NlR&uWMz`5a7K0 zc23Bumca{(^h*ZM@A1P%B%S!~C}W#>SqOfTG`m*W)CYbM&KTCZ2Zlp~;Bs#=h>$tw zs>IRUm^Kb^q>UH>T_3ek)JMu4C>YbnY5VdqVm+#2kb?LlCFxOt^9=={ykr#0S zjDDOgvr$x}r=>X;DQ7uUw%>pHd~vn`U9zqmuno>-?kd(b^w4ZCX4*o;pzgTJHMfsX z-XQYEa6iu&m_Q^pbwYDwv}?z3*Tat~`!vxkpo29q_*B7kpY3FDe-g$m#UyAU6eB4k z!isDNtudL&w%L;$l0)v>oT+?r37PK&%*?MypuR$YK_=R*96zlbKSc&Nw9vNI#dYn5 zCgeLP{cWTSz43JbZRe|Z%%>lCuF#@nIT6QjrIEGJAT$gF!WnWRT@wKv1<;J^smm|O zqt6FaVGRh2PN=Lo+}WrCIB{D9><547(tYItt(XftJagH} zaC^Y)JQg9g9nJiBGd-KK+5h^!-feSs^~ab8{+)zKBCk{Yk4pxj^0#)B--MLf5$_)E zj98#QzIaS>hnN|WrXJJ!Ru$o!0|!qe1O3W>xL_t+#rw1>GHrEqXfy<2ZxZuirjBg2 zE`M|Y?jZHbYcB=%vO4|R*kzKL@~X?r?h&yV%uaw%w2w)|HOKhYFF2_BZGMqU&#E03 zjwe!fba8>?M_T+jMgnu+6f>dS+MjxebIbEi3%qH>+KiF{O35FWj%uF90q&=WnxtmV zRE^9UeX`%l5@J_V)g^gDTIj~ehUNmbci$DY|AN8l`+I$8zUBJbUjH&1^N_@}=Vh{& z59&}?&u5D2DivWwKRZ8LuM@M*Zw!n9cSS53W>Ys!*gH#?ml5g8e8P^$yW>a4LzV9k z3Gfd(oa7HyFzVF?_Xu%-BkUL@43?Q^8(Qogl}1hQbO+bm#|dfO`;ZdQLz8BVAv3-BqC@VDNJl z{6(&o`VCGxn1Uz<)&>E4fuD?{-EOuu^u+!$gnA{h9-KaVGaFrmDMFX>D@DwGczmb){kWiCp zuWF_C=pK8mD6)VYFH2pHpNY0l&}SAH9DcgLxK=o@6g zDU(yFB>5yZ()qyK1(G^;`B-$3-;KlNK40}u*}ek$tkDCjOpMV3gW!3Yb%}28FZYVN zXztX>XHe=AMj?Kf3Ikc*FkJEAv9K_**Yp?U zb8!Z=Z;HXr74T20J$xaat9dwJybm6op;p(cS>D{P>qPEYUYv+>zN;uM8RM3k1$Jgm zMngVAe?KUaPH$1P9oq`HmkQZmC@wz@#Mh8J-e7g!H@D(g9ZfnDY|lgbi0F>%H{yjJ zlCj*km72;fm0jo0w4AH93~G)*Tv6F!qCm_6K6gNjM6lV^n|N#8i4bHSG*4d@3-1q} zIv1VjyUibq;x5HJx;e?6dB%d?GnSeTxqhX(ppL6wtiO8|N=um^x0NOm|J~L4;YK<( zK#a4ma=6v4H2`2!-aj~(i$-}hr~2L2nQ#Q<+pt7d3bNQxxlOtL&M%%#$X2OsLo@Jb z*P4%C+0QsRPKQ`IfVxe=~77@`*31PIOY~%S3O+Q{+aQBkF&} zNTUV)4iTp`VPlHc8WN9JF5B89w4Rr-F|{%A>9%T{B~hM7@D`w~t9s*hFcy^>&?g<@ zAQ!Ef^mn+%pGNdIx=Lmem#FzBKGmx+V?;`H7}$tVhAPGi93R3(e1z`1W(-`xrlhR5 zwc6uD84%o3hF~gdYfN}4S5?LGi+Kb_D#`D&C%VF1RzO?q0nee~mpoa`-8vRl`(ME> zVC{oAh#*8kB(gk;4eA}}+gpY^*o-%(ZuHaU5RWtk0fFFR+2A5A`UrYZe{wp!z0nA2~x-3mwQ4vA(qMG-# zgxis+3fuDUVH~GA&nfWx$^E9nyAG9iz_jNrJWJwaqMe7B26|_nXDpR{)oS--i)=V5y`YV5kw3|IRXfH)?&(@SKgGmxEK4E zifhl}+>!mj^-l1&#opthq|{CHT%BC#*)PeH7t5hTw2 ztQX1~Tvy_l^k$OPmWu))%1BnP1y-s`#Ja#HD z-B$e+yc^HQ+5jdl9j8-V>5<>f7?UKdFndgc162}=DOLUhQ>s7b;-G3$XH58p{1i4} zLsk^6PKuYMikFZ@hDw&1Ulutifa2#p>qiB-rU+{lp`0x#l%JiA1e)g$f2JKD#-&eBnXIMD94gM1>_%Um_Sik2#VIiPXP^piM@rrXXkcyIr=3%#Wl)3JtIwui!~J-X+W+PEK|!A zK&6^P;(hz(cp(RKz3>OBC~NDv5_q))%z`)n#4dc6Dc#w<+MenjxxonEAnjvI5V%A* z;1X7mp>W^y%jU!Sit&5mEwLoN^KKVP(7X6=029K|QGCmF1BK0S=chG2TYcwh!4`Ih zY70h8mmCF(LK*WeSAyWY0jFSUXw_3KF9eh@c}~r4rc2rH~?*`x(k`t(a!KJFOR}>R>0GiT*mcd zHP^u35_Vn?@}Q*Uag8OVxabd%979oz=YJ8gDuW8CX3q1C{K#!Zb*jpk(Zx-CHw2T8 zoNt5d;xz_lc4_BV-a)XfwFzxn6oJ^x?Pxe6hu-9!m;4_yfhlzPfp;?X)1EKb$m+;b zQzW0+_4>R6l0EG$HZqFtsJg3`; z$`IDt;15!iEjF=U1lN7fy=X4)om#S)?QQIK7&3|SA(>>lMHrl%z+gnha31UIg-^wQ z(G`N|n9igB7xzB*U`Wjd{2VVvOMl`Yf6K;GCMjT;ccQU!IJ4!$0PHgtI9IHvOxY)|M zm<2E3H}E9wII}hX_&g|Y=1~XC7@3O5_fL|sXlNDP#(2fV*K0bg-^4*8nCT$<^e8g@<)^zaenD}1aFh~wr z!Lv^Oo5>WeRW1ApzWjPNk8XAIu{_+f_jA3D)v+n_GLfc7OUES1H;h=GRam&-j8LCO zT%$hrBx9t7<{Z`$I4IeV15wDRbfGOZl8u-V0y}74m~q62=ekfqA^dR3guJmN!|!Ug z6-A|alnMUFEcruV@Qrj6)|lAY`}sM(NJ;Q8@!9+CZZdHDuS-OTr0G5DA05(5uk(Q= zn3(f>>U}Bq+tcw1N}EKF8ND%ys!z>SJnt0BX>ub4!*t3u6|6MrrEwmUk6T$ib`Yjg#GZ<8I7Qq(=nF*vh<39AXAs-MU^QX&YTp3ZP*VR26_ve zUdAWxoDJ4XE~FM6iSv#BY|{Nf)xs0RGB|@`j^Lm(cpq~ z|8|{Oc2wc;y)CPmIR#DJ5=^iut4Bcxm=WO`iP-P!bzK|Q<(yU)fur=k>p4iC9$H?F z1XW%?xqC(9LlHPG|~_ zsL6Q>m>V8|_amqaMRY66uid1uvG*+UoC+V_)Alk8W#(+0A(LB$V?Vi}j?pmFrbzhV zDez;pYtQg_P;he!dI+XcJ<=)f4s1iZ=!#aY-n$%qn&{!J4Eam*OkXbCL6fd^GvYP+ z>1m3aC0(Kpy*kO?MmaTdn&Se%zbgi##d0r!x}W?_6hO@*$qVPbt=wF+_YjZoEFw5q z!ZQ>}*PmWuT8}zb3-J22jG3!`;5!r9N0op!)GsME4687tq~`Kge;%lLJ;?pCzaM;4aOrNn;(-~@2X1e_Y(|Ye!LQM#GRhZ#j~13@w2hh<)nyOuo>Ah zbZy<0Y<5C;{mf~sJ29UBS5}JSv8_veg!mg0L}UP{7fy{Jw4BdJ6tXxzLtucjou(v3WOwRehdw)r*m?Bq{R zIPfWr$?0euwX!fZ?HY@cwoXjZO`k<0QNj@Y`{R-a>Gju-Yqw`d=j#NI5uI;VpEiL< z%50?5m4piI?`5sOa6Boi%|$qAszGK)DlG)El$xl`1WJmM5j)8Bofpf4w{o~#LL~*0_@j=DAG`UsRZ^QN zf-iZL58`Id32ZI`Yl3d#mQ&#L+)z6x(qdA-(XTXq+V6}3xq>5vZI?>RSj>D27)v>T zKc)T6+~VUl=Gn3jJ_Jn(NYkmIQ)y;Gc)Lm%jcmedctCCb6l;Q4R~A)XPnpk#T;~#l zKRireO}?9AqX5x{@G-&>P*V~oI)!x;WQ1`-r)wfoW=E@tJMuxn69;+ZY}BMtPKc@a z1vu4volD?~#TcbQbqq0aJZ1yvLYe2fBRL2a|1fmjkr*|&=HWr=PI^gKuOBE#5?vd4 z+?-w7>2?$f8=j|H@Q&2&Fs8YcL&{S7?G{CIQP33}-B^-p^SrZy%|g^fC5MRYG^$mN z2x6j`k?uJq;@w6(c{;1cY_dGDZF+K;Y7unOSV8MtjsA!rPWk;`y#)Rfu#on8VMf;4 zf~*w$EM8Sc#TG8u3nL98r#jeW&hl zPBjH_KE|S<5$FmM;+@kV9iTh=(RmH}vnhh!5le!G;N1F3GSdQahHG9tyB*$ig?nFI zpU(@)*y@VhDMw)QJ+ul+w1dRK3@*6N);BkT$0+$!ef7QhGaU_N#QGzyl}H8mh7Niy zE8Ldq%mH%?FoG4wjpjn;ufh3xUu0j3Lf458BU_~^kX8wgc=#Xeemb_eDtne+@*(7D zf=}Ktj2@-Q^Nj8>pfd;|M-#^kKOuGyw7^{x|VNS*XenJ zx`I0u7p|qPvmnHu7L2uik^@!$#qj9XK}+-gZ>!EX$@hidWGZH;kpyGp`fHgw&&qv$ z4VQ;{$5?GUzwN`(Bcd3+6Tzeb@R2`#GRFns-CCnenynw=+oA%(Ck|>U>uzJp?4f*K znI&d!PU-jjx8c6lzuKN?afVh`i8|&|Ey}FTbl#}TCPQY>wz$X=ao0n9GQ!vE&R*_W zJ;OmywMgDKp#u*^qG-1nLcyKdz9*$j(IeO6IMQ|ZF>+$Y3=BRZyXtuh?3vyv?Q$ksq)x=nc z>oCm67~rE|Ad9At8&K8rz;o_5E_Fj~E_|T?CM^ywZ zKa#Y63_jIEw(p?LAK=558P~h{pGwED$(T7lsTEiQSJFjr!s0tfGqWb5HNO(yBL#7^ z8u)25@`x4`d_Cv-Wslzl?0!dMV{;<5s^c|zB(K_AdwLn@2ugWvgvf%`J71sV%KN#E z?zzEb`|mkn7JB(!YBMIeTCvxO2dz!kn3@`!+bQJe({pUDIzU8Z_bK5b6T7g~xoy7Y zsM>XJLp;s36AlZ&i{P7~g=C1WmNL`~*U!3Q$T7X-sZYAUdc*`zlcbB^BW*_b6denr zf}J*-Oa=4@9MLO{EQ0o6)_G#0tjtqni-nq<@m;i)PxC=`*!5$AsnL~bb3$Y-ZpWW) zIDt@kbDeMnAa3?J*Vg8u4KXGEdOqfW#D(UJm=yG?!DW3El8hjvNLV zNL-d*@w&+wz^wiC&0YD|WAHqt=orO z+~@ozuc9~MrE$4@vs|(_9Mle)q&)xoiE47nBS9hFzk-wfQ1h7WnLd+nV1zUlD0I>; z+iriJC~5jqh2}kupiq8dp({c5laz#6zE2F|lT_iNB{Js$AMWn{H%*BPs>voH2AUsT z!3|9%RzJtbhtOYO&Ri`tmjKFT!$fiaJ8J)jV6#{V+Lwu-sEGFdJ8E7zJyTwLDP@gj z_-Aac_e|L|B@c&Ij4g6i3{EKhK*Hw@^CWqNclzNY@~AS>=2-`rf+qB_bMUA2&T&Lg zqNzSNm=KnxL+Ps@S}y#hko`Z!v$T4;+PqwTVIP>Q8A*QfsJmyLZ0MyE8JfJ$E)^H! zgD7_WDpCTgJ6GQ-+dXr;JXS3t?-~>)*iHJ}44K<~w`K77UOE;3%NjjN1CKR+CYU`q zL&}ux-7KFwMRw}jC_T3tz6olPuzG|aqd!(N5vnG#GXiF^t!b(MF$o6uuRuxgx{`K9 z2v`fi^H!nNU}!zqdfUmjd;ukUPcXQk-t+B-d!Iwp7J)@B?WBsvOmm_Y$`r?(-!9Ws zF+C_AMIc@hR7G?9(M=~lF|)7H#({4klDw>^y28pu+k%vdQS3)ao`an7MIE~p8^`~r ztj-CTwnc=dJd(lpLIFswaRB3QFv*nJ4Oj+BU?2Y+V!xq@F9+OC=F`2=6Fz;~N28#7 zBBpeZP!%fsMB4Zn+$&xt^`@kh>rc$c^$~O_G=BbNT{O(UL+CCtN zED%`ho`=+fYr*8skqrIn+uq(=b1I?9y>t#waL|XQ!g48LF zKjTgH9-}U&AUdEe&_TS7PrlD$FPnR*DdIb1G@Lm$1Mx)B4%x5POS$i;MZ)g%+~2+g zyG-JuTmfCW`B(XswU4gH@QDn#-f+xizuZ)QDFxV8FFME%}RL{xoW zf@&tJdX1MatCrUNeCnfN+B{?=L;3poq+I&p0*wLO)z8tnpxNQ{uYiQur4A+zR>gl;EKjAfXWY|l5$%{P@y{Kw zsuujdP@dc+bRgPzpXgt*V&}Z$1YZO?l8<%tc2)T+>!a_o7(u`Ez&Ww67hzHZa}>4{ zE`NWXIjs0T=vQpr4CJEL*Y=0K)~ALtCvlSo{EkyAAs#oXy+5R6YCESC@M>dhYTrrYBngRI6x)QANZ2E5&=Y20tEIWUPC0 z=kH_Aq?IxgHh>@*C4FqXvhTe<%-#Is81Js@8*isU5&;fcydzv<^ed+T4kPRP_c3YMMx>^Gv%mRG8O@vJ`uJHM@@ zp>+LdasY6Dfm~(lp}08L<69S*OJ5d);fu_5=K;P{U#a0kCCWC~bHn#Nba9dr#;3Gf z0fsB`&57GZ^c7Dnjgh1JU_XWtBDiTs_9{jK@jJu2Rr+BR z0ywRE$vytFEa54A8{O&7kj9m7*aV7NI=9RIap4{}(MF$+`h0)a7L{^4G=;P8^!<(> za5VOQhNOQklb?uX+V*H+Lx+FmQ1PVw##h<;&#WXby}yr6W-JQ??XW(yhLd$jiY@Tl<#{gg!W4?070WA?EWMZ5$ZT+}o=h}KC)i&n9q zgg509nqBV~xZ1VAW8_kzZv9byjqmjVw2=&MwHD6W&AGzr!Zi$Y-w)=eJmPM&euxb$ zbDvyNd8!HqYEuF_K$kgrLjuk5ZxQOKYxp0L{ZaiO)(Ku8pLAN57d!=?=DM3L>~OD4 z510xaAmmc*W9?j30%S?J>%|j=l~VX#GlYdo7U3{BHMCS9-=Ov-#76|;uuKmSw_fkF z9#=k}b1cHHX<&0cPrTn~_{>~(&_`|CKIyrQ&BkVl0OLnaF+=rBC@VE(7r@b?HIiX_?Qu8uLpy zk>J0-nJRuKDzjvIA?H6KTmH2anzyIbVtV%@ddk%SlTxndG5@MQ9U6tz1CLmJoT8w+ zv)ER89KZ)a{$7eL{c=C(H`7oWV{{6#@L+zZldwR`JR8mvZlEFR9^yO%vTI@Hm2lpb zr_cg#R})-DmS?`~<)$Xu2o0K#MdNzwwA6Us*OR;cCA%qJ2=LiojytSw|GO4Y!5R1@ z^SSZFAN}KXq|4uDsNr){dPdK@J=TSj)3GwF5;h4uUG|AFvVJFjZI4oymV0Cr-H3*J z<8$J*l!3U_C+q7Hl{JRlYM+7X6Ze51+LH}c(b3+s*g zKEI<{&rRgu3lA678{++&`&4_iV5v09zGm~&L-eSAGkegjcWE z_W1&fH-tkJ*7mRiJfhoG-;eOyUKfcu9k9;#cG7_cG#1Jmi| z)}|k{0}`#t_hSD3UBpmS45zFZ!9?g2h_Z1NHX~;jN9N(!+JvcbjFxME5LfTiC>+X% zlQRb7GniQ8kwB=7SFr2n7nhlVr{A{deMa!9zp>$uZ-9v(eg!We8T^Mj^hq}l@Eq#g z#@^zpIx6`Lcef+RB1y*X)a(y|R3qH9IwQ zzp=SFGK59yJ_$nK;D;l@ZeW*v$LB34;QT?w`kod5@%nhg;KK7-Po~9;E!My>ROM)V za_xWCb#$epVPU=1RRdr4Y>8V8q|ED6CW@R}+?XlRS6tlL#U(43Dv4nATJw}ZcV|oe z_zq(|7bJpTA&9|do1FHMR>92@)?llI_)#gR54MPA8Ocf^+H1#~kp^$g-_MwH0p-Fj zZS&pj`*%r}1%d)q&CJQai@^lJ|J-o>!5Q4WDkM<(Unl$xNA}e9_b`yhf#FgQP&T^` zJS78;Sw7dHmZM@%lnv+R&3mW&4Tddtu>F(8^OnURx#g^en#1Qu*qz$V-AVN~U+X_2 zH|EhwAko$(8)&A@ugyjDiDF=GyyR6tMUd+JzMw?kKHI?=yz?(BTTUrY{BJIknB!X< zZ1x57ltyo;hEYa_{;fc!-)cmI6xIv=%vKoV@j&jwupsC(atR1?*9jh=4Z`6Oo3epW z5HDFfT^kjlCxm%nGa^7@XTlSM2WQh2=QZ0t;Y}O{^QbMm34{Z%MG|wR9bB(TpPUz# zr!!)$qZ-+4l`x;(HQ9tZ;5-0-*{S2cXS6L~dgXa$r0ueXBS6d0&{@;>o|qrD8K2ov z_3q?(2zVA-Ts-6*g?{R8b9_MYP!ON+JZG3eI>n&9nE%lKC6sGDL60*$!7{9;1MgV+U+-6sEY}W9?YW;qW;IaN_9L+|Ke!lAeFHYJF1#yHj5L zrNguuXsV>P(Y)`t)r`82>`)&!JP8oDk4y; z52%Yx*;6(>(!G$du7VSEO-JWp&wsUHsXnE#t?dTUKIS};IhOvAq!qWOV-(sivA78m z8oxd15qy#a2<1+@r7S;OBc@=fS9nl+V2*t`#@#EK0)f14>+vVx`jroay_cXXuO{^0 z29y%(QtQv~|K$tlCtZ-e)d-2!A`k|AuJf&(M>QNs&(~x@Y7@@`9WZEz!-{wO(n{9D z7RS=Q`c&riXiI*@$q>4s9DE4>XiI@x6{iDMmiJ@q!w~G=@~!Qgh#O=A3o|jluHdV? z-ah(2vC{+xft=*t-J33EW7AdIkZJ=v(}n+Nu;q4a(F1(8Emg%#2+hl_z=?$^k|x6C zoP||XymRhQHe$Dxl^^WtrirEjCqkkY$1rI|Fk7`@yBbG9Fjkq5iB$xt(aEJ`$C{=6 zyUL8n2bq<599ZTpts@SNxzPc6Qsk3WU6-8d&xjM$yI523+^yxOqf56>e2C4)uxEPG z#JkGY%UrLuz(cU_UE9qf&`L39N2KgFxRc=h+~#e5R-mw<>!b->H|i!bA!1avo!2~E zRr(IBC;bk_qju$Aat@EaITUC+c<*X-`$bfkrQ4vbFhVxr`chUw^c|ea&|oaWJ%dY? zl{8=4z`?x>4cq_GrOz9W;=&aXxS+0iUAhRKWym9(c!N4Jrobsex78b%7~_yNNdkcs z`P?V){DPzs^#n!j+GdUdh|_G7A6ov+3*j&h6Cu0o;q|BOtRs*N)mvXn?ngZ+6|~ak zv=d`;;lH%&uWMznWIWqv^*yZr<0WWtvfb|{oc)=4O(%B#)F-^e;h_Ha9CmC6TS$jb z#0FYQJK!G5YN})ObC+IHB0suwLcwPK2Uiby_- z-JI$uVc&Y^RAH2l7-!4}l%_z;5jt5}{j|jAB9`sd6LepP%(+2g1V@p-t~k2&PAwV} zn0|?K$Cg_;j@q+#l67yyklKim9@H!28frW%8cfxu#0(S73fxv>>kHG{H}JCB0~)B~ zhNfhFnhe(~pAQWCgG8N{9~VY}?U|&S^MLc0-OAKXcs-NnO_GX8*#NNB2V?oP7u)6e zz2o5oK%Qnpb?eVdh>s_`RD199NsK526W2EM9dWn*7E0`Ytv@y)rGweBlE-S z5OkZFPAa&ol(M>qzSHq5pH2#by+W-i9o1L3_JPn3|9j!*`5^;gm*4~L7-Ia4XZ}?- zK4?g18JsMP*a;Z9vaNsC7wB#_h~;e|c7WSK)RMJ^!oKc*)617{pLwmQO<0)OE8Uz{ zc_pFgZ@klzmC`$pcK1QqSJ8Jabz>l)p?M}#M05#XJa*j`zFcUZ4^bMi-|HM?H_ zpn*z2XONiKa}jKf%^nlBKsg3=G{pl++MIcXtmk&&7TJ_TJC_|DWd_%!}c( zxURLC>@$l`p)=!4+`iUg5IXFMa_cHRB95Vc(K zOuS+%8s@i!19DODdL{xBknV962B+pi9Vv85J@nIX*y>wh&V;VFvl^P5ZkUXXJBRV{ zu)Vt&Y*eXKWku1<<))SNu0Oz4GTYaL-Nx>{N-H_sNlu~^zCOCN@%^pN4+Xr~A=OWP zQv0RYwcNs}wv))?Nn9$$oA-4OuOE#BsS3>k z3qOf#@UqFjxn&N8+CEu`%i*^cTN3RkY1N!YrCSgJ!+b@ijH!!XQA1&~ z6E9?F-@g9|>FyxBFD|jFmGgT3thjj6UicT<01VsoLD`^EopU$)dZIJdHXIL!5aoxaOdWzuY?5qV`TC>0cVBR_j`8 zbyjc5_fNqA>tShC7Bh33<<&5O{s)Ot>CD6}L);j?Phz`Fch?_lws8+2q9ZAw7JB`f zfQv77X-iA4llG z+HfK9^Vvu=g~M4@PMmJH7`I{ z4=~b*4eT@%hy!H|kR2G0`-dWkFUxl#&4anuYOq5}=pY4<6^H!q=#U}j<5(Gluzaiv zAN^7^`f+f&2MXjT|(k5^TnC0KcRkD8=H zty#<-S~9kOY1mi&Qb}ilpIU%_e!#A`&e?E5A@QhwbX83^clcv_=;|?nano&&g*Y7+ zOJUzlzRxjljQ)4evig?ZCY^Iq9EeSZ%3gTH#&RXazUBjLq7CqjABy@@`4zUSuaS`+ z3*!Ba7E}*;B^OrOmU=3C@%z)8CH7f073I$1)~y7!7utmHY_*dTK5t4PZQq8Cu7Lo{ z#V9xj)x9r<_LEf3mxZIOcGebp)_&;|ja|!B#Huam)AX5zZZzyF}dJljPy7;x6fbdO|HwFBQ{E5os z3zwab$jo4guL~fzZC9Gjs{_maq$^>3pw8t4SNN+H*VujZ)p^v^%*lXt8omx91Dn43 z7zsXBWX7ymB@9qYky<|59Ap@LzneUA+76uHyvWv-l*sTEFqvz(BE?#|!O(fH?>KH%5yd9^8AEtG$zV3N^w#!|nN^&@_RK(W*>iJuzg z-6d_M1O@ZuARDm_LN7=(Z2LY8ehHTGl_hkU`4T-DHSKIJBoLa9fe3A_g4G9-du4V} z1!8!CVyicGp7D>SiX2#r0J;?dWAlU(WbbUp@MU`Ver=|44iMCb@?IR6QLlR(*g8lb zYBNN28NU|}Y({I)>eUN3_qryz7>89JYsgvk-gE6)-QZ7GV8VX-fo7j}+tfI2#BRGc zS6U@InjZ3+|t;yD8%os|9nCE&TaMUa`{jlB&#pk38;3lz(NvV(GtvM z;}^ZzkKHR)h<99p-j-v(5~O0hCI*9Rd1iWvVG`;T}k@T z5jmie^epGP6zHsy97zx9IZkz=>?-zN?dvvhJzb+|+ZhlCbShh44!ssNGqWqVA$ zk=Jfzc^zBW#Vo57p+p-Uew)I*fnte+PNlgpVcU^{ibV?P9UC?2!!KFo_zu$q(@y!8 zu8jWYy2+xST73x@oMok;Jp79-3)GPm%Aoig-Pz?swi2n0z3O72)-uS7k*xm*L!mc} zp2GhNNFf^4l1-a6ppwWp5k?ZGJ3=b8^hWDLnId9%#_7(j3#siAq;=V5u&!C(8$d|p8)>S6r^~@Gl`%Dlx9!9~m5=I;KgtbYHGuR* z;JQb?VA%LFSd6tmaybk!N_V+fe=&gp@;m0;_P6V|>$!Gn+Lh+Nz?346Zrxf@AYLAV z`SR7DH`QJoCA`cuYoD(3t`_%JWoq4Msx-Hfxh!RQ$lTG+q>+##@T``=z6E`G*SwZ9 zzwwOeeJy`|nsDpdaEU{?g>(`Ba#xQ$f%vtrZ6Gy3y!aIDwfF4_Jb2;j`6%IiVCm^2 zg1)^@1U;UPVa0c1-)n`eN#v2Ax9Bo?!k*p|u-n#(6r-iUSdLzfF=44?d_ebsupR}< z;z_S?pm+M|(wOxA6Q{K}TRY~7G2Ei-lmn;<5l>d1E~jkEC)q6qs{jz;K4QdzQ3RPp z@*8O)r4*kv&EfUWDIVt|tjXk!7U%`t7~BMIoCga2~E_+O!TK z=r0>`53R)n@ov0iWzy^XRMb@3E%)Lc8s(Iulo;!;G{j17o1qVy;eh|@Ce~kq+v0_- z1S!MG5Zt!_e;#VKZ-7pwVii+lvvhh5x~ISS>dkRi!Z1qO3=LawwU4rj^3S0-Cy6UZE(Wb z*UZECMa?_~nx2IARGO=%pn)Rf({0+R?qmr!@-P-hh3D7!+fGzuW_yRs`aobd2N0D9?F@CJ81$RBKWlJO}s!% znUpo^&->St98(>HzOs~v2Qi;`VD3dMVO8T{iI*ZjHD!oGg6;640LJH=e$LXuMP)7r zbj@&(nJ?+}fo_0nNb5)GLntc)2(=+4`4epCHcGrc2zo#7y>vBa=sDj}U=YXF@AZgm zMQfFW_$(Rvyb_+*Igq=3bRLE`{~&brt-OJ$KF0_N>GHH&(jPlJJI$$EzK1vT2y{1* z)z~_$cM-elmV+RG`Dja*PvjN%0C*Aql^64HFQ``L2FPvvPakba_$avHED&D1V14C- z*-4Ydaz{pY=AL~`&MzOJ9RE~nlK`jg$?3T@H)Qrh*H-*TOt$?PXG4!=#XOZrUV1SzpKh*n-)4bj_l~% z3V?||!)o!RR36U2wic`>UT!n{oCX6*F4Ia99h=3KBP9s?#A?%aDP-1bo*~u(8^2cH zQk@ufNDOc+ZvV&V^+LRv@{F)dZgc^(A*AzN*2xh;DW&b*C;0^VpYlgU!7Uv?c~Nv} zVu={BFaK_q?luWuZS!5|Hjwl=t4jR!`oo!@B2NcN=0^q@0+kNAJ2FyTkIPR0joQ=z zPHJBtuD@i&{Wk*Z`p}zFztSuLnAF>ro>Kdxi+L>Wgn;wz{Z&tdp}5TF z4cZvERhrk0Mz!~AwiD{M-m4%ozAmU;nn3Nr=&NDE{=h%TpHdoV85E9Q0f)jFN>A!w zz%aT>v1!3q@FNRCrNZ5MgF>#jpz}4iW`M}EAx$Pu`xvsdkjCt}s;T{ZUHldrPWgS8 z{P5x9OZ&=0Vb`_pJ5?Jb(z_>xKMamPNMIe2jC{PE%)e717?-F+{))#Xji-AK8huTR zVH0Ofzn0I>wCaJK1I_zPUJGxSmwwkgI5~M!%m3H@rGFMawC!7ooR+4lR8e&F=@l)- z@J*=;+|;27r7&ep&Fvy+zERXWZ6#Vf+OD){@^30w4&xEI+YZX#IbknEvxy<5ikNt^ zh3~;3fgm*UPOC=4>t^b*l7g1IK3Zsh-1@PPn;h+;5r7HTkUne(DcsMdB;ve4E(KA;ZstZnUzokY>pSUn-)?M7_M zKD(wV4MHlg-m{cz2g9r)IGZEIncTvfjRM0~J8;^4^t={kMKz#+Klb+EEdTrk1S8w6 zi604o?tlV|qY;P&**N>Zz0E5!Oe`cg7~*iViZl3P1f9@jyPm71H4Zb?XLR%Pej!*(Ci4EA*_rzll-SI$w1|n`qJ`vyXU3|& z9Xti@!Q^Qodl0=!wcrF2}cP14Ew)1w`q=+ZE6nrn8mHDgiO5^UdLUvdE8)@~*+^e>(; zWnWy<+{3dCcT)14tns4NWVehRv6MD2Ou@QYz%H8?%f3=*YA#P3>FKqNOoiG9g*AYC z)0;r6#VY-vEm!>1B(1xtt-fS8Og6)u=d_s2UJI(&;Tft-9N#nxDAf{Q1Q~@073st8 z={?z|CC}u+3LJoPfSCuN_O^*y%P}2vIs!HVZ8uRa(b!oET=r|BH;mq|ymee=^v>pv zgQUir5jf6D|2IkZqE^?E@U)f-DqG8^Rp*-Ot$_VfJ)O3U{d~M-K0{P3>&`h5ckZK^ zBl(~Ed!%h8w2^5AAi@jciRsr~bk1GA%dQ2Vs) zi)p}XKYy#ca^E5+1XbK#=d;?Emv}*4M5(sT`D8;MBlS^nt&hpk+3si4-C!AxI{nD)9Qps3-Al~(n!S_xo?GyLAppbFL>%(8EE^~{$KR#(%-~h|J zk$C|}dWB^eMcy6ryK{N?wxged%^03Em;yaYxBV~d|58JQeaT2#3nOK!6xDihBP#xz zc*-hT27==>ax}hlN1DHr_PVMpJE~GVK$o+{lbZ~B3OdT+$7To}cP4qyrB-VsSy;{P z_KL~KR8p<&<#p+^H_>VT2`ctuJlYWtbdLJ(rPciLcrQV;pSsg)Cum zRexYQ6dBTU;0Qq}d<_{QA8mhA)$CzmZqFaYd?t_8Pl8|Hz_z2Qp8VlVM4`36r90@< zHby;FJ#i#4RuPn4W|90LffxV;m{k9XzR7in;61f4i1fG%y5Gub0zo+Qf3$F_|J{g( zC4*>gzcdKJDI5H!JD;MRa)I&0UG-0*OKh@Kg~S+lnoqZ08sw>Q&cBQ>xCM`w%pEF&aDjb?Y-heNmsvwI4HcUV@F|+ z`0(1^(<8emvc-SVzY5UzQpz%Q6IslJa-nP=C%9_t@x}<5+rp$mlNZ(3vkr8tHZz#& z6sc_=_7LQE>Do6t_Y>Y!ojW6UKg65?cUbTqjUuC5Kq zZbZK7`nD3X#L)b(-~}bE^yO&2Pl6=gPA(6)49ihSKd2X5-BzuhbY@qbXvidPLpOL$ z6mw(v0e5BpHPe5MlHb7b+_j|`XN;ulI-r6dd^w1;(~UiKUhlH)xUTQ(OF0O~`R|tbIU|pSHhm~~ogx6SXO?*|Vo1iFuggvj{IY&%6 zU&6;utlX#CJ6Zul7MUSyiXK=U$UuU=j4<+}=ZT)XFAFa(7hM?*jY~CV{4YeR=GjXg z_p~nXd^*>Wb7}MD@$GTWqieb1Y}?J7OG6IT8K|#(9^AIV&qtEq8IW5F0RA*w7JsTf zNA#cbYUYR6R{yC(n@K$_478LCx!I}YmA8_kJz~2-Nvk2jnV>x~u`voI|BrPQbgo{E zLS2&S9@%*xNqaA-Z*Aa;@$$}rrPZv7xd(m1ivwr2W64j4KUOjqyR=1s51@8)stFw6+ByZjL=t;b+CS>7O*2ISNX-mAh z8!}I6{?DNe!@#_q9$IdUd~WaPy$&HqR%RTIK(s(d?AG09?sBbgc8G>wKUv6F%K?>+ z2g!YBnLRr#t{Qz%TV_KrNmbSsuxoF>4{ z?L>HFs(OU^hiu|S{o`0{{W-9vw7vgxBTu2h&ssq{&^Te;1q0;CF;_xQLZR!E^RjG$SJ4OlR@Z#ou@%y<; zv@&d+RdSyq?_tIlzYu+WGY0P0vLE^jn>4}bn9x~}vI~8f)K^_nT%4@MiX9s=+PcU^ z;4U0-Cv%&wZp;@{Y7&=9_TPx$Bq?5NT@~UXd=(*mTrUDmF#0Q(*M22OpW52Z^28H5 z&w?rWjq~-~p^`wIQt0}@L220jMkPVA3%Qa^{SOMkKQEFM;$euTSa4Xy9%ZD?NgnNu z=(g$zeQiB#a4H5rvi90h#L-mmiNt-8K;U~kA!L{gB&0(oAY3(?{A`uW}`j@_8-r;)-nW)LZ= zzZL;FFh0~jeppWY;9Fg7bo&c?e#kGcp$RwEi>Kd(L(0mcTkV+ABe;e2D&?3owr-jk z{O<5cggK8W2YmXaY3_vq(+G_9VNiWgdahwk;B;>r1CW)l%PHxtJ4RLWy_~Zz;Y_$; zzKocI!2B-FD#Uij=PJ7da$>aSVC%hpe^KCn!0vTo)W9~dtXba)&Y12&Ju54j($mHO zW|zI*!KNNG!31k14oxm*Vz$D4iN}yv1u-0q;leo982EU( zD`E}ZdNF;qM?Vv-W~$_F>Ys}Q-fK{}GwShY^d5EA+4UP?d{k3D*btsF`j5*6z+`29 zBAo|sesx^8aWmzg4T_-Ao$pQ3DIbOy>=@L zy^5n$>$2_NNGtm;pHov+r5k5q{yBwJ5U+@Tyui3RdsxB!y>MF9^Ih%akUr20B(D7x z1g}#(+WIZu^Dp*YT2Pz=o+Z&Z?9t?XE8G~lqwt7ESH1fgalkT;7-4T7``2MBNCEfU z*vZ$CrpU#wsIkDef<`9JbGgK8bs*4u{r&L-t%o#ZeCKcTwAH(bA!iJu_z#t{L~K&W zN8V;-4~^Dz?jG69v{ShG&Q5^2Ek>7J>tgiGX>dcGh(o7CioqBNBeLCKhj6WPMVFjU z^7x);)n=D_i?DPo=X0nn#9k<;BI;Bu8V5nB0fB>x`fLP9|De;ihf;+RIjTwS+8TAu zU1#n{2gX7@vdne6MQh)F0iDns8T8*%)Rjx+#@_+~V~kMf z*oRuq%ULDNC;|tD?ri2_%3V{cfs5X}4I-f+5%a!t`=N_HTfX`YN#m~Rhjme5`6)-F zm?hdE8h%9bGdL^3_Vtq)zvK6|Z7E(mX#rm0Si3lv>vjX%GA)FV=_jQzJegwdci&yh zJGDTLZ&CE1mvU4K*2a+IN}cZ+1~;8iu>Iti5wzA>5@dA7{Yf*;VIyM;K;x?(E*2$F zi7sN;mB>vRYH4)5NfdeR$n^%`azKMmYn{0dEWD?b^3{fV7tBy@|J?rmC&}7dW#ZOC_;=*J_st`^yW? zcs;XGP|^IhIityljOJ5egPuqko>VnkU5t*kc5=AkYwiyNd@RMI?hB zosm_8Jg?2mD@JE30A)=)5c;0#b1}%~3Wa;PDU+!Y^P2WVSkGbdx_UsF6;6DZ0e94q z3v5>{8zzj8ThzQg|GHdKe%Vud8lz``;*FhGt|C2qmYiPnEX}mNnlwhb$K|P)ORyx_ zlUi6pwcBGbLSdqk!2qy&ixc*K6!6MQgITEOI_%0c@lPDwl?eFdpOgAEdp#E--~PM; zzV$oIWAI{_i~%Y_uHn3Uy?8K&JYz})^9pd9Tld&E*c2^Ze;9|(g^l`v^}h% zMdH?fmz)Fl9YfAgzWmnzHW_A0fXfX4r#bS>7g2Yc$s78_3ddJ>Qj?I-r^;qI?Uke< zT4Mt7+*sH5H2Ly(6JkK*Z{qZV6RpK}VA>ESefHP;5<9I$41+o|c^$j~%*;%GJuW2c zMSuRi4k?jj*sJYiB1+g4s8nq{G|t5kjDsg6vyw*4xDZ5)N`QjCRkODb>hgO5~Crlx5dJ`=wWBb!#Qb%(2FS*TDt^-G%>|2px4y&SH zZ42i%n%0wf9$E>Rk8j`GlmB*c&yIngIXA z)(StAw1svKy#IRYL9&;r{U0a?0XRqt5P|K!YNyA^j97yjC;y{WuPdK|H=l!(+lmuf9$_kjyh$78Ii>sW>hkxaIK?69Pb#@(U#|S`Ukm_SBERpRoveb zJeTFRx3kqn%ZD63fi1EqtEo2Q2}DWTrzhf`J+-^zT-@LzJQ#Htqvyb^?}UmkaLPFT zrj!yeS`LDYeh6gT{7=>k0t!e--l z0VQg1;rngoKE#UL1LH8je?=E2Pyb=tgCZ_m7Wu@680fAVW#mtABo(M7DC_D$Sel6XT`%0 zftd>MDqsR2ThBUz=d|IxLB!e=yo9@HZ{YKU(kF?Vh@QqteB+m--#`QQ)CO~(y7B_Q z4;X|9KHvXd&b8*_q|Aj!&a6s1G_mXkzjMLtnvf?E6Wmj_sT^Z~r)XxR zW7I^7zLv|N`E@GW+l28YweNF3Dm(&Kf3Xh+XkJq<`*O~G4tI9nJOt-kK+T|_)6RFq zTrjmlQ&W=be($5!+wh=ZA%)4Q0Fz~W!;hh?2P}g4fE5J{` zm-q1~%p|T@Wm9^Fjlwe4li6e8%?PJXNChyzNpgsM6 zComWe^Bt@WG12XDNOOz*%jB;{C}Xe zMFeIGPv8*U5a&#v;S4Q24wl}h-yW|~0d%&ORBKdLKMYZqZkf`ywH`m^>i;{jCq}`* zl#3!7H12~i#2S^Jdp0<8!$TLxysm!4fv@+@R0K2cC83P#NYWUHRlqQlAeW_Wt{WU? zfU7&1bFxpT!9Fm6Tpb_3A=dLX_$)h(ZuUfgy5a8AY1BWQ;g##A1Xi-A%`4pJ@+*i7@?E1n zE-Q9~w)j{Oe9%-Ooez7(=^d>pseOM@j>(|LWK4H>R2V|2u@)C4P96uM@0JN0f~#I+ z0uhBnYpW$!G|bxgDDz(dTsTIo4w3WYQ=>tIPV`zy@J_EvC+3okf_YC?;$-Jxfn@(A zajz5hVRBRw?nW*GVYl^=`<~LQHr@KAjLr>P$-f$@%n2b!s|k;aHaRQCM5gvKz)e{1yFe<*v)@Op|Sf=x6RTX=xEgTeoW#6<2~AML0p?1+XseTfNoM z3tsbSH9`*)DOKY=za8@wi zVwu-FIS_PD<7Cco0sDt3-{M0vHdrdjo;1EnI}c0}cSU@ohGFHUp#1-z^R>vpX@U?4 zoWJF8Hzy2$o0uS18r}w7mo=L-9zdoo*xxu7$193nYtz2d1%>dRl#|2;ZHnM^=ISD~w8q=r((5a5vjdxc!XjU~n55rxGuww`-A2_4{S zwBkgkd>-v`(yk@m^USgbPa;%U!$$)44l4eq6aZngVYJ0OMYMv2+5ScHi(K)!0&#@o zbXI2OJz5+YK6)`N)(VJBTJ7z!*p9A*D(yxJNRW$P_uHWWT^df`1-9bmHNoy#k}IHC zWiiIG)4H6pznK4AV()^v!_s%PG;`RlVlWF%visxy7JXOudQ5~uo<(XWJKFL8j8s4^ z_?5wy4VQj%dgDuiM3N>|%rn>CMOb8deQ%Kh7aUHwAf3Svenp3I5p}_-h~T4Q44{t#fN z(b@ak^CSW!u;qiYl26K9i}wyk>@HnXPR*R(Kbjwq4j8lFQO`(L?Wqf0)w-GDvsa9r zv@ebT3vGo(PKb%)pUqIl+K88p+D}6D7{qd4C(Z|W_#zP?zXT%YaL`y@=2Py!`JSO3 z|GNQmibQRNFfRVh?}#?{bQ>cW05glsw8%IBkwNq`hL=(V2ztjgoA@Q`ajc%c5lRz3 zBEc!T3j6v9|8Hti1bXj34$c4Lz61d!0F+EzMHljJJ}GbLFcCiQ;G9XSp6Kp;H`P;1 zAu*F_xnn%lHrv%F9UHwBTbpiMXs$OiSFl?QY)v{a8cDGfVDo~)9Tkly*f)P z7Yi77r1WDeT*SkG4k9UL`?yQreRK=_Cs%m9COzj-+?fyKAiUs^DRkQA)3u6U)2Wa!AkEtw0_ za69&uynGTRM9qt6{&#S;K(D)0?I$?_co&7@c*ZluYdO?SQ2Jun6VP_PMT-XI`b4aU z>3liFl7h* zdrc{KbQUFVXgA`Q(%m`%OFP8XGjHT+G=7aBA+ zMCZl_Mw+{vjhZF0d0=YUJ5U}X0yE3X;re{S%&+AR9H$KE_)ufOLu*4lB=+Kx!bdwJ zC)#;u9CLaKZK(gV>J>CO)EPiBBqh>ovmB>;&EgNJJ+n<-m zGaf7P!OB@x`3?#a6?~tKtK{)QI~(My{OeQ#ivFM11!J&HfKyj6!nDHB1!Ad3ZTIZ> z^(`6)SxWbiska<6hWQd!?}f96(a~X#^#7Rc2S~6qZ~=HH(^JT1n6#(xcz^X2N&ql2-N2e>2cflNi_b06q)mtrvv1U!PdN%J_6!(@{{ zcAI#o02=KDEb2*0rlZ~F!9b<<*{^TD1jmB!X9@b*7*pI^L`P6?lxaViX4A zuM1Lk4NNSI9AQu0x$Wt@p34XkA+`qAK2p}%%(4r9EuzgZIZsllbA7UkG1_^P(_Vbsl^mGih>1}Hiw_gCsz47Lu7{_@TstwsWkQE| z{0P~?+XbF1M%|is{qD?Ss2#*Z*xg^&?v&zS!5DjvHu-6aA3hqW8m19#1ScOTZoLF-QZP-PbnCLf$VuKdvIr{{?Z& zhhaoLN4yo91m#wy;VT8*Jx18KrGLI#f3&1lPF`Fu$xNH3d!Gc>9weO&gI+P6gNyW& zkqtYBkXjh-mtZtWs@B8#QOG3#98LMvhCCXhQt1zTu*k6u^L#img-wpH6Wn(>_T0wR zi4SfeBgS9ZWt zC!1!Mo|tXYJXYp1oh)!@cKM)e{Y{IJHdHFZ^VmQ~D(1zR?A%Dmm;7{3&tH>}k%K&k zzIxw6iK1w?^=EcwLsDyjRl`x%%7e?pjjGGUhVOooyI7w+ot)n*gFhdyY@F)kw7e)U zdWw_rCh(0PHt2f9y!N~UF#XjO|Lw`6+_H{%lsFzJBGD8pdUoueFOsWTvrH#Ih};R) ze`LrZKWcK5pk3_bp5U>fDoYlGi{-&c=^UUw_2zcl)2d-jVO9=0KT+MkuO{8+5K zCv3Wvu4teq!OlcXYHY=IHX>~kCowF5eKi+NHUcR^W z%b8*J)<9Rgxmu8g$7+Toxj12)IWsF}s&_5zsrSPwc~se{OS=68!L9NIe{`FklU}|m zUyPFLqn`VZ3@|g#8TK0FIc|^2pW8BVEx}8_4um-hzs@pAU(}K4(}KHWGLB?|Z69b+7E-$#JG@8s7!`x!%$*sVVaxa*k8gKKPo( zb1TztFQA&`_uOJ`KZLsR7c}l*aFsb{jnfO4u690@Sy&IWOJ0=Pv7+%>3ct#enY|CJ zs{H?XhChg9>T4O&F<|N_ij;PH$SRzdMCi8rhi9jX?NJN68sVCP6H}qQX-{J+e=cc)^nkk})`Sm0o~SsvA76f5p8UCJ zUpX(bqL6aQsuoiTtHZJR92V+xRK#OkYqujTR7d)_-qFKSM6QYT&g`oTE=qh0GbF80 zPjqo|EdMf;Pwi_^?OL6c?Bn0_5zL8k0_`>pamf=zfo6ETFv5&grq=R}YiHkv#nr2< zY}RQqUXy%f$ov6_COWqo2R;oF%M`K^=dmYF5yC6_x`GNHiKf`K7FhEYRva4cw4zno zy?CQ17tItwQQDw`dklZj^*JcW|Fx{%ueYovrL1gsIf-CFucJE#V&Xnz-!2`_9+K6> z{GhnY$+G#B6V8~6rSf7LaQEwbaIp@k;Ka&zU!3=+&>8vwW1FLQw&!A^wPKjIi*OFR zuJ*z_*h{`jN1+hE!KurDU;Rf<*9U{NMRY~-B1Z<#K9Ao$nW_~h2PPG_frH}0qZ##j zaYy66@)VwVeTijaIy6z zlvi<(QJ0KE?VsfCnX7}&lPk6uzf!i`!V$8g<+GmEB^0X!uHD2$(BfwR=^)DsqWjma zy&qZ6;zE=m+G!H4gPPzq&J;vExAXo?LVLIIB|gkG%Wy}QuEq-k?P{?^w%74 zUlX-DEus)&TMQ$!INZ+b>64uISTKMMu%~#bB3T0|#+2#ijA-B0w};^iD-mO;Ut9ma z=>GLi>YrJd4#zx-pBqrDpIbbMe&wYwJ25uBce{EH8k!`!>K{;k;*li!sT%S~g0`vl zG4iMCH2uB*VhI!_!v#!#0_4I!SLBoj;pv5T6mH1K?8B&5QI0;`{@;zcr*x1#bs4sw zVS@REU(jiyzj^xGPzkR^1n?9&eQ5@wGf1Ttge-|#)?m6!1W|K>R&RS=NQtGU(4)23 zT8DGBMX%PwN$nl?l^`{5+(J-Nh+Yf@Hlm}h5doYP=m^dTr+5HgIgh&q`>JZO$5>}B z`r2(=(`a0Rw{NTAEyi2M1{_MyF_(|TdA6e{%#?@VigWuzo7s-Z49rgZ6rhJ_<$z-H zl-@YR%Xn?mb=pdBfk2jFvS2dqroaPw=C~Uleuc(qT^B#2)I#uKvia>jNeZmU z@MzF}+kZD&OWX!2M<0c$yMbfU>|3cVd|l z>x}9fSerNI(z1WUXTlnENPGCh66LNh#UT<5og82E^B65DSwm-2oZafXbXfQyEDa1D zlD0**he?4zFD}5bvC4h(Zm`o}ebS-C6uxw+ge7Lu1)v?zadhjZ)bY7HUd0k}a=?`} zce*bHzp~jq3msXm3Y&7<=PCF3P+NG?`R=+Tvm|~4_OUQ{MIYE@=^s+8n_S7o+>|o% z6e(=3m4(^v2Mv_q{WWmU3rHg~BX`)OpNrS|5$ZVl$^P+TJY@7aTz9|9R5R3hC9Lst zs00C+e}X=h__m*6Jx2OsfRc5v>8D|(1A58;5B{}rnPr-ipDkrkK|Ex0M>e^NbjLkA z!Q1EEJjdA~?vMT6EuB>O&J0V69g&|m&b{8`RkDtnLG2QvHN>cv=DXI7!Ef{r!?;Tp zOS{^c#NES~p`E|C+iw?6J1YhE7n-${>A7Cp03t_JrhWM8NQ&%nMK$ox0Zfl3h>G5n z)V|a+{>iIUKkfzd3`d(EM%Xp$V)X{cU!Hbc;_f!tt3dU#CT)jp)a}5f7NHcW{$%zhOe5yJophvS6J7 zJb+nF0mrF!LN`BPT4Irx#>0<(~dTn>dsmxRa6!iYDkMXxrCqd=25yzKCKD~zp z%zJGqrEZJ3^Ya?)X_lZAu8GL~q=>%Iy#0X)x{rbNN$FsmvF=0k5x8k)d4Z2Qa?Rz% zK{SF>*s3qB&khrEC%H*f0FlF zd#un-svD(=4gA=CsBjuZ`%Of{|6ZMpo+3wxvWza>tML>39Pi&!UtVivUQ(u7_huN*TbFVQ$MrcFefZ=$Xaap0yP+pYkogq$`_k8!dhMlA1fI*d8e^zx+qr&GYuXRSFMZW+fsyCA1 zQBU>-kTp$YeDCSm#~jf&;BFGacJ`v8z{=EJjA_i6${3fLBZW&zsAAy`$mzWy@LNs{ zcHNK~uAAv@TL`Z_(Nu;&W%F)xfgyWOiUzG2xHGL0@3rGpK*@3VXVggLx4o8dnjoRW zd$2%owo;8#t@Et0R`Jj5Q|_}%?FNPZ$rA;h7~WlVGLZjjs8XdNe6d@7+4(E4{_-N_ zDU5gydpPZljqb~J-j7L$EF4R-OU=viwgX8x@37Zc6#grP?&t>}Z$$KqEp{jB|4syx`uAB5#+^>k|I-;qtvR$v$TD3>Kst+tN%6*lV=&O+71j87#s)62FL0P4ej39M3qm$jWp- zznHMM)8|o72-m`UxPUr)794lIFSuZ{u#?5#4ZZ6mUaYTriUT5m&Ee z64dPSEWsY@!RT&N?d2_CcyHz27QVLW?Lb|%J8#w--l-0GpaOM|E4*~*LaGdP0dm90 zVb*mKQf2G*7j^G>^=ViImsS&3xnI=f5%Ry+{K5N*36(C7ULlkbPyegls4LG9d}d0X zM6Ml}RXfZ>gF^VA`htArHBb5u^W8~}8Jf-q|DN4XdI`;L<4&D;T& zP{d5R8EkEv9CVnc0{Petdm})7Sm69Dm(SafMBr9jEknJhuMzId*GvE6hn3fORaw{d z#uAHD$W1@VyN9=7XDAJaK%0l_U#gA>WIxPf9qAzR;m#W;vL&Cj1wTh~S@&DNpljvk zO=a+!AD7pE2=ATO`+xX4%dn{4uI&$?U;qQ6fFLCbDBax#9fEX7Go(n4#0F71q@|Va zX6SB^ZibSEA&0Kv-Tv?AexLh!j^lm5?L8mnn0@SPu4}FH{H?W|Jgq z&jtS|p9l+&yai8rkv$(mxI44z7xv^J zvTDI|&~~bacEAVBd~L&Y%BJ+Xf#4KY=N`R@`O zN8^ewkFfsiZ>8?46)PA`g||OcD^6qm8=A~KP*VUJf)KBYWsEH4!L%(;zjd>3>FC>i z16RX|+p{&H{nNEkV&9c-pB}R|J$%_@XdvdI!h35}>k4C35%Bj2zT)K+H%{1fINuWT zvCt3vXN_-pq6}}!PgFk_aXBgqcy6RYGPG4Fo|0^}L`i`O&5$@(r4{xE=C)q7qR|Av zVu;qHnQ8P#hT%)rfx)=mL-W)(`nS#kcAtAt3)m^Gs~UhBsBL9r_NU4;%*d`iLX z68d)P1C2fD7a`-Yh1dL3arW0Tr6Tb6T;=}O?}XHu?oSA5L!=W**jq}_?jA}gQA4G5~KQesb&eAL!1N8F}S`EKTcb!FuXuswI>pNF-@}_i%2meucpQj|{{h4+qn#@G@0mZq8fubVLGa5`ULPMhNWh(2r z-LEzWr7|u37y1r;qXTJ#k!wcTqq!b*j@U%+Yle{Q{J+!mv9yVSxgXC`5ba=yo6V|< zVo|0Ho#@O0=So?V$RQ>CYzjioNeacHvsgJzP0T8u>v%FL>Kb>y>7(vGI99pK*K}5Z zQX9OuxiGx>?(BWs)EOh+#=<6+4V=wiK3Z975~!>9kC8bp1`xg*$=C|a7Y|lViBV~# zRASv~aS_>eM=ijZ7qU#;^qc&_z3_LrD;#$>G-g<6?g%-c9~oY+8%`}x6n8C2yg@Zi zc7S%07Rlu|r;_xf>Jd+EcPdAuyP4<9xCaoNx#T3+weF)jtlL+I%_WC0 zj?VsdEGZOBaa?+$eJ;Ha5>DV!*9*(C+u3i)63?KXrnTy`E<*$Hgj8ZnDZroC47z^V zz}0;JKxY*R<3Q>m+=MlOFuzR z2B3t*V9oWr;s0co6GJQ9q$1j#P%`qmVEzTQ4S*rWhGS*m6f@r0)9<>j0;99(YyAKTz-B)3MlOL+ zFynu0;|Zs8)h>E(B9Gr{SFZN?wrA#k3zSbQ@z;J=%jY|TFC98uhS&!)-LjV-=sPRy zc(8q)?nHgT6{Jqd+GJL{-@)lbVPRoRlaVHZORg4<_2tc*9LnZ5kE3c$>pW+Y#VJjF zmEaVJG&=ykWYZ^mC@IX=P2+jNXZNXX>+8ix>9XB|*R>6A;kR>VGBfUkVb$$9>fx^} z7B za?IYujTmOd@iFVL+vW}`qV9cdCHU9wk`sEm$P4hMx$8C7HZD@;I$C@16Rga9nCO2m z=PKujo`+oNd;X7g|D168w zSLLMwo5sts5yoDj1pKdzw=Ouni|(9>R6Ow1QOy?FfjY}+{I;1xNBjQm)*%QJi+j$` z0>nMF?ee-oTQTJnR}Eet2REsWzq?w?2hOiZO%rF9c7z-C-@b}+h9J0b8=nT1UgxR@ z+AwcLTi{Q9LZ5APct1LCey8e5v$)Qky~?kfqW2&XqxDGGW!H&4C;6qJ7-FH2vYq)$ z$e5MZ{bq#an9<~?{e%KGc^Y)b&W)RA7=S48a4@>Z4BrV?OI+g(BG1c+oi_e%E*(IZ zm}RQHo+=VwhNjcqlCm5WmEBa4K$$+xQHWh#mZ%iZ$xu=qKKS~fXO6Nx0mU&L?q>)%Z#%*aowcLx%d$mzGrhp8T5g z`L)l_&CM65{xkI6Vsl?<`r=-|$$l0$O^Ti-HQx8WPquq2<8>}^@=lM^`3yBIWA^Rg zTm|A}S)7kQYc=d$CWpAsT?k=BEeaSe6LAvw#rYleMz$=0;awLG$EyJ+siUjGkLCEYo?GJr|&|`2u#QQSjH&=IBZISBk)9=uw^yDKB zDwh9Vo?PneZ5eT9zc=`8H7k7YHE%3v;EplV$jomK%ymUXwvPioJ-z>iLL}modMl~T zXbJ2EuMk#u-uH3(esT3A5lR~19-$d&IksN>%STzHdErKN_T}!U^=1<&d}>3q-J?6!G9-y(&we6Q2uJx>VSOrGtmdwe{ES=fqf-`B zFz%<8-;u4hQbaJ z@^)zK0WxA+vSt*3Q0&`M*9sIvh^tYS6xdh@msFRnMYAbPC25&*XK`mQi$2b4 zWxKRr@WI*L%wB%0)ul}BbZzbM(n4LcjURi8G_*Fo;z>P2ejhOMwy_Q8Ao*#sZhIG8 zWA+`qmM1VfsG4*W6|n}_YL3YMDG*g%{#|r+ku`I(z_xAkEr{T@Iz4ZRVhOJx#PxkB zg&TE;vftlh#nyYZ3sNA7J^uN&-@K3n)RSm)YH#A#QE*M|Zg~{{MC{lUt!Y0KQ*?+V!q;-F<(X}uBt1Q-5a#&G&OGpa(<^cWZ`u+d^p$ZaWuW&xP_WH2Kv5AD8u*5m^B(VEWb>S1?;MNIL9wi zzNjj1Yy+F7FbEl@)bMJu{o%Xs|9QsByl-}Nqvt9m0+048r-t0kCHrFQ`rRzgw3q4h8tnUm1Mu&ek?sSGZ*Nt@q z^3i2L|3^U9*=w0UJhS1%e4(};*Iq7G*Zx7}G3e@TfHR!+oBI>_J!&cArTxRIrQa^) zuJow+>)9Jt=zruHIRd=mZ0ORZGoHwR*>Ty?5uKG`FVA1Oxm!AFfLlJUXwUUE{}82k z+GwU$V~Ie&>&>yV%%MwldD?eh#&=;)r5=412`uo8)X%Gr2RkpfXoNd$4C20sHdhHO zp@Xg%hVHc+H+DhNKdCZlG%-KV&)4J4fnA5q~xJ2Z1=9Tw9w$z9b!1v1BX% z-H-bT90F`ilBpi^u4k{VtZ!=84V?VPivdQni|*~!KA;*8x)d{I(uCPM+$JNuKPF|m z?B_&X<~6q!HIXW7+iO)fPXcLrl*QhD`gI`rvNB(s=*H8 zO_cSFrGqg=sccNokQ@}{BufPTN`H?>#~b_p{c?r3;kth?0b(sd^UPg zE@R;Cov>b#83N-Wt+(YFP0JhRB)HX5#5$G-9;&o(KDKDTke1T!Mb2tI0>GWwWM-XL z$WWm^JDm~du9jIx&)qT23>QGx(#`1N?d;3?T zYyD*AxNHV`yS;g zR~!GmG?H=Cu`e+hQj#WnTU&Irc_@|O2LaQlM8B?hY6{Dvt`#7LX3BhIC-hGhmd$H! z?gzdaXS9Dc^MYqIV{;Sig`%NTT&d4e<=>SVVAUQHOdnaC7i~1pV4a>DVmeuL!VH0P z`xl~Hfk7VFZfNxQYP6$!MuppLDbHcqo!qLB=iz;fRz`Z^L>8zCLK>h%{&us!WvY`H zb;I|p6(oKJ65zM5jqndOpxtcvwBH6cxQm&tfDciL6);xU-~Zs=UT4ZNF?f>{$}WFpX7Kc^Em|^Tm^9b)p*K66P5u@3m=jqImt3D(xA(o3E;1 z8a$S1bB$|_Wa|m{WcjHE(y zIPW}5IFRI3WyWyU+2rE$4Ig6Bpw(J^Tg>#iT`-@AhU(33Xj zk_@Nu2pHk4a%7x$57-!Eej6uv^x!FR!V1r*Z{Kv*iI+~JhCk@|DUVimx?Wz)Xx<1A z4+ZFSYrRnJ4>f@i7xSJZwEw{qh4bCnBvOvgX)rj{fx`Q8ACW-xUucluG1fVZhM9Vk z3((@kKm5o#>6Jp0ni$&!sU=rWPucJJnaFi_2#8%g93n}bxl=`N2RFH@JE9d5Pn%Cr z1o(O zPUIbnK636-D$LZL<4A6ILB+%Nux+M=RtTv_@@YPjK@#6(9@`{@Wj-@XuumX7&)ggZ zoC^2#of7d%ETn{txHxp#48YlI7T?AvpW}083C@muC-_1DPYcNV>eQ7JLjuutNH(Vr z#D6fdQvRLH0~b^{dEpP&%q`6O4$q9L6Qe_#Ynw|Na~m{^U%d=in&&6NT4B4&@Z0Uta9`s<^0F{E{u))zUjx z{pGIzUgI(KxBR#{DLS#z{nH=(cQ|bLIX}E(Ok*t_pr!rE`v1AU78o+m{Goy3x%Um` z`sege4w=kyQZWS}SQ|G|k6f{asFO&SHC2~Mxvbi?)PQK1KI!09z)T8PC-x!y_x!k-mHXyw@m=yoggHpU>T_kB7%yWN8#Ej{y2uCn_%5?S5ari%y zz??uI%KIy}1r9zXvvfjZLUFGt=Z76p>IEkb2j?|+zMwyO_CDNp%G{CXL%?5`I+aKl#+a9sLtD+xYxI z^H6s~71Xw*YQNN?bqL+Jc-HPdVc(Xek`NUBb`ldf-RcIH^-5d)iAv-L)#p>%23x37@EwY2#~ zrK{@(@*bEEvwQMoUY^eVZgZpYrcW!ydyG;(8hC+k8~7s2;I(d=W(G&a_zz=)_b^@b zU$63a>W}w?o+o|J@aZ95KVirDHzS$Bgs#}N$x03Agtk*wnPGj%n|s;qfZK?4;!(gz z9J%}WC1=?TL!gBhMP*?u(xVVek_TLun=??Tmaj}cV_$!k2*e+u3=Qqw`svWMq zOkf5jmBIGwOCd4RaWs96BF`ho2Q;T}Lwzc{7qO!-PSi2qdY6{kTMOnNvXzE*%wyU$ zv7Or@xrPYnQcdLrcX)tzaepNnYMnx{0}}o9iwT07!s7a+HixqfwcYsjl+#TO?n$%o zbNACF&Av{vWtz?!<$J;(sF}a@W;b+xPmTp2Schf_md$BuVfN1#!NlCo+UC%zRh!oQ zD~)tYkGz9CXcqlnF7)3RMP6e35A?m0>-cI!-K+8#{;&ZMr9@c6XaQkI#<^7L8(1Su zXeB-iib6pB7^IJn+m@OFM{b=&OiWT5#7UJUpu*3lE5K#I^u*&W-$QDFf5Qa1>##aSw!ZjJWzepVKvTsDek6x;OA4vSd> z4m)>>@Kev$>Ku__RF0z72ciP?*HxXK2OZ*02-fu`FjMwS3I3Lr*yz=lU3&2(e`sg% z1owr){0WLBSf?|gJauwvrUBPgR1^|5V;QuY?2YBD1< z>5Ws#c=THSj+942@i_0h-AKyq z9CA)|n7%{*+i!1gtZUXP6-TfB25R4UikUN37k6lIGKfWPoIcQ%Q%Q(Mcu@yCmX}A} zFUL@)Hr3I`N01@pNWcd!9pgv9v=_c>Mg5-cWYq0UU=%wpHCMm{w5?3oO#v&2C*o_* z*?UYs?0M<=A*D%7Om>$#+^`<=VYKtaEJ8cq?`TvwP+c`YBt8>qKY5UPwh}0@Q{6&x zaMtpD_VyW$`1Vr@Dk=y5B7KuGYhq#jM&{zW$dg@4mpYdY5^P3`s(s!-YKbr|V}rT$ zi>*&AgSAAI!=sF?;3T+I(LDe;`y=HC<+bA35N}uSwoyONz1xFw-`^5PV@V1rYG=Sk zZ$M_}&U@yuJFLFpO1>5<NK;=Qb#gHmuTebs>gBrUlUXT>KmHeivK5n{#FU-#yoSrXWQnG>j35fHpKHyxl zJ9dSnnIx|GtbSj^Wu{YnUWGi2Gi~Defekk&C?Ub*$7=sWDUWoUu~I0@)I&yQv)zTh ze0{K+YFA1GR33EE)B?&7p1uC6c^Ar+CvSut?zv)-(}|pRrbFb%NGel6=;gnd7i~jZ zYXH8Mt%|gSC)qc7Fu*+lkBMgV>=}DPHFw1LaPghxO*hajU-JoJNr}svVC8ZU(*z1H1hE;;DNR zC9XO?3igJn?&}Swp8Y2@Qw&H$i@DqTYkdkj&qkd-DuY2>nMYiH>>U{VZ7o1W=^(0{ z*6l~~rRRLO+&JE);m@yoiA2!HT+hqCJVi@Bg(}dWA(C`Bv4$Rv))%p?N?dj|6aQkg z=Pcxobm~r@k%X?_`&?RGw7^C4o!Ky^g`7*L>i;sUKLJX{Jx+BmPNaaFHvL zlz5NTxA4B#YlGYxp@%daU}Fo^6Krf`fVXUNH*OXfV`=S(S*9|0?BgXjC))Ez} zL($vi$-0=dpXFs!_Qp>!w|QMiQD2|7I^KwGF*s<o3LG4;F+7Uba8Iu-GXhLPU`* zk;(4OHm>g8p6X(n9`WZuIqd$iXWe4CunJA$%(E!JhVES}jO z+5=yZWfR3XV1uGy`QUGXOJ}^Q=K7j$wsbRXLs^d>QWmI)THa4ylLi$!9bT+%HA!2X z6yQ$en(YwLZ0vRDAZZsF^P`nGS=W45EVsNI-t|}BT0lNQwoO|rsD0u3X@S?4^7y*r za?DYkJ|EyYB{TQpeR=745ZW?cMh*~#x0cX; zKN?f3o7*pG&hC>ti_yIr8>VK zmPmil`auw>nEq794-C)WgK38m4{iqKqeyK^+z?58I^P0epJeGVAzQ@bPCHw07mRrVAv^5fIkh3CwPgIZ_Ba}0!5d2@hzy-&WXjTH%t_4 zx(d$+q+Xk_A5AWJFsm2F_SnrlZ38=1Nib;N@T@-`M z_ybWOR+JF2Z6M%`i-l$TUpN1{=86BF)0w#4D^<6i>T+G?$-Q~Vj>#_sS9nq}=F*U5 zfR!}ZZfi?1b)H#o!%^A>Z&>&i`HUq#Xf{`{o>TaK{Yq`|4`Sq!56wD0$g27DxZY!$ zKU0OJI+$#!3a38pe!R1^^ll~plI#I6I=Jhc$k!EqJFOD3t(a!ZwEC(rJ0!<>@dcxm zsM)JR_lJgSWPc2_&%^Ii?fyO(jBWp{#I9hVrIk~(+h3cdVh^QHHh)b^4}Atp;R=S^ z6e#aHF*8EoFY|1h{W0V$xRE}H9QG60`V&d7@uS(L*4DO~%`F`W;hn|{V$Byo5Z(NP zhJyKAGgI4+7s}G2k0Gi4M5TMzWzNoAq2PR$POKl>O$jC`-e?QHEoC^_Cd(k)%Z zLA^jOa=3gdhn(BSqw!q1h->-^1S%WXAEAxLX+cu_R4U*h-^^c8>2KLW=++pstDxWH z%t;4{&)F5bczs?I=I#D-cF#H5;$qI|Z{Pi)!?^O@xH+h{SxR8?gm0i7-@)e(x zvj|jCU@Y<=YP({VhUF=!qWutecz(GZg=y93&wy2u?}rDI>A`R*JDtP{3Kvukd4I2` zEbQ^wjIEce!k)PUA(lu*K~>ZXdMhfo-hTlk)E)f2_NSd&dm@Q24pCn5b9b0g<1;w} zb~ggLcZBV9k`?~R1{C62-%%2G42aBC@Vuo*2lq@&J5C0s=t$hmjYhkUH7oN^So zp5i`CCFInejcobd+p!pzs&rYvIFRBP>=O#q`xx7}N571)ZOaF$stjr0l|EPhXvi+6{H>pBvYO0LL~k|y<|A2i zBh4U?W2w$2W;K?*`5`?}ter>yuyN|x-f`d*v+AqjnC_VFw%cZXulPCWFm{zu5#H_I z`Q;<0*7?Tjp);>{bC=vs66EV=C4LROuOhx#oDbcYN0T$)*4e`OB0_3U`Yzuz2h867 zQQ$QvYKP6N81fed3x!9Q%KT~BG6va+yJ%13L{DsGj* z1nSetn+x}pEwRY{ss)c7QqmHipzqr_AHY=~YZ%4++zw%g9?O4B6UH8@>K%DwpOs|Q zP3&?Urzce~e6lF*q;i+c;-1~fgd+R7w&GcRiF|x0C4XI1apRWtO{+ZK?8Wf~K#)Ct z`lh*PtN2DFT>|l1hg?{k=K5lC655BVXh3YVLF!q5z>cu|>CF_ZlUF0`1S>yd|DWQo;?j+qh|;` zsLP_hh=>V!gHP+|eBbq>4qO{p{n@Db9v3Ike{MgR{qtQVD`A%5)_FvKeWb(87I5YS>s1*9bbh2-!KK6kpu|jWp$4e9Zz0-`Gt??*74P z*p5!vZ4Vc_7&|_B1r`15?mm0S{v^`xqv`K^;o^#8V3AVx=68RFWQ$mUP2Mnd?*fyy zeL?p5t4UwXpet*P#aoMf<{P*z1g#UTR24o*~tpfzT2aj|?u zWKw)yeSG`@En%=2B_xmZJG-}w&7!{IWk~q)=(tYz`XJr=2^(hL*mu;!@-IGSSE+ob zNdA_CZ)63ka?}eKc&sSb;i>qUu zWd1wVPHi8J{b7nH_}|n98o~gI)BlNWXzblpsea*(owJ8k5SxrOywgmSfSJma3sUk=JIJDRMM_1+ig->?o^^_>hi zqan1XrG#YY^)*K^O@dmZc3&wK2?Qyjkr0|`kj*;Sto@2nf^-XC30I0LoAJ)?^n_C> zvtJ&-c_>7KhoHE(u;P3*uE8dA^eV?1{No}8Zf0I!t->sQlK`;X$$fyPwX66p%Ag>6w#5{}=ab6T^CF)ChvV`wpR% z6+%XPxbHHbx?}4FX(nA=9BxgMKy0rzMhEl4`YD-PuRPn7)2t z;ml-FYcdsfS0V?E@KN9&EU2SbKes`GXSz4PM zNum8e^pqdh4ABeawwX_UT=%@XC(z18Jk80bEZP49?*Q z6a6bULN(!Q3u|sZelI1jYZC{k67PkSGPPy#V+G`&U^xkM$~5MDIHza*SngeKyXQDW zQr-I&IKez$>{MM7b~*a3DP8mk*wkMJpUREGcLCW)Np<1^&x$iP`+4$~YHy~6K(B;E zCx)`FncU*d&075%8IlFBai-tyx!g0a~>3N1SDoUQaV2A*5Azz6bjWz?X;#r zgQBak0oC?~bhOtj&r9Vy5rk1G_}z00FQ$+8g0#?|eNbQ4tcytcgqWpupxO_^c$m#p z)p><7Bx^?!!Ygbqn)FE^a}cydpZ^Gc3gJsQm4{QblC^`OJ5hu)RSym%rt;~3pcl5_sh9c zG|x_i&F);?a*<)f(jj?FD3C@+cAY2i?8O8pP(U-ssH|OUu;MBGfP4m~03NoLRA(Y% zAyBB7v2bro3Pj*>nU~tu;lR|Rk42{JL2$sTl*`s-dv-Mi*nDnSv&~toRpsoSx)Yp+R!81p-^Cv-x+^h1gKXxoe6`VnYUU<*g(sOU9ONNWWG1A%9|It{ z!6HH94dGYHxXsotd%rX%S}zyhma?Es--$YNx#WohcA{x>cXh%Bh5+zYGmhKJJ%hN0vc~wKtEFdVRxHHmgV<2>!x?ehn8o16xC^zR0q+5sR&a)Zh0Gz8M|d)^zUD zhcq0KzND1Q;MH!JFgy51pOp8U-q8*Zloxx+LTaZppfpcnZGa~=iECh(Gm0SpEQ9q+hRNij)aY_B?O4%d*@rfHqMm>Sr$|`R6`%cTyCS3F*aBdTy${NE(Dk4L zoQxbV3?NKb-RKbYgyHj}LjFRoT233A!q=X8b7K9g3)6S8G*&naL>qAI)=>xLH=^z* zH6+oST-Muj?qVMmudYIdhg`Ah3n*HY<;rKB>rjoL z83r!yPHJAy80wolV^5=9|Fmr1Xdgcs4qsbChB+YB%1qg^+0Tyq;(EuG%+knKxpq5iT(JBXNg04GbJ@y zrz1%=IHNYX)>YyCG@C4W$%L|kJqGJ56hJaA?WltxYaswvH(*}7MT6sYtt&t?y_;-J8(!WqIei^SGe6xSM zJHr0}NdpJax|@77z)5`Z(&D0y>(PdnYfVnCIotOFdoH|gjK0vzxQCWXnI1WAf zU1N*dI=w8e3{p!+&n#?TvGCn(J{L!YPZB)!dw;C+O9fh)(aSgTp{JI6Yyboz?voQy za%4PK=~v709aQSsdR6ET9X&dQ8$13)X3D|?0d-C0nio@aAIAvBwc5C$n-3C>dzLNw zdeEgO=QHnwS-Y3p2%op&HDP2M9w2v$>svG2w{o*rHCD^T=Ge>)=5fTY+fKzUWzW^O zzidBvE2Pl*!O@{lcx0)ST2oMa8JD-hxexp<2j-|6a}R;efM2r?T(kKPzv;TpK5zvd z0_RpUB#{1gyo!$s5ui5_jf#2gLrm9uc7dDTz;YrXIL!P|no2b{k7e~$zOvk?SZhPs za;oR6#1%o!_{1lyVfv&Ejkw?O&*bg{;R~KX>u_kON~d^o0K=VD&hi``e~$!*E?OcK%ad6(@L~d9I}`6D(J? z=9V^y-dkFJt$0r1%pt35JY=aYL;1I+q;eF?%{(f}ZZ%!r!GBNSqzt7^X{#Bu9s^u2 z(M-ozG%xw@VY*_*(u#?vPgB3T6Q5=N@F!i*pIk0|N3rf3TO1 zpL2_Qa$zawO_NAapDP#!WoI;DJp9b_am6u5?2W9_D7@K-wu3~zqR%`_(RYo*Ekk&Q zZ*&O7UTO1bUtEY(b+g|bdmesz)k$M7KOgN5+r(_QrS=Z6U$wzgCvOFh9n5?fCZx-< zrT>A5@t=JsV{WUHP}E>m$pfIQ%;A(7JIyF@T+(hO(7}^%N>fCJ5oA^>$24(s3%=71 zBD*Em802&utCw4~FsD_ey4hw^s5#XsrG6~UyP(U} zS7f<;s&ZAZWZcalzv0EUh28uo$K?a*K;J$JN}P=HoX0dPuzXB}0EwW3ZC?qei|74HG#Gk+0#ON8lTM@MEnbT=fbr~^0xeNM7 zRhcc_EVstQigF{HnY@!fw^K6o<`Z*gN`mYy0Ic$UG1Mi!5I zNr{%sk`xC&Cq^nOl#PCxc~Hp~n9cgXw0z(%_WrK~nl_sN6hnn(tTNcXUcLsW=iou- zzUZCFT6k&cyJP>&SD(_6gmb@ZIK{?^FmJvm8b5Y989!IkG%_-yo*77P$WZ#CZ} z|A2g@h<)Zei`iVXns>n!erexjC48|Z!VEQM=vx1@OH}>ra?~)=u<#l3PVZ<*qKC@l zv$7qT^4HW_R!(YWd=;Ml$Sa$xf}2YIc@Sadl`xz6bdt}0vvZh4N#!`|njQ)a`CX&^ z`v491A3mWttFW{7Y|O188K7Qgn17Z8vdY$T?xk~rMXO)`alXHQGxsI$T<~DSej2j! zK0D%#(~@aD8*T0UA6KHc421#FBrovZy&0<&xiC%q)fkE7BD$CgXQh`5{~ex`8cdDa zI`pC_F21|saQ%l@$}qUOJR%_*KL*mYltTih4VF}Qa09rK5%q)u!oVwfVG=Gh{5!lk z*5gsB^kVXK&#dsRFerYle;F;uD+DJUC3Cr$jD;$Qj6roZbmm5E*n{bX;wmn8s(NZ$ zS|m?5EmAL?gyT_@MYVOVcIQvu04<49#D63No4VEk)%8-hiYp6JuIt+Od3N{bgQMk86cqd$i>IJ&Df+2FqI<29T zr(q((-@aof#_$FXL+DWeT2JcOPT)m&^@NtXp87+RbZFH~D}Q2BT0XvZO@dh4Zr6vx zpf1AUv|JG4Gtv#gp~Fk#W}2juHgMG=h0@GuHR^Ou*#M;+jVcK(?BdsqJ+%5Uw|!QB z6BsY6{-UJ(J#?p1^dEX#i!n(DqaI2w=Fv{D69$BOoE=!$&8fJ(%be9|1$!g_=N_aM z=5y_plwzUdf2@%nm*UC*mmP)Ya}siJ18o@#hGqYawQZqd&`M->{ME5l)a~=5@_CZQ zY=B#Q4W^+v{X`r-VmnF1xt1S6`b*%OFoiUnMyJI5LHZz?4!n4Jm`fAOFTxN&Qy=;a}JaCIc2IfCYrl z|EVhUvtbYXe!(khJy%pUk2Xgl>`>jYO-vuv=MON;#vb`(G}jT=QXcw*ce*}fm&+g{ z2hl!YWeX#?4xSeetcW68?f|On=bcQ_ff{>!zcNFIGG6qZ!v?4r z`go?nA{bdoDQv(Ymjr443Pu6EKb1%6po&6+pY@CNid_lQ*q&J%qPPXcof}kM8b42O zz@56^G)`YwjI#*e8O~vb2#&UXHt1u*6La~jM*=x{5aIJ70gIk%Q6`FUOX;4ovB6{X zUFXkm7bCkr!2IkHT9i>k)?{bS$DIp{oHHD|f){-4GoI8kL`R|ZJM5x+7yO;}YF9gZ zH{0M7Zv=zw9OIr8st&UBOca|~9rN4y74bJ=G~E|y8MG^Oj6WcKco>c^)gf8-b1vj$ zv>{QW;$GPm`M#dVm6LOw1P2GMODk%5MwY^)x3~Zux%X!OCH4O6JqPa(t#O_wah~x6 z*^tGO%0tcHa^_b}dS?VTHQ;^)*ZVF+6)bxG6@edf|2wRikRc|`3%Uwsjq+w_n*id1{N2mqv664|61 z-hxF&pY_C4gQa+b%n)|kVnc>ubNUO5pR1O~H5*p;hqFNir;~=|Ac&8nyd&*$6)bdK zKUf&7>li7Z`RZTK5MR2Z3{u9*9#&ANc6#V^_3DB37~aX{O1M|d-;QqR=Y|c2UKc%w z`QN}A3`hH>(?+s#h>eQL-gV|YA$p=^)IZ1L93rXit)ErZZ#u*Gz@%@ zq*;0~Dp^&(%jCo{Qk#DKjauZUf&jjQ60TzrZdpi3?giir_B}DH`ZEjsZw>LI(OiL{ zV?S0iYNMSp_{zsaoFF>AVBv-a=Me;rm;Ew-A98?s&#s7_dX#h z>7yol7Xa(6qgwE|oZD*EMJ!J_xRXiPkH2O%)?v@sTujX}{6sl9P)mi{k4WQ~zT2|B zwB5b&yWO^Q4KB*QWgWPB41+u}*U_YY^lIjT*{cm+`yJuP-J@Hy_P$2hH$;|MkDUyX zY#Hg2tIDIcrQjM_a@^eXhgQl{A#5*?ik&C@`GE7Fa;#>Nj2+D=sKI63FKiB`;BZ8D zzD$N%wt-{a>9$c>p;j!iR@~#XkljRQ{??DgpejIMgO{@nOD2T3Cuyfo7oGj5f?eKq=?LNl#L$O|1df;O_A7<6YpkF^rDAu;Z>tKspvLyc zxc^9g$9e(}p`@An$%j8QS^H8r)_Ak)RKUd|wD)rJH%yahY1;f1{nmZ&Gma21st`U> zK_(E(Qc2ih{9A^H`0J9v(k`V27`z;ex zuE6`({C#+`6MGAL&-c9cBakIVzRFdJ=NBN7@zi{8!LlfM6~{x9p0&ZUwQbU4ma?q~m9w=iZvY%sj~`)9q&<(lx`g@(xSkwKNS zZoR;epq?&qjY#_)l1iu<1z>$#H>s?ddT9;&ZQT^W{(dc+`gaJ1j!(e7xPL612h*KPC=fLTerM z%=Fx&qr>SC4ShNJU!Ro23-G3%#%#lSjH1+|3DiOItg4k!`Jome5T-D5S}mq|ecYt? ztG~>A$rma0DPEo9(U8t%1qBClO^VaSd^B`PIX!X+r?*LvY zp;o#DttN+`(HFq%LhQ>b4A~wjMx_&xkR+lY3 ziyr&=On-dS0drc-0Qn{HZRsZtK6OjBg6l1zd$2j9#pxP~>2r$Qb%;>{e9D8l>OP4H zcW|)r;1*Hl8067v>~G<3D&%@!aos$(IN0 zE0KtX{SaMYk>44Y!P}?dG2O{&#f?|?hGSnukjeE9eW(2f!z-c!8kb)oo(ZqFUH{b` zBt*p7T|JfR6AhD23Pq*N-rbLf7tZ{gMQ@!=M|W9atJ_>7&OB71^GbMHs6hOt0toZKn+SD3GYt6ff;phOP6l{mUFRIFjjzr@2qjNvZ9s|wTagY`8YOhwZ>hPGq;no6!xEDGaT>Lez>tSsZ zO&P>BG0b~*>QMqrge=Sn!45mo-ewuUsD8^>L=;kjozOs^{I9N6z(6B{J5y-P@!T*# zPbZ}F-sg)WXuiEN}L zNCaGE4xhCi6_&;a3LE=6I&VBF8a$*Ey&B5Bx=$6UlSRp7H!giEC(wt^YA$GzX8jiJ z!-uT&Q2gu70ouUyVpAad~Xgz(k<(30PIQN`E4Rt>K&Z}8M}pWd(OEY>qC zyZB9ZA0pj;VGZ&D+B;6Paxl*agOZAW6FPnNe>(e!usyy{S%o8~lEPjCdPNN@ajAoD zUc8)c^ow9jf226WxPUjMKS%Zb>D5%{#x2fI6!eNmO|ibpS)!CHH2}cAyJVee`JlN6 zLR{1Bc(W-U3_aLo8$^lNb1P;%As6aW+Z#ME_Q!qN-$oP=MC|;Wmz_cKOMlR>EK}7WNCkYON^V5kyE${{eo;h+!hGYL<*8!qf zRzPZseK6f(ji05yn?LeAlQ4?eN zHe~x?_GaMswc(f}kdhC_;OaacB|SdZKNMNf5*S%gCEkx^qSv_&k`dp%E5Rh7V-C+a z?@}7h5hf53);fGb^lECVCC&M_bUGUz3aitC6sU<(aA`6YZSG$^hLo85222Zzh|!F3 z22T+#IXg&5$ht4MNmG}+UQU)neax^{x>bW<>ui)s6gIbbj5lJm4s> z(Te`2l=W4wG^i1EclM?z+}Sb-IWr?R0Vl_S_2zpDs@06{*bkTBH=FOP86h(vyn-}d zz}4NUmpk+2<2!Ty{iTl`W^Xrd61|H5cUI5ZBNY7FRYK!>J)MaizI$`|I|Hd#&7S> z_xpYPzQ5l;+hc#;-FwbG_nc=C#f!c*Q)0$|oCq)o3oqHWbz7W2=sf^Y^VuMH2wa+g z1YT176uc$95qjdJuk01V(uC`BDA-tSv?)XQUOavO!5`alKF?i49e?8eU=e{=$Smer zPni#No2%QA9}ZzA@ZW0r@ows5ZwV%n|6v|?%?JAb7)ldR$i_jobCK`LdE}cd*ALwp zeg`js{L(5c98FSUfZ#8a&oFa)_2g}DmM0LAO`zmmk82aZgY1;~sK<^97HLa7-2j_>F?`6*HF?YksHLBb_kKJ>l|3Cm7O zoF(8J;M*I@Qk#~iJ^n!r`)45A7izlhrQo12Xa4_Qwt<4Gz^l;*InPg0*IQhAnxa=a zI4|a1cy??EzK<}<@x<`g>z(Req|15MYdH`ncR4TagpD0KXj5o;rK8}I=c-9|&{r_^8XDhZHhxUfImX~jE@T#-#dS&sK zJ=`OTq}sGu#fH3dWfJHQJ`2;Q3L@Qjz#5&r8#^vdhnFqGPj8nem@GkrCQQl4 z^8noUx>)8sn^rn2Jy-^^ciOON_fi@;;P9!{`@*AXouYv?kL9-Fv*QkutH{D+2|~&n zR|wN6oaL3trkQoyf1h*UNO@b9Y*twEr^+;AmR?`*w+Llp5W=sn?>B3K5#V+!LyI}L|zg&_t?D6!h-n;f#wXxgvE<6B*z%{|0`_u zztft1A<5AocL23@z(n>z`f;DObgi+aj{e-YtNe@QPZ1Fh?QW+lCA(d4QdaU1T$0|^ z>>ge8B~{X!MY&8L(`p9DN!?u4l7IJ=m#06DSkf9`pOxu5YkN{=KMBGMA>Hyk52PrhyxF9+Ii+Pk zv8X8%XtyPBL6Si0kGYL(X2dc5sy^#}7uh&w_n3^g)Rp~q|6A%OM=7Y3w}Z$p#uf`i z_$Fmk8EY+hu;Y-r_xZO=ZF}H2-VHI@(Eo;k@XWg$DW0oD zKc6k+!v?KV?rzK&rP~h-{9#7L84SyP=v|#J-oNGAr3$;;sov6M4s8M*HlGK(&>w&t z5wYhV-+TwfJAOqz{#Bpfq3!HM^%~HTd-7rP_W8%xLJ`kL+GT_|DYD*3CZHd5Dudi} z@Z&E{P8-cv-*NTFms8a2^jdztf+uo=#2(#Y(b{`Z1vDm!mPt=if+*vg-vBd7)4i2e zvhsw*2RT@KZ6sYVr;9g@X5}`1;hJ@5p!h-nlOsJIb@zeeTQg?i!*;ypfy|0}SnXZq`!fR?F45 zZ9OoAJELd$@?Fb-~_|mH|-E#3RG(4rx&_`0wTqPJ$@!)&kB9( zYAa6RO|QUU7bmdZIID537t+}opS4BVKA-E%%|=j0qiEkG75p0yrj zULJ%0=&+*C&YQ#+0|)B%eixz})YFggca+j$M_WVo-#gL^7QV=32%nBGj6EiZlhTt6 zw_}!F3>Wv4+r0_c-@dl%jZOFX4w^VHy1o2`qt;W z`d(~J=5TusnA%DzlVF1#8h-h#rJ2ply_iLhDqi%#uU;pyK)L$uM6vuBk{pr;XBu1t zd8e3^HAKEENs7p1DZmjz;EIBdqY z?xjS?CqE(^fxC*X7G1ANq$k6V!sms`uui)@c65r&F$u4)g$Uu@?*Z`hg>a5E*==n; z%9K+Au&34QeafIR26^M(q9$sgH?rw8`P>Lbf<2Zg7V_ zmlmQe&Q3b#&&Ck{;7R~dC0o#t*_nfuCfO5TS=Rv_$>=GJmY#!gy2V;V&75mwEmOz0 ziuZ`bxSG*C_{Cb|u#>F+3VQtp%(A4wNa)92JQs0yO@SAW7WQs=WWDW}+03&-3 z*3Up4TBmRF?v@#PB{Y07Yjw_rSp!s*wa6hA~+ zaRM0k3by58BZb)8hQ^}L)yPiSE}@fGzOvw;3k_a+2XVa zABAK1Y8YC2VNmM5Md-t=E@;_!rwBMV*R81l{w{nx{M(> z#N`-yDe$uS{caTedfXhKb1U3ot~u7U^Bh!PXxah~nEY1LiD8N$LZIsd-#XLJHd;A(IqJxIk#*G&2;~JHCZBnAMZ2j3bg#Cz^$6tA#?b3-qzrSRc7g)1=G*xo& zImHw`)NauhOa#q}93eF%-I`xiP`mwb%ttyY7T)#q^@~ zHE`py=3OpL*)t$I0DZ|2*r+|YfT&w2Np~A!!=s~wn0O9kPkL%Wr}4Es|6c)An(Wt( z`e^%1>g82B$Z}#GkyWukvRh*UEM7^o$d6zdd`##dk-oPxGlokCT0xRRB!-d~xEnSA zv&T@6_nlhT0)3I!>0Mx($vg-YrVgy0HAwC>51$H;jK101yWuB2_%e*p-s}6LBBp*B z*|}fT-~U^TL{)L9O+=k7JoZtgwu4}Ip3NNPw;x2`xTY^{vo_uz`@2~LzMH!F=2FtG zPkq3QdBVzxJV*KH40j?uV_ogYD76zyMP@boCZZS1vwJntuf6<~G9o;WEcyV`?yT ziQMDWyj;5^L*ci74JizP7C`S8yz-Xi9iEI7$>JdInNMRD^p9q|=}J(9!~b}E{~l?& zT}-34K%B;O=-(6nr*1*|6JlvwL6d$uLil$d?|VA=TNKYM3$NUoRXOj*nAg@hfAxQL zJ3o{}E~eNiv1Rd)UCfY@-Hn-w4W$o1BanusOBdu8cnjWs_uiU3#RFO^`MTlxO#1`+ zG|XW#&ewf%wMfFW^S@Sy_2mo+(+R)eLCf*#$$IPoNW<{kIu>Bf= zFXJR_#>SromE7yEb;&{4u-tU+yUj{3O%2Ux(vdMn$^~j;& z<#GSFd)14r+#>Mi`92>XCpJI+J}F-UJT4nuP@fT&xCcTquQC%f)5x~1limJnY8@_| zH(ON&Zf}pn@k52ueODvXrslPDbi7T%kgGK+(<}NF*D-)Fej()@B*@>_Kj5~TFdDQk zylHo-T}b6g5c_Rtoa{C$dt!?jmetK_cW|Z2)XB~&aD2YvA=JE1y3wpCJPK9NDYrS@~=&1p3I7F zv|Uk5n#2LAhhGRg%|EXACEkt$Kl3{+Y|u13#qSPfFN$LY^l(=}DeDb$)L`63MTULj zBOj0;19$fp-vAZGPh!9AgD(^Z__<>7>HG`=-9GDzphA1vPT}Qv^>Qv?_v;>WBtV5* z18~`~06~3=S4gmt9SGMo*X*TlBk#JH`~fX42NY^k|Nrte_IH?`Zv6u+Up7{=ZK%g2W=~~2fye9k&GzVfHT+va}`t|n_xx1PW#!yK5#y z{@9D&f0IpZv{X48gX$`qtw>Ph$t9rUConKPkh3oaf@lk+*kou?*F2b0c2uFtQJ zcQgQzr9ZmYAJ+qrT?xJcc`XCU=F*~@zYA-@*;g@5}Ro& zon|Nd^r>F_X3hh5GrQ_gYP%B6)zm`4LW8irF~^e%}Ggp?ZF@dQs!dn4={dx3u z?tBQB`6Mvsu2`G?2LAu8ehFB>e1ZSb*89IoV&;m^n)C!Xf@eLcEP1!Z_d z%OL1GU8F16w6k;3;#;QoYOsQqC(yy0ZH6Z>urIr4`Cfzv!}UX_3K?myri=?K`>Ct~^&rMa(#4O&3csa{}c9X=+JSk`jhv@0|cH&?$W|$ z?HkWx3`P$d2-W@%2xzIvs4Umw?$_}sNYoAY#qdv?VX2rZ-8sS1WGTk*nLP85W8{twfD4CU3=JrFJWsw&7=4|u^oW;skZmP zdUsFrzV~B9^_k)Ej&nL_CP<`&KrR1Av_3kzJiDSuc^9g+392NaB^jiAkx5zx{<)dT zFz}%A>ZD`##qq~mhNR*zR1ez!#W&TO>oHBOF{kr@NxyvW*@|S$UHuX2GTnN54JUX& z#Qlj~>zw(HeF@#R`GMJklp+C>51h5BzurgiJN;jN8k65`n~VR|t|L}LWl|x}iZV1V z$^|ny@zzy2%3YkaHdoeFl9q<%`tee7CFC?&g&vOxsMXzF}yMn zlButMTMEl12R|N3%01<=x*Fdy708F25S*v4o=9b#Mz8>ac8{HlQW~9zsdsOAvW5Th z^X8Xgk&$NW4bJuJ-3O^K<#>aHOA<(uew~hOlnZVIeE$8nC2>Jm&pugU?d0|%-7NpF z%0SLU3Z9Skx|0Nn)NHrVpDO+T2TMQ`{bXgTO`2eryRS{3X-$xK8rVI3{k8Fti(afz z>pmFh5=-bREX4R%3^DDM*mKQ&3nbuuBfSYfcDer3Q^07V?MjhxVh?8c36elQW*O;k z%d+GGFWMFwpnRHjUOy=oNhJs%y)ta9>@i!!$@BMqT-1g74P&}b$i;7;3k?elTNcS@ zF+ATr_SHoXW5T-K5h+*26ak5$g$} z%6&hG?b^QH=WloYN-_S;sXfT4E$Et?nfeYn^;IYl3F!?)qFU-bb>*+$1><{M-A<8< zi^zlZe{LVIjQlTRD4`sg+ zs!AnTEOIo3gF$3frq908wd4NMjU;Q_X9i1%-{lbJ&T+O{Zgfjz*nu(wj;7e%b08qV z$s>P^Gt}w54tig9!39zD$*^w}+ZeEGc?~s-m6W*I+O!=0=}gXDTdIw z#1?c6RL3OeSqTHtVgS(xX=`m zpISRvrduOgJ6j)w{nG`W^|ZhR#vvmqV!&H@*<*(2qmw!k#AkxCCj{G9)Ym>LZjOl~ zDV^1Hx!&-(wmf-rP&>OgQ*A?ZXH3-t?%^A7xMC<>B5Sm@e*SwV41+67X~^dKI}Ek` zG@s%QABM`t7s*f!m6$FUb`97!y$vk?A~;dr(eD0}dgX>jY6kF&`IGabneX+-ip<|M z*S|KHzwV7mZM9`EN`MyFUQ?DHIyx468FYz{8N4(w(AM55`gFekL!74w9X_s^0K;cp zZ+Li)Kzc4h4{>yMm8Zkf$}d}Ewgn8JJW8I6%hvt%)4a4`_R!P!;JtrwLM|;j$JWyL zAkfH-f1&D7Zh0WTLLB95U+b1YBQ%d`S;A@dVKB>x>z4sct5o=8jj;SkAp4koE6hPnClX*W|vKDDC>E`4aR)Xm{t3&PQ!9j&Qkjd z`&MwQv;3iNIctm|vT>}f;za8$J4^UYW-4mtySLA1R)J;SF>PHd8?55QxUjiyFSodu zuDCSch|%TI{NHA#DBm7R;!@~x>N>3hb6+IXXBw1KddP1d=T(}X5O|WYa2n?ZKgKxp z&CM5%ex_?!HcvxvSMP9ff(pdT&berejxK?Q~tE zx8|tQW(q0Qf=0>ZHJXPfF?~cXskyu{RVH(vLQ;h6eWgdg;=EQ_9amuQ!KJAL&-s-{ zwEv!|gC*x|qqOhql@A^#9;Y5k(u-kEv?G5gF{e9*WtI zBp0z2|7UyshBZE8@-b~L&-r(o&@v1Vpdp>$q^0wT;!XuFftOzB z9U$uB7A6<9XIv-FqG~}}e>zJdUCPevk<(s`!N-xzwakt#67!qE9sxchY)JsFNK7lh zKTP(>qc8EAoc;QfpHXv&^nKX%Io{)BI1_8dw+v>$-2v$k>!?lP)A(Y% zdne2}+id8BC2n7pn~}W8Ee0~AIChKFSWyWvt*x@j?Hwoh19U00oKmjF)7tND0IjaX zvqB9X-)XkN(b?2DrDApCL;>tV`6cPK%i3M;S%hr(y%oyWP%*TT~O8;o|CE% zpnxikzdeB?(tYf?{tG<3PIcdV zieyzjsFCb65eQs&8KS5Gr{2W#uPg2*O?EryJD76HRe4%l`~Mw2R=s~$t&H|F0*mHu zKbWvO8ATbe{I;E#?&6XSHJwaa*KgXo?k5*Q@j-V6Ox3g2Wv?0ESo(-x?r6g1*~jw< zns57c;Au7di>14??Ck6$B_Fy{&II4FMoYTj%dwXkK%vy=MdYSOnpakBx7#S?q3W#f z-VmM$G;FW{2M!|u*wbs_4eNl&6#~Q*_+nE2+5g;SK^cZwRaMqq^tPqK**S~*xXj`3 z5=4Kk)cKQ8&u7Q8&mz?D^88obRGs(?ve=<-i&&cbQ)8ytXBm$yR5eTob__S+R!_!tKk^9V+uSQr zO!*Mt<1?+X0xx%}+v)YZPj>NuOkBU+b&e1UGm?#4*)OpK(WVs7#u*;Hid!;)BoIAR zKV2x7p+wnZdZkimju4%n*Pn|@SyM2k8IUuB6iI2BzOpRZ;~?&trdj*4r|I0@-cO%( z%M6~WIa?+5)&##oMcXWhl}W*#A8=h`0i1&Sd8YKsj`>5+q-hhp)=8|)4mBkbhg+!W zMpNWV9JGUzA`ECH{pjespLtaXnj^iJAYa>cj`R?>5jnuHoa;;msq#zFd?3pTihKO zIoFTdRtbAea$tnDNS0bW7sUX}ZGomdvMG)1uQ{X}sAOVAO4%Jl>tYAdNxqc?d6m8@ zINISi>Bx->9#ibr%kzHr201s|RZqCF?&(+*WE-NN6x!&6)A7$WRn2N3N{61B)~&~J z-hAZ3?J)AZB4x#~hm&Ao0VbALzgX6zGip|AY4{-*xy)~r`L*YE&kg_r@saYWo`*g0 zc;zpx`*>fkJoh3*YNkz(VVhw}OV;xVUm*l~Z<5|E+QWVtb_%m}fS!&IXd3HhWmR}Z zYz`z(p*-Dj4K|5IXngM0T>Us)*Y$X8+1Ot>gpejL_~0)*PG(1N?kCe5UF^_~`$^fY zm_IG%PVq9cW(6r_lx|W@V6?F%>}%tdEv@DZn3fF3Vl<3#f5gvXwcP8U zUwLgEbms{5Xn~ym*2%A zijIquZ?|aTe}&y-X1Hzb6z89ZS$D(mh2&e+ELBnBHAR~;57H6LhS>%Ul_w}vhRG?t zsK_reZ?lDF2VL}G?Z?EpnS7Z-$Fyl}+^8Z?VN%?6w+o7IXm)3y42QmyaJpQ8V>AGx z7^S#GByhfTI3RJht6NEByQJT1H!X=oOA`8b;8T8sY&p`x4`3vw)zfi?-VgLo5Bjxw z|F@q9`vvF^mk|7FtU(e~AF!oyq6Az(;#$gb5Ic`t@Y_6nnatvjd1BgX2eyAjlE%Xf z7rGZ>x+!CCf6qv*KTVX@c>3C#?Gg1#2YLnue7(s3Vak2H_ea}#!Tnp#nql`b;YhrL zgz5!M@M3BrDM;ak9blHOx_n{Z#k{jgDu4Rgtpv2N#AF57%?PnLkNITGcrm|!wV!jh zV3oXyXawHQTfPYpi?M*(`bbj>m6~VQ1{5SuFz>Raj z9J|WtCUd*B`&hP3d0H~g(&FCLOpZ|6wfJ9Xl|c-Zg8VD?$voPNO#lSfeO=HZ-I3BX?M(O+)(g?$PB?{s8nScG6{EDPu!qmZ zU0j}@yE0KKr$(gpr3=%xXky}9Vu9AQi_utaV1ta0L6)p-Gx!x1v6>pW)7M~_$2)}H zshbRF`S#EpkD2xOrmoC-F$vMc$`)gWQ@m2;w0=!>d2IjkuBIVxr#4BMQ;Cb0PL=@- zHtc*g!Vl|j5oGojSQ*;5w90*+Fz98_ch#S~&S`pe2IH&Wy5>`&64~L)2BbL9N$)aotsn)3?8GE#_#7bj$XU_~8bpD-C37uE@^ZavP*Hh_Cc zH(-*>W+F4oQ`Yu*AeDy1@DpZu#M?|eKPwlWt8tgB2-!47NG3(utU!SO_6Twp)@*`E z`MJ|zKXc9&!Ch3wOT6uIIQE^R85({F+Gx;k;6 zefo?J2KsMjLqBp|G-uN*TYP)vWW)Ln<{if>9Bu=B-tTCYrs*{R4K;2!t_;Rg7&9({ zL;+P}@+TKS#lJ;(dUaqnC{852j^GSyxjkXuy;84m zbeo!A%a-7Ky^DmPJ{WTF&@#w0Q^Vm9JdBNI(C1 z2f&n<&Q*Fch6(-A&cd`rfk|icLm>^m*1WrI;#1Xt%fkR~(%_Bz2+7P1*=t`ZCKK+H z?Z1aSOBxOv5YL3A~${%M_##L8lS{J(04g<+)dmjPT{&K0=Y0BtEWJ|gI-J zLdm>%{MF7MSyGo6Yg95AbuC)1kG$|Tnvhx(rYhxuuy03A4gH_oV#x{^rTk_8Q@hxZ zEm!02UhC5^%qN6@df8)&wQ-d_uC$qE48$4&_H`&IupKPBO=dIge06oU{*6^}uOm<* zeB*b6mEXtVRY*c{t&iB^f_{^Y4MExA9Xh z_-^x^Y*pQE93ju%1Nfx&JX8#)xzz7`*#ShF<#o0Lhq@f$kFe)9f|lmt)q_B zCWylWz{1XY_JEqvV7l1RWv}wqyUNTEu2r8!7~dso6xYvqFAIn35`ywxHUWq1U;QI) zu`&B!FZd++EY-M(A1-OaS2$MIxE^w*gm(OBXh;x6-upNXn4BTz=2gUy#N71FT(@jM zZ%M0m`m94_1-&#Z*uo981_L4g>k^9W_GTl1azj^%+S(PQ^?O8!U^PDE92z~>QxII5 zG5y<*AHN&BDY##&HtB2%;jc#aAGU73y%{(FKf@UIQ82&kapppIW$`7#_OffEaA>3x z%!kPVIM+R|J$8Nj$U=Q=SuWz`$3)#nHkG<4r+2Y;;n!1|_tPT;xzXg}58|L;&g$RJ z`M3GIvUD$ue#|C>@p*Z)4|BfZ-!kex(Z70kx{AVTD?&moXndN2=NT|zcrUb9(`&1NvRmIe@I&DJ&_<0KMkTj^*{=wtFI`)5-va@R z=^f|aIG<}gBxC0EIqa%mb>}85-Fwb-AQ#$pI8%q)D}yI2b1X14)sNi0HWC(zSoqTN z?-#;pVbQR~q3p!zd-#uiDo{T+z;L82;@59ay?H&Q}WwVny026W_LTW z+xoFyJB+G|zk!L-%ULkNh?^7}&9(oW+x10_ph zmw#o$cX)8d+*gx*En~O;Accw{Aj20E!`^%HtETDr;9xF5sqiZGB0_CO-d%lrJ#xLc z!(R;@$&-B1Fnjlz>_*1HPoQhS9n?m5cpf#w_+Ck0{O+T`z$n7eoB9xoue^;5KhnaZe0u`TzC%Q9^#ij zg#sU3mK!r}FUtN{yLH)WZ1joMxI=K$Va5(CI*UjRsm*-;SerDT8Sv$NJ7epX%}GDM zTW&$FL#?8dne`kGQOW#OCd@Z_?!~s7(eunrUG{fH?scBmT93|qFc>86xH2iYhsMko znc{{2aJew|5S?E=gbn`DaWx*wzB*>-a%nlkR76r8E@&=Z92fP)HkZVSq-TCt(fPQE ztd%=>xX;&`c>+i10l|*9vY%Dq!I;^om|Sdd_@-KBp8GmOuU?y1dtr}Iua=%`T2`+%S|T&M#tL^21kAOK z(kCD*h0qk8_2G;n>z@1Y^6JW?zkkPwdF(LNqWiHRSu!98Hpg}kwLeM4GXlG?7p`mm z&d<+3OQOJ?Sel7GoQo}TA~y+`tH7Qh(CV$`OWOn7{^;EBVBtQ?)i)@$i|^D??2t1* zy=n8?y-{Or-a5xG;%p|TlXkbBr>}+P{~Hz*;K{~`U)Mr*Z1x@7Qs9{MJ_Z2i!Zj{( zA+ePr3rNS~3l;{h`=f-|ntr+<*mln_d}WV{yj_G#jASt=U@0X zrD%a0-)J(&cVYb`Pol)^F|T^Xu)vwY!oi9`;X-Ovz%~8FOZa3)brkL!(kXcSi<9aR z?zVXmEqXa;=Lh+<;G&@GJhRe6iHZn@{AJ#42|A3Hp-K6MpWzW!wshIF_9mFCeA}D&T>`EEvx$r65A@!>-yNKsmgk#VJk89XZu=^w0F#436L(H$R2pu z)HgMyb7C&NCk7AdSnY&$EUDrN3go!;jTD%K=ia`855x~!2vIe`9h@hr%d~6CeM#~z zpp3Xqo$a~-KjmbLR-QKDg9W(YTF!mMr}vrIxy?9eMI`P@SiR!*;tuE~M3t`3F5Movabze1pFK^7 zr?g~wPuVmnB9k)K#wrR<+cb&U4fWE(mQ@ERiJ83jsObaR;>8Oqk(T@*+P+9+bCzB0 z{@0ew`%lT~?^OR%#L-VGEEj##+Rcg6+BM#kO7T0G=dQAF?O*{GbH`~)Wv&BHaz}s% z`uLfijGsJmHa--~9LvG7qQ3-2kn&Fgw&u>((`3i$?3VB~%cYq=cV?}+4z_v}T7;yr z$W7!z4K`-61ONOM=d(Qp&|L{CP@r(w;3v%=R92>Ogq|$y`^AG$%l6?fWWzUav5;GF zd+e$`{}H-RzUK?zekR4a(53L*7`^(SL>c`})Q@fU`}^E+#esEI#Sl`PJaj~c@Y|$T z_p=An=$Y1s-8b}m3M{jlg~cJKzkkw6-)6)sx9#3ZM$txykf5KXRkD(M3*NcMVzV#5 z(!t!+cVd1RX<0+@{5?m;R%nRUrf2G2##V!+h|Iw8N;0Az;G&)#Na?c4R+Y0F0sHQb zXY;b$gKYt4O-rh^3rN`a!N2R#(7kNcf(>E_at}9!?ruTGD1rMbwDD@aYX8#O+M$Wl zB%l#LjyADsbyw6zN@ZX6EmIn8D|en3gO1j-EGp^4?fJ-+PNYJ)k<8)T@ac_)m%2w2jH zVp*EpS)MIbx?_|g>=nrDmHAg@_2svI8=AVRZIUEO7u@n2R!FEhqPsl^CNJ&%0NGt) z*!N{2Sj1du=EBeHubgJw;X%Sj4g=R=92tOV@pMx0NAQ(rapx`zD z1F)0|3Jd{(=GH`i*X~UKQ_eW7yvIn0=aqbrlSuv7f#t`R%s;amht1Z6s!S#dRrU#; z!?-9Du>Mh&z~Nko+Rm0odHHuWnd=0r%TR9)Gu=a<{X97Me6a@XLb0S0Rfs+lJnB%A z5!~Uu&OAHccqR9yl98C|MquK{6T+((VB-p$JkC)VJ@3Njf^Eil>`%bcpUURdUiLv$ zPzjW0f?mf6gf->sd*uJKwucPCBwpt4Cane@sVTan$!P&L3<>BWk2P*P3|Xa_6RX@4 zaa?$k+|aP2Ib%#bpe>>uhuul-8X?|m>U$@A71M>eO-{nfB=VKfcT!jd0uYMBO(3gB z*V^$zV8f!2J*!n6wsyYeCVZWJ&e_TVCO2D!a2ZcLB{IrNRZjw@=8eT zRU1=nUY(K=Z96Dt`w;8 zS1HCVIzu@NRZIV84K{Vx&ruT)7SCrikak(wrg;36X43Dl{*OT2WWBW}%Ft=wah4b0 zHsMGVw&u3Y<38cf@&W~ky$y4sfo8u!|FatdmnFe(t`w_4K~Gui0%P-Dv?v{_2I#k( z4Q_pXQQ!N78!a{=4CW zx@lc$?9NN6@B7bbL?mgS&%P|IbkDw;Ov!Mv2Ut4R0B%5|0iG@V`J`9FIOc9J1|%Qi zrdTDnHxYmm_;+w-GJJB%T-l#hG)PDv8QvVI#czB*RFss{215t6NWFdHcDn$et>XA) zF1b`>f36>Lw&<-}q=&_lw=McKh<&)CJO4{YsT!+BhF(GJ9(QK`G+mz;#3o5m$RgvM z|JW2Tgh@4cZT$Y>#Bf}}ak=)aMb&%C@n+rWY)BNAUOlU#ilpOw5oJGH7npId)LPSm z#}6OT;=Tt)5OUv4YV!x(Z&iW_u1d%&*d8G@JcQ%c)>6IZ*l9O<>cs8fr`vWb+9@Gq zcWP^idsIIT&&9nx91RQeE(2Kf#cf9}gMqiQ*t{6wrzcUUo~yKlgZBK7MdLO1O9uyM za3MQo#B<)+oMeqC3Z?ZnZ`URdZ;q$p*=ln=P#8Nlx<2~uKVdIM7K>CV*e9<{6UAXm zmf^MU^*B+1<0U=VlLog9J82|Vkb!sn#aCTO&wm@4_E z$%^b#q)&h9&UT%$*xOHJcc^aoLnzc9)qkee{`fC)E~n)W0NG9c9oo0|u7I*fv3T!m z)bq7hGEw!Jp6pHDf3Anel0}aXIgaDTh)CjB6)VS))h-6BKz&_H4e$?M6Bog*oO(-- zRuo<$vZAEtNuA?li`dr0ejYrw9Rr{DLG}zG=OT(lY4k!2J9cHGuX5x-u0(y*RdSVt z|9IYM#G26in3!tP4gg|FEHMT)D`_5G`*FXb? zG~GQmcGl6!d^_U!4lO2k=G$58=NcXXYiRT?VBh4^nBA9rEBjZUzF+E(k#T&2(A=s5 zh|mOv(n^Y1e7zWW1S}jrp5C_FnJnBCB%Gcg@;9-J(7+E$8qsO}RqgD|6_|?{sl*Rk z4Jne`+YP@cGyL=FZ2Eq;hT4Fu(=uB+a2*>vJHK~mVDx5SMI-*1@+ML-B)Yv+mcj`r z@G#SS@)x$|JG#tTN9jPg-9M&E-C?OvW3APc8S#4BeJayB&Sq$Wm3RxaIzKjTI#F{6 z{3Pw>oXU7Uu+=g*iTjALIo0eZ2N7UyYPIs}sI*`Cij`09X9 ztWtz--0zVW7rDLx-vqt7;jinOu6tqhLS@)!MpRkS_nuHs2rgio48R3cn%0n0r5f6574I84zkjgON!c*AfZ~k5t z|I(hf)bzQS4*S0IECIWvb3fZPHG?ko7xcvDo$jM^@Xg|Z&|9^s$ydkbC@?7P;`z>W zAAFzGH4;XM=dnxeo|L5$Va-i&xrN!O*-G}{+pb1J&O%w)I`60ONUvLDWrvR`>I zT6N_~@jOcrwk*O%JdAJAIL6{zekP-IS}B@*=`@>Vevj4KIM3|hhkR)+uOqT8t;cvQs{ZFb2V}ltKxWl7@ip**MaxN( z@3u8r(^{mvAyW3I?pEWNb?d!$s#l0fvAb9NL1AQ02R`S8+&tV!`5ZH$zN0gyVJzHb zsoFKOt)PXkMdZ1Y&CMe;=YBwc%1MhgPe}7(fAvTZ&A`MlbjnM^1!r4)>~y^{m?&Gn zwX?pkL5GC`fS6=;k2wb(HtKIJnYHRu*HGmZ-~jb19JiknYrip|s5$W|x^w80`lr|^ zP0WAOP#UMp&p1Be6_SMI2(>Fk=T(1dvjZHIQIh&5UaN0RskKIs^S>PX+DzqF6}ryk z(0a);!5D{ot(i(@>e`>hFuS7}ef693kC2zVDL{!J6s>g>-eUV(L;;DZ#*b}BXr36K zbbMlU9bhX6sUnv4*5Q!MsIDRgqoer0=$5RXi_YuNnNIO*hbeG<``v+#`0ugnpXf2C zu_>@3RLFpKn)&=Y6NP}`!_6i??{U9)gbx_XL?W7)9S|i2T==DaCA40A2+4ua}CyUB<+qLw>D@cM#n%+K@t*|pLwakm>JJkd7A_|tC?Y45W@c__DZ5IX zLO^Yf>V_;f{2GdkxFN(oS6fBw+s{FHhg%x`g6=Y+ZTj)JTe8%Lz?#E6|2vfyTC7gl z&7~e!AaLQu^wDcMEZ}rK+)o$q{>*3$TD*i_d+bA~T^x|kOS6l52uJbn7pZzUab)p& z+^3iuL!HQHLZjoGd+*ipTB~8PSgJhd(jB?BK$)~ZWhB!tOeZI=o;{>?NsSv_<|;{} zQ<_X7kqwI;U#Skp-UK_0hG3(wLcmd$!C5R4eD3#4y=K2X1h8H8ZTZIvTU&YVz=7t- zh^A?#;dflyV6m*4?c3Ma6ApZ#XxH{-_o8I}!y4pW!F>`iSLw5IrDFTcKlp8ruTo_0 z|Gi_@-h!0@OMf|i)AB8i8O=9cOD9FIy_e&(afda`0S-e8nL6T7F7BkCuymc+^)fIi zCT5<;LFg0!5n=cb_T*zJi1gzexKix~HjgD{Bo0Ct-DWV@ zY!#FakBq=CBlp&_ZQpglv#=eXp z>sXRx3t6HVMp-9Y)@CrIVeGOiTgn;{Mm4ChD`FT1mA!1e&-8mg@9RIG56^SXeXetz z>pstU?nl`9L6;J?>{G8Sa~fq7#h|jYMe~4X<4cXI%s-8rBZ40HrL})Gk$f(d+@51( zg`@(<{Po3xw0yRs@36xr`LyJ;i{<9}h^V=|bS)vYw7_p%OMtw(7;M_9hGucFF> zh~a`=zG>nhg=PD0lv!YUXvA|Tc^5x>%^_y+4}#~&RTnIbxT~MUb_&d|$V<*%Y|`R= z^mVy)WwH<$LOB#vHT!t<7K$GGNAJhn)aE8F4rmF!q)-O*Uy3VFM~H+YpZo|p#?ERS zbjP`N+~_p-gfj0+7cNuh$z0BxD;4hP5eDVa{!c7lmYID}UNa3Xqc%D~ zqLL7CSV9EqYDl&1*AeB3)sbk*j~@oEFTFH83-w{KD})O3{hGVFP>;{JL8%ahJ@_JF z6}GmlvM;R4LpkbFAb)MQ;>zgZ(MR+YRK?>a+sZ>H85Trd=Cvoo6g^P!a-1PfF@QuP#YrxlXu^N7vf>}0d>YWy z`cJFg`XOh*u)1u~PaQwwQJ1>Gdy_|Xr0jgYE6I=j*K>@u`ep^SeD;HXvL!nP^c!%p zol?P_`|-7})~1ib?5i)^(E|d?odnr7JN-$K+{oIAd&=UCJ1go~esU%`wd{l-9BPkU zBr`W=7o$An5GV4s2H7X6hk>Ues!VoCoT)~Dsa<;GKrbLCXwgm*?5mXP%x3UMG}n2@ zb=q3MX*iX&>74Y8NmRcQD$4b~fg9R=)`ksfxzndF?lPitG(6ls_5{2^xFr`*I4DUy@YTqmA$3>8}+0wg>z{2cqZZT<1Y>c>_Gwf6<~4?^e7V zJo?vMouw%3hgle}>o;csSHL-qQtmw$zdX@Yi}EkDla%gd0?bWA_}7Ux>9tU-??r}j z?`$uJ$ea{fUY}y8_=NoK<40+r)X|)&4oKf5aS4US}%B`USD(hpmThj=&|}El3d^_efQPvgzanYSsh!f z8{4rw?8i2OEG}m|KFDz3=P&#Jz`R)DE%ID^q%$^D?ey2SW5(O{SB$#8aYgoOAl#`K zkylv3r87Z$j4m_aYwSK(ue7gTG1}F?CSqjEFHg9flHe3PTs+WRg%nv70<-tBcZANSijXv z;TV=SKlgsq@cqXrbZJZttm0`^M02CpRXOiZO@*Iy_u0D~HtgTbA0kOG zUQU8Ep%R(L97gcBVoyH3Tk!;r_~qI8EPuy!?sow_Op>b7!5!=w?0qj{cf4ubizN8$ zQ`iN?3TuU;AJv1C$zQiMJg^>|3oH4~CB7b9-0;(ED@k!5q#>0zODnVtRIY)m@>`?s z|B^c&V!U2WT-p?DmJ5Ak^%K=%r-T$CuQm2p8UOZqFbO_?$QA00|JpLp%@IR{rIpgN zEXcL*I*BnF>*vnB1B$mY)xZw5=kiySfTVOm7CxvF_&-s#j+|pJ#CG&%8q&kP{|G?* zV0ndBqBFwEIf4Pq%3W&4@05PNz*W+{aJcwG_o=f@(1=BAT$%=E(+0~JYn0rxrU^&F zg9aoZ$F=8^Iep8MdtQv0vjq*!oRSwMy?V`;C0i=+?20$8QEGWh3G*<;WK!qoH-|@g zd?j3^YCSwA9;z%@AyJ%iMQ0B|aYbTFIy}8P8p)WoDD^dJzx#IR^=fZcqXx0oHS_+= zf1$06KWiV18Wj7S)xHKjc=hF;@2j()40>^6A!KmngcPEG6GiP#WIJV-YD6T9!I}!` zDNQxFUHw&E`X2rFWp+OVg|jc1wf^*#Eq;x#8|m~V&&oAyvLxX5vnyv-gfRrc2g3va z!%0wGs6ipr+O*EFFGY}8Oze}OU-+YbcDe4;rR1KNS}SwPpNIPDWv)Kw2s=Y(NGfpQ z4q{|E@m=)MyYAiH0;_9-H~l;P;yyHhIZVK(xVcMKDz5a&Ok|>p2V^GiBR%+lcej+Y z=O7~YxUkbxYiw=dT|Z*{LnG!QHDC{>#TI>DhBvTH8~^@_vb3!KRh16 zdS`mG`uV$3G$U*>T7Bq{JBN!;Xy> zC&ri%)vtY42TnM|fRLfoP+a@CxN7fQsw+KA8gja#=+q{uS)e*Pp)|zfcu8JvE-@>+ zYW)n$RaA9ydvE245Cv*7ar9mB_ZWw`%UB~8^-IfG z>sQ%05#jv%i{G8EBVZ%8LQFnkrBgub0tpc6rmYQ7PY6%F9fd0h(q2ulY z|u%gcenmFcWXNP%*+}RarY4dXrnP`9e?zvC-teR)Qrp9;A z1FjJHUITHbrft`k`%O9B&u(t><$f}2srP!jeBXZd{^WAG?d^PUG%ofYxHK^Be@bmS|`9pdiK)mPp)O>DYIh_uvL|b>-`dg#V29A_3Aa46oL>|3~o2 za>qJ%`#fanzTLZNuh%KUD6SJcWhA)i71czQgk*#JRr&4CT1mLKpd_P=%E3rf3}$o_7i>0V%K?pfOU7 zo*A7DLZ2hFt=GXDS+UddKB7rz#v>A|DxFVa?&w(+_w`FxM|1yv9vY9lxNX%b*fLx* z^@_FZ#j&pdpZ-)rF2C&OK#JREI7&|MH%Snbwp;e>w?hxFzy30Q@AWEQ`(}T5-k|mN zi4>RxKUDSdU6J1 zVvp^s(#XFN=!b7yOV`%qrfXX6mTs>$X!4)YT@acO=#+s(T0$)|Gj0{&`D&qF^I3h6 z7jWtZY;yg;V6ICvpMFbSQgiT+O7Qrt-AZBQ)ALl&hReI_IQH|0X2M@; zkUfZwN*@^bXmV+Ci}hmAQb%IWg^tdnvbG9E!)L;I)NW#J7L<0!>OyPjtK#>5K4>=l z-D3E=8g~%?7XPB|wCO#XNmQBMk5nTo#cMT&J%bmq-cgim-yDH`OXKs!y`-MlKiWU( z&ta~|!Ky>n;b10-+YK5xP=eXausnVgRzI`2%-4=o12Kufh#@zQY^aGJ6ooKtoH6M} z)s>jlE}qj4*VsAmzw`@2e`8ZZ8Nk<3aulQFW~oO}*4G`T@7z}~Sy=tpQRrY?;H%zZ5(2bo8t zS3PS`uTWs((QVf4cC5H+3fWN=lT`*0yRc&@H2h@ui+^N5RpLxMmqimkvwz`?*b!|! z%XFFB5@h=34jaTzIq$cWN+;(x%*gHjR{d5MqOa^dnepc-&9{~f>ufyA7cqIb)jnRNYHC8ljVfYmQRa4l zD%$TLUIhq_P}#5fz3cRaRdol{?5HvsbE>~+ZLdjpp;bf*ab?HV^u?m8o1AB*ywG`; z(!WdX=OR^lyFS_@y&-sB_}g=9sNVC!5^0wW*@Tb8oc~ZCaz;o%b3vdA}pz)|5WU;}GRq$7bCk&h$%s2Q& ze_dFG-`5B}>kecGk0fad9|f$ zI{)1m_ACr5$JXuiRAatIcXi>~L`y>-Iwuuez@+lP%ftL0dC(t(oDhq4`7be8v=PS1 zC%P}`ww}aG76?I@*3>ADTLF<%Pb(kLYcOu1r;q=a>iSsplQAY)Jdl=H@?#mO=y6p{ z?qxAJqE^v-i^M^zR(O?)_ebYtUrbq_+ZpTy`(eb1Y%(~4CI-o7^a*xuoK6-G zLgZL=hhGxD@;fb4C*bEEfghC@OX3JWy`$V1X=L_s>}WKYKY!EK)2Yz`gWoyxx}LL~ zpdl~_>nM1>F7V{S_9Y$GluZTI?gxQ=dvV)b?UPF7PKhe3pbBolU|Xu20TV};vM!Uc zf}QoJp%2H%#5a(pzMh~4d5oRwBS*Rpaf4OTOiV;=5hcxvlHMuq49R~Ig0K3y^(ySB zWWL%n&dXCF@uwqOF(r-hdPt2XNkVoZ-K2Psz*_%wQTqrmR^L{IsZ&|5aoR;)r`;%k zu%ior?|P-Z_ez>Af!~#Uf_aMDhLvG8XQVwxnG(37e~8-=gCGUHSLe1LdPh61g+3?5 zkhutRF#uNVvQ8J%W}0E|u6L0cXiDK3YhWT=0ZnlLsoyloVL)QIk8KsEJ;#UL{i^!p zNKh80=>}+qU14Ip@>9TXt4t-=75zn|K6pNbDEb{wBj@l0S!6xzEXP7_)8kfgecfD_ zx`s-2Ek`28xdVkOC!~SGDH3oTjS?ZjR8uiB*>@SnBJsMaOdh)-g)hZXGMiDCC$6`e zxv#@G#J7rW#f(uFyL`D}TU10J?ZjEt6wa-5VsV>EcuWQB4s5~_JbAs15okir} zTrAmi4Wgcl#UE3XHEoq8u-59uh!Yy24~B<&m&-hy8mz8&Ka>FkG+i#9Yn7HPv`KRx zoQm6*p%+Z3(9aKL{*#$-bOcZyKKZiv{{F>r6?6h5a;a#nXdpx>_6s!i#Nfa{pWqMld*1F#Ca zXdoBi@e-yA3Qu9(P+3Kk89gDL;Kh(PEC{mu&wKz*MDYi9mtWLvFczPV>lYhk|w~@UurvP~Qju~Msfy1+iq_SppN~0uIF(qLCm(+l6cO+1se;JnKdfq$e z<^dHen%4H1_R6l#o#yPmpSDjt*gxpTfwJH_< zgurMXmks4^@>I-hH}5WIEzH+AJs%985U3AY2kb1=RB=bVEG5Mn1~vqn*%2gE8Tuy( zaNyE(xh(4UQY@f&KiuV4PR`LJv2UddDkA#;9}JG73q&OXrK?5>kN?ugA8XuQ(lt0Y z;c}}lff_BAs67;76WU!+l&j8}ddkI$%C@AMCXdlPY9${XY@|8R)2R6Pl36y6Fa@D= zYXrv(`WGm;pG)j_M1}&nfOI*?wO)NYy=Db1R6=8&#Y#1Jh*L9qfT9Raf};Md`?n(V z^#+e6FFfzuW6gI}s))5gl|r#ZMh8m0f)dbo^M)-(NxX|gonm(TRF`6qRloh)Zw9Km z!;yOk{xd-4?UPdj>s5SBKBiVF&%38-9t>%zrl7^pAA|dX7Ygv;a9`ox*^_5aE~j9T zWpF=%k)KBI{}zF@F!~L;+#lx}JS6ypeQ6-w(vW_Wvh>LRWsJL=JHO_hhgv!$M*b!* z4}&aHq~73ta03XV1sgI9X z25J^Skz*nsV~*Simw zZwaZh;Ohx*W~|<(cMaH2dnc)2vJQ>t_kdfizHsJlKZ$-StEavQz5|&Wg%@YJ*=CCHyE2*Z+Y;qGrJuXJ3 z2IQuiWEbMu-SH#7T0u1hgK_FMVoMM+2axyeb9f8P%&kGq;B=}r64(!tsiD;Fv;GW$ zj3SM`R9qv#osJFXpuZAQ*7|iTNANODx5eT<32j!?Xbl7-7q_ zfkR&{ro9%LDa#T(8TGo{gjsB>jv1u^L^vSfAs1|9?`xyF_a%fXb6d;~<_kg}>Nn`z zYZ!olSDA#N6Yf-4oDctpQBB?RMhr5<4Hl~qEaJ9a^0FUf3ucs6sRPFbdL~m59AKe; z|5~88ri^7+&ZXu|OYIeNngXaFkPwo~+V3M;qcTat zOY3|Xw+*;Ly}~))MIm*DctnL15Y=HT+~BRaStOGKGUZIPe*qg@^|XSnLL+W=53=2%U3i%$AO|!`UvN}=11CO#bbF(e>l4idWSLDY z*p?Xae0iy80iy##+?7mD3rFQ#QtL508w_yZfc?j**90c@U&`_A{c zC>PBe+3MRpX$@tf3c;CnCA<$}4Ssmu%3Qx?CU|;b>8!-^ml7EBN_aO$q%;tZ@-L}Q z-Q^#2O+|t1;ci`tV!P(F&S67Wb#oZZ?JxRO#xQIp!r_;R)Pkq3b3g25`?Sa(sUQMXtS;0TfU2+i-vtF*D6ITnt_- zbRmPef+_$LT|{iRHovOIX=Ca3K#u^cJ|J_TAWvXCPP^lbZp~!-mOnF^tk{jpEjGYE{x3~h`y%E>|8WL(kzVbKO zED-%u_C&NYS~Omlcx!0G@G(Uw&srMLa2*Fxn)$BlTibmGPQWY4fCPA2UF!O|xnf|J zB)$rOZo&UPFjKu-ZVZm(Pdf5IT581k>)`Vz+Cz=BRaqp7S@b=YJU4En#}7L`E;_iR zbw8;G8^vX?thXKE_%C&e^4kh$2}%7l=8i|!IQ^lGZAQ`0D)_hS?xbG`mz;PjApp;I zWAg6r)w6epTXEX+9O>hV*7q7-_yNu}m?DCPQ~5zAet-}HAmT1$+I_Qkx$V@nVP@&* zc80xGZ%-wBT|I{D*y?q;EI&yzF!nP3i&?iyUqV)KxmEHCzG%Z2>1rwN_p^uz?+qY_ zzr1U=vE6{PNS%p91@TJ3A2rw3;pU_7X8fa#vD|D|uoEouT+Aoe#Snk^yLKUw760*8As?@Q(>wZ4SOP{jKNR@w2`a z8=|n2%bUe>f0I^v?^3hiETsaGo^gKH9ELxQfclcPhk}I1+sxe2l5priS6>NypzULX z7;->)-NF|@5Gu*s`XBJ-h1qG6IXkGoz28^fo~pnzz4`sFHZ)ugI|_Pu8#IGsByi>b zc!PVCq&=i80$dWPc*t(vKEaI8Jm9kb6z|38RGvU-pBAaDLnQoFXl_QawNtm(Kv!L3 zpTcJsu|fLyV$qGKp>LTPgX>+s+l1?Aif4+kCgDJhcw_#^!qqEvp$<>0LeP>dCYmR4 zmdHJ8ETz$!9(>+oDStrL?!<>>8=MM8e-oJ-7u;Cqs~>@YzXA@?xuj9PqxHEQ+?tGk zY4riamTSlsNMF}KZt>tIGT)6Yv2plP%V_1T*e{v!E(9SLk?B4pCKri*%Ds!amj2PY zRCLt}`gC|`+SU4Pvbi-6TwrA9U(oLkDPwJ%0BqCYEK~kD%Q_>`m5>=pi#sh(!dm6c zuiJz0E2-RH@^j0Y>!$W}42G0LvwHXPGR9gR=Or~0!_(oU;Ok%ea!ZSzl&xCYx`HD) z1tSUHTyB+-N29?>Kx#g&4{L2ttZFaqtVK6`HKcsj!Ot%5G>rdEO1tR>;ItmAVvyoq zl)D(-c58%Z%Yyp0bm?H=v+Wk@Z`LSCWfWA_9IY}+C})4L1hEJTr2u2Pj+s*Q@ftMs z#nfbf9}p4LS~x-zPdF0(RTiClKbI>&x(=yHYI$kg)>{|R?kERbW(Oo)@2avxC}Y2Y zJO^QMfBo~)TSF&<{}RoKSUBkp&A!JV4|XH{cijpwEVa3cL7<6n65)QOp}Cr3rRJ*A z2uL`agSKkeb0=*}pTTj1t-@zHxZSSN@UIHIs-Y|*SFEwj?Nw2`4WCo){ikxDwQ$_7 zct(I(u=1|JtAYrnmypXrOcR7#j7Iq@AkLt&x>cb+3*+@ZHrTCOUUplaJ2&3H_4({3 z9(-6d224uS(uU`5B-n)6mG;0{Tty;f)#7STX={|jS&*QzT|4PHC)&oFpck!$L5u&% zUN_1@w3qts1YBYa?2V$qkpR@beDlARr9HwA{=kvE{zuxLUVN~AT^r>jm3qFi0X6cv zDvtt0@8;VDEQU?qlr1snR3?;nOMjUoJ-K5p>`uif{XX&cWE@Ljx8=F+!N>ztDA#@^Za* N9r*Rs+eb%^{2wO~GM@kd From 3c0576df6636c3a091a8c80da60af70c94695558 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 1 Feb 2012 06:41:11 -0600 Subject: [PATCH 534/746] a second attempt to fix the icns files (cherry picked from commit e4b1ef1b6e714585ade646cd128bb003565b4bd7) --- src/mac/icon/GRacket.icns | Bin 177382 -> 218548 bytes src/mac/icon/Starter.icns | Bin 90858 -> 218548 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/src/mac/icon/GRacket.icns b/src/mac/icon/GRacket.icns index e4c38b4111532e76301e574ef93a237929d57a0e..8f905d1b5bf864eb0346d9ab376c542417057918 100644 GIT binary patch delta 41539 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൬QwnRx9mIKGt-8^zs$KwRHS9|AoMfbHE(C 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 L_0-!(M~?g-3W+W1 delta 38 ucmdn8n)lUFR)NgqykZ8%q*o#S&I$|+3 Date: Wed, 1 Feb 2012 20:43:44 -0700 Subject: [PATCH 535/746] Update version number for the v5.2.1 release --- src/racket/src/schvers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index f4055c2426..9d7f4e0be9 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.2.0.901" +#define MZSCHEME_VERSION "5.2.1" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 2 -#define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 901 +#define MZSCHEME_VERSION_Z 1 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 3aa43f88b76663a4b905e79da7d582a382812d72 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 1 Feb 2012 23:15:36 -0500 Subject: [PATCH 536/746] New Racket version 5.2.1. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index 6d14252e7c..c744a428d2 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index e4677a5ca8..46b8d3afce 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,901 - PRODUCTVERSION 5,2,0,901 + FILEVERSION 5,2,1,0 + PRODUCTVERSION 5,2,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 2, 0, 901\0" + VALUE "FileVersion", "5, 2, 1, 0\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 0, 901\0" + VALUE "ProductVersion", "5, 2, 1, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 356e175975..0f50704dd4 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,901 - PRODUCTVERSION 5,2,0,901 + FILEVERSION 5,2,1,0 + PRODUCTVERSION 5,2,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 2, 0, 901" + VALUE "FileVersion", "5, 2, 1, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2012 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 2, 0, 901" + VALUE "ProductVersion", "5, 2, 1, 0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index 3f9f36b845..5999857f1d 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.2.0.901 = s 'MzObj Class' + MzCOM.MzObj.5.2.1.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.2.0.901' + CurVer = s 'MzCOM.MzObj.5.2.1.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.2.0.901' + ProgID = s 'MzCOM.MzObj.5.2.1.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 5bbf6e4d5e..5c0677f96c 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 63d0c276c4..1400d2a39f 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,901 - PRODUCTVERSION 5,2,0,901 + FILEVERSION 5,2,1,0 + PRODUCTVERSION 5,2,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 2, 0, 901\0" + VALUE "FileVersion", "5, 2, 1, 0\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 0, 901\0" + VALUE "ProductVersion", "5, 2, 1, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index ce689a7f8c..fc09f64371 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,0,901 - PRODUCTVERSION 5,2,0,901 + FILEVERSION 5,2,1,0 + PRODUCTVERSION 5,2,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 2, 0, 901\0" + VALUE "FileVersion", "5, 2, 1, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 0, 901\0" + VALUE "ProductVersion", "5, 2, 1, 0\0" END END BLOCK "VarFileInfo" From b5e6a1e3e2fcc2607a5d7e7c32b40d0816c91ffa Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 2 Feb 2012 14:59:30 -0500 Subject: [PATCH 537/746] v5.2.1 stuff (cherry picked from commit 3ddf935f20e8c9efdb5c3446c7493d0f9c1605e5) --- collects/meta/web/download/installers.txt | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index 3724d45402..1cccbbbafe 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -160,6 +160,30 @@ 16095941 5.1/racket/racket-5.1-src-mac.dmg 15759982 5.1/racket/racket-5.1-src-unix.tgz 17987080 5.1/racket/racket-5.1-src-win.zip +10267078 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-linux-f12.sh +10279092 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-linux-ubuntu-karmic.sh +10832751 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-osx-mac.dmg +7716294 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-win32.exe +10770012 5.2.1/racket-textual/racket-textual-5.2.1-bin-ppc-osx-mac.dmg +10451906 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-linux-debian-squeeze.sh +10456800 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-linux-f14.sh +10955603 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-osx-mac.dmg +8044970 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-win32.exe +5944758 5.2.1/racket-textual/racket-textual-5.2.1-src-mac.dmg +5822416 5.2.1/racket-textual/racket-textual-5.2.1-src-unix.tgz +6874674 5.2.1/racket-textual/racket-textual-5.2.1-src-win.zip +58245126 5.2.1/racket/racket-5.2.1-bin-i386-linux-f12.sh +58264080 5.2.1/racket/racket-5.2.1-bin-i386-linux-ubuntu-karmic.sh +60616293 5.2.1/racket/racket-5.2.1-bin-i386-osx-mac.dmg +39511426 5.2.1/racket/racket-5.2.1-bin-i386-win32.exe +61643894 5.2.1/racket/racket-5.2.1-bin-ppc-osx-mac.dmg +58615183 5.2.1/racket/racket-5.2.1-bin-x86_64-linux-debian-squeeze.sh +58618119 5.2.1/racket/racket-5.2.1-bin-x86_64-linux-f14.sh +60851959 5.2.1/racket/racket-5.2.1-bin-x86_64-osx-mac.dmg +40202340 5.2.1/racket/racket-5.2.1-bin-x86_64-win32.exe +17941079 5.2.1/racket/racket-5.2.1-src-mac.dmg +17210561 5.2.1/racket/racket-5.2.1-src-unix.tgz +20641697 5.2.1/racket/racket-5.2.1-src-win.zip 10072568 5.2/racket-textual/racket-textual-5.2-bin-i386-linux-f12.sh 10087724 5.2/racket-textual/racket-textual-5.2-bin-i386-linux-ubuntu-karmic.sh 10419223 5.2/racket-textual/racket-textual-5.2-bin-i386-osx-mac.dmg From a5656fb3a8de00bf3f0043076db31de19f6202a4 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 26 Mar 2012 06:33:37 -0600 Subject: [PATCH 538/746] unbreak DrRacket (cherry picked from commit 704c32013173ff99ee73314e88e7fced12cedb7e) --- collects/drracket/private/drracket-normal.rkt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collects/drracket/private/drracket-normal.rkt b/collects/drracket/private/drracket-normal.rkt index cd2455ac83..e5dc6563cc 100644 --- a/collects/drracket/private/drracket-normal.rkt +++ b/collects/drracket/private/drracket-normal.rkt @@ -132,7 +132,9 @@ [(currently-the-weekend?) weekend-bitmap-spec] [else normal-bitmap-spec])) -(define the-splash-bitmap (read-bitmap the-bitmap-spec)) +(define the-splash-bitmap (if (path? the-bitmap-spec) + (read-bitmap the-bitmap-spec) + the-bitmap-spec)) (set-splash-char-observer drracket-splash-char-observer) (when (eq? (system-type) 'macosx) From 0a3fcb20ab5a7a30a0dd81b3daa94d260a910c58 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Mon, 26 Mar 2012 07:49:13 -0500 Subject: [PATCH 539/746] re-unbreak DrRacket (cherry picked from commit bef9e11272c3e1c9cb99ca275aa6df91eed5994c) --- collects/drracket/private/drracket-normal.rkt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/collects/drracket/private/drracket-normal.rkt b/collects/drracket/private/drracket-normal.rkt index e5dc6563cc..f3c0e36faa 100644 --- a/collects/drracket/private/drracket-normal.rkt +++ b/collects/drracket/private/drracket-normal.rkt @@ -132,10 +132,10 @@ [(currently-the-weekend?) weekend-bitmap-spec] [else normal-bitmap-spec])) -(define the-splash-bitmap (if (path? the-bitmap-spec) - (read-bitmap the-bitmap-spec) - the-bitmap-spec)) -(set-splash-char-observer drracket-splash-char-observer) + +(define the-splash-bitmap (and (path? the-bitmap-spec) (read-bitmap the-bitmap-spec))) +(when the-splash-bitmap + (set-splash-char-observer drracket-splash-char-observer)) (when (eq? (system-type) 'macosx) (define initial-state (current-icon-state)) @@ -171,7 +171,8 @@ (set-icon next-state)) (loop next-state)))))) -(start-splash the-splash-bitmap +(start-splash (or the-splash-bitmap + the-bitmap-spec) "DrRacket" 700 #:allow-funny? #t From dc7cb8c0ba0a0003b0e672dede46e76b312bde5a Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 26 Mar 2012 15:51:22 -0400 Subject: [PATCH 540/746] v5.2.1 re-built installer sizes (cherry picked from commit 8203cf37694775848ab7d1dadc41b93a67894e27) --- collects/meta/web/download/installers.txt | 46 +++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/collects/meta/web/download/installers.txt b/collects/meta/web/download/installers.txt index 1cccbbbafe..c9cbc28237 100644 --- a/collects/meta/web/download/installers.txt +++ b/collects/meta/web/download/installers.txt @@ -160,30 +160,30 @@ 16095941 5.1/racket/racket-5.1-src-mac.dmg 15759982 5.1/racket/racket-5.1-src-unix.tgz 17987080 5.1/racket/racket-5.1-src-win.zip -10267078 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-linux-f12.sh -10279092 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-linux-ubuntu-karmic.sh -10832751 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-osx-mac.dmg -7716294 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-win32.exe -10770012 5.2.1/racket-textual/racket-textual-5.2.1-bin-ppc-osx-mac.dmg -10451906 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-linux-debian-squeeze.sh -10456800 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-linux-f14.sh -10955603 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-osx-mac.dmg -8044970 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-win32.exe -5944758 5.2.1/racket-textual/racket-textual-5.2.1-src-mac.dmg -5822416 5.2.1/racket-textual/racket-textual-5.2.1-src-unix.tgz +10268779 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-linux-f12.sh +10279415 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-linux-ubuntu-karmic.sh +10829117 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-osx-mac.dmg +7719949 5.2.1/racket-textual/racket-textual-5.2.1-bin-i386-win32.exe +10766423 5.2.1/racket-textual/racket-textual-5.2.1-bin-ppc-osx-mac.dmg +10453826 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-linux-debian-squeeze.sh +10458751 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-linux-f14.sh +10960644 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-osx-mac.dmg +8048658 5.2.1/racket-textual/racket-textual-5.2.1-bin-x86_64-win32.exe +5944766 5.2.1/racket-textual/racket-textual-5.2.1-src-mac.dmg +5822408 5.2.1/racket-textual/racket-textual-5.2.1-src-unix.tgz 6874674 5.2.1/racket-textual/racket-textual-5.2.1-src-win.zip -58245126 5.2.1/racket/racket-5.2.1-bin-i386-linux-f12.sh -58264080 5.2.1/racket/racket-5.2.1-bin-i386-linux-ubuntu-karmic.sh -60616293 5.2.1/racket/racket-5.2.1-bin-i386-osx-mac.dmg -39511426 5.2.1/racket/racket-5.2.1-bin-i386-win32.exe -61643894 5.2.1/racket/racket-5.2.1-bin-ppc-osx-mac.dmg -58615183 5.2.1/racket/racket-5.2.1-bin-x86_64-linux-debian-squeeze.sh -58618119 5.2.1/racket/racket-5.2.1-bin-x86_64-linux-f14.sh -60851959 5.2.1/racket/racket-5.2.1-bin-x86_64-osx-mac.dmg -40202340 5.2.1/racket/racket-5.2.1-bin-x86_64-win32.exe -17941079 5.2.1/racket/racket-5.2.1-src-mac.dmg -17210561 5.2.1/racket/racket-5.2.1-src-unix.tgz -20641697 5.2.1/racket/racket-5.2.1-src-win.zip +58246608 5.2.1/racket/racket-5.2.1-bin-i386-linux-f12.sh +58279927 5.2.1/racket/racket-5.2.1-bin-i386-linux-ubuntu-karmic.sh +60604498 5.2.1/racket/racket-5.2.1-bin-i386-osx-mac.dmg +39516478 5.2.1/racket/racket-5.2.1-bin-i386-win32.exe +61654421 5.2.1/racket/racket-5.2.1-bin-ppc-osx-mac.dmg +58616709 5.2.1/racket/racket-5.2.1-bin-x86_64-linux-debian-squeeze.sh +58626727 5.2.1/racket/racket-5.2.1-bin-x86_64-linux-f14.sh +60847004 5.2.1/racket/racket-5.2.1-bin-x86_64-osx-mac.dmg +40203933 5.2.1/racket/racket-5.2.1-bin-x86_64-win32.exe +17941288 5.2.1/racket/racket-5.2.1-src-mac.dmg +17211427 5.2.1/racket/racket-5.2.1-src-unix.tgz +20641716 5.2.1/racket/racket-5.2.1-src-win.zip 10072568 5.2/racket-textual/racket-textual-5.2-bin-i386-linux-f12.sh 10087724 5.2/racket-textual/racket-textual-5.2-bin-i386-linux-ubuntu-karmic.sh 10419223 5.2/racket-textual/racket-textual-5.2-bin-i386-osx-mac.dmg From d15edaf6cc32644c0a1617eabb955bab9d478ede Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Tue, 17 Jul 2012 19:20:47 -0400 Subject: [PATCH 541/746] Alpha version number for the v5.3 release --- src/racket/src/schvers.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index 1594ccfc73..daed211de7 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.3.0.15" +#define MZSCHEME_VERSION "5.2.900.0" #define MZSCHEME_VERSION_X 5 -#define MZSCHEME_VERSION_Y 3 -#define MZSCHEME_VERSION_Z 0 -#define MZSCHEME_VERSION_W 15 +#define MZSCHEME_VERSION_Y 2 +#define MZSCHEME_VERSION_Z 900 +#define MZSCHEME_VERSION_W 0 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 59353fbc0bef428330fdff844dd5e91bbd6e32e2 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 18 Jul 2012 20:43:07 -0400 Subject: [PATCH 542/746] Fix version string --- src/racket/src/schvers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index daed211de7..e263c18428 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,7 +13,7 @@ consistently.) */ -#define MZSCHEME_VERSION "5.2.900.0" +#define MZSCHEME_VERSION "5.2.900" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 2 From 18b8e8367be04fcba172f8ae051e2c7012072bb2 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 19 Jul 2012 12:48:48 -0400 Subject: [PATCH 543/746] Revert "doc fixups for `struct' variants in `scheme/unit', etc." This reverts commit 3ded3934ee0a650fa2f3d180d7f3a56cab9af4b8. --- collects/mzlib/scribblings/common.rkt | 9 +++----- collects/mzlib/scribblings/unit.scrbl | 26 ++++++++++++------------ collects/mzlib/unit.rkt | 4 ++-- collects/racket/unit.rkt | 4 ++-- collects/scheme/unit.rkt | 4 ++-- collects/scribblings/scheme/scheme.scrbl | 17 +++------------- 6 files changed, 25 insertions(+), 39 deletions(-) diff --git a/collects/mzlib/scribblings/common.rkt b/collects/mzlib/scribblings/common.rkt index 713a2f17c2..de100022c5 100644 --- a/collects/mzlib/scribblings/common.rkt +++ b/collects/mzlib/scribblings/common.rkt @@ -12,13 +12,10 @@ (define-syntax (mzlib stx) (syntax-case stx () - [(_ #:mode section name #:use-sources (src ...)) + [(_ #:mode section name) (with-syntax ([lib (string->symbol (format "mzlib/~a" (syntax-e #'name)))]) #'(begin (section #:style 'hidden (racket lib)) - (defmodule lib #:use-sources (src ...))))] - [(_ #:mode section name) - #'(mzlib #:mode section name #:use-sources ())] - [(_ name) - #'(mzlib #:mode section name #:use-sources ())])) + (defmodule lib)))] + [(_ name) #'(mzlib #:mode section name)])) diff --git a/collects/mzlib/scribblings/unit.scrbl b/collects/mzlib/scribblings/unit.scrbl index ce5afd608b..20a5221a27 100644 --- a/collects/mzlib/scribblings/unit.scrbl +++ b/collects/mzlib/scribblings/unit.scrbl @@ -5,7 +5,7 @@ @(begin (define-syntax-rule (bind id) (begin - (require (for-label racket/base)) + (require (for-label racket/unit)) (define id (racket struct)))) (bind racket-struct) (define-syntax-rule (bindc id) @@ -14,7 +14,7 @@ (define id (racket struct/ctc)))) (bindc racket-struct/ctc)) -@mzlib[#:mode title unit #:use-sources ((submod racket/unit compat))] +@mzlib[#:mode title unit] @deprecated[@racketmodname[racket/unit]]{} @@ -28,8 +28,8 @@ The @racketmodname[mzlib/unit] library mostly re-provides -setters -constructor])]{ -A signature form like @racket-struct from @racketmodname[racket/base], -but with a different syntax for options that limit exports.} +A signature form like @racket-struct from @racketmodname[racket/unit], +but with a different syntax for the options that limit exports.} @defform/subs[(struct/ctc id ([field-id contract-expr] ...) omit-decl ...) ([omit-decl -type @@ -40,18 +40,18 @@ but with a different syntax for options that limit exports.} A signature form like @racket-struct/ctc from @racketmodname[racket/unit], but with a different syntax for the options that limit exports.} -@deftogether[( -@defidform[struct~r] -@defidform[struct~r/ctc] -)]{ - -The same as @|racket-struct| from @racketmodname[racket/base] and @|racket-struct/ctc| from -@racketmodname[racket/unit].} - @deftogether[( @defidform[struct~s] @defidform[struct~s/ctc] )]{ -Like @racket[struct~r] and @racket[struct~r/ctc], but the constructor is +The same as @|racket-struct| and @|racket-struct/ctc| from +@racketmodname[racket/unit].} + +@deftogether[( +@defidform[struct~r] +@defidform[struct~r/ctc] +)]{ + +Like @racket[struct~s] and @racket[struct~s/ctc], but the constructor is named the same as the type, instead of with @racketidfont{make-} prefix.} diff --git a/collects/mzlib/unit.rkt b/collects/mzlib/unit.rkt index 6079b0f64a..e5efa5b8e1 100644 --- a/collects/mzlib/unit.rkt +++ b/collects/mzlib/unit.rkt @@ -2,7 +2,7 @@ ;; deprecated library, see `racket/unit` -(require (except-in racket/unit struct/ctc) +(require racket/unit (submod racket/unit compat)) -(provide (all-from-out racket/unit) +(provide (except-out (all-from-out racket/unit) struct/ctc) (all-from-out (submod racket/unit compat))) diff --git a/collects/racket/unit.rkt b/collects/racket/unit.rkt index e7c98b9a88..3b8c588eef 100644 --- a/collects/racket/unit.rkt +++ b/collects/racket/unit.rkt @@ -65,7 +65,7 @@ (module+ compat ;; export only for compatibility with `mzlib/unit` - (provide (protect-out struct) struct/ctc) + (provide (protect-out struct)) (define-signature-form (struct stx) (parameterize ((error-syntax stx)) @@ -551,7 +551,7 @@ stx)))) (module+ compat ;; export only for compatibility with `mzlib/unit` - (provide (protect-out struct~s/ctc) struct~r/ctc) + (provide (protect-out struct~s/ctc)) (define-signature-form (struct~s/ctc stx) (do-struct~/ctc stx #t))) diff --git a/collects/scheme/unit.rkt b/collects/scheme/unit.rkt index f0e3e8ea43..567fcd0dbb 100644 --- a/collects/scheme/unit.rkt +++ b/collects/scheme/unit.rkt @@ -1,7 +1,7 @@ #lang racket/base -(require (except-in racket/unit struct/ctc) +(require racket/unit (submod racket/unit compat)) -(provide (all-from-out racket/unit) +(provide (except-out (all-from-out racket/unit) struct/ctc) (rename-out [struct~s struct] [struct~s/ctc struct/ctc])) diff --git a/collects/scribblings/scheme/scheme.scrbl b/collects/scribblings/scheme/scheme.scrbl index 97d756dcd9..59a8de5b42 100644 --- a/collects/scribblings/scheme/scheme.scrbl +++ b/collects/scribblings/scheme/scheme.scrbl @@ -6,14 +6,11 @@ (only-in scheme/class printable<%>) (only-in racket/class writable<%>) (only-in racket/base struct hash hasheq hasheqv in-directory local-require) - (only-in racket/unit struct/ctc) (only-in scheme/gui/base make-gui-namespace make-gui-empty-namespace) - (only-in mzlib/unit struct~s struct~s/ctc) scheme/gui/base scheme/sandbox)) @(define-syntax-rule (def-extras unit-struct - unit-struct/ctc make-base-namespace-id make-base-empty-namespace-id sandbox-namespace-specs-id @@ -22,13 +19,12 @@ pretty-print-id printable<%>-id) (begin - (require (for-label (only-in scheme struct struct/ctc) + (require (for-label (only-in scheme struct) (only-in racket/base make-base-namespace make-base-empty-namespace) (only-in racket/pretty pretty-print) racket/sandbox)) (define unit-struct (racket struct)) - (define unit-struct/ctc (racket struct/ctc)) (define make-base-namespace-id (racket make-base-namespace)) (define make-base-empty-namespace-id (racket make-base-empty-namespace)) (define sandbox-namespace-specs-id (racket sandbox-namespace-specs)) @@ -37,7 +33,6 @@ (define pretty-print-id (racket pretty-print)) (define printable<%>-id (racket printable<%>)))) @(def-extras unit-struct - unit-struct/ctc make-base-namespace-id make-base-empty-namespace-id sandbox-namespace-specs-id @@ -63,7 +58,7 @@ old name. A few @seclink["compat-exe"]{old executables} are also provided. @table-of-contents[] @compat-except[scheme racket]{, except based on @racketmodname[scheme/base] -instead of @racketmodname[racket/base], the @|unit-struct| and @|unit-struct/ctc| from +instead of @racketmodname[racket/base], the @|unit-struct| from @racketmodname[scheme/unit] is exported, @racketmodname[scheme/set] is not re-exported, @racketmodname[scheme/system] is not re-exported, @racket[pretty-print] is re-directed in as @@ -341,13 +336,7 @@ and @|make-module-evaluator-id| from @racketmodname[racket/sandbox].} @; @compat[scheme/trace racket/trace] @compat[scheme/trait racket/trait] @compat[scheme/udp racket/udp] - -@compat-except[scheme/unit racket/unit]{, except that @|unit-struct| -and @|unit-struct/ctc| are @racket[struct~s] and -@racket[struct~s/ctc] from @racketmodname[mzlib/unit] instead of -@racket[struct] from @racket[racket/base] and @racket[struct/ctc] from -@racketmodname[racket/unit]} - +@compat[scheme/unit racket/unit] @compat[scheme/unit-exptime racket/unit-exptime] @compat[scheme/unsafe/ops racket/unsafe/ops] @compat[scheme/vector racket/vector] From 6f2f7e7b88a0a8c504f9f33e0b40830ee00b3b2a Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 19 Jul 2012 12:49:13 -0400 Subject: [PATCH 544/746] Revert "Update props file for `racket/private/shared-body.rkt`" This reverts commit 68d550e2c39b592a235b8c04ce5a9417c6aa5c10. --- collects/meta/props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/meta/props b/collects/meta/props index 7d9a0daadd..577568a6b9 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -840,6 +840,7 @@ path/s is either such a string or a list of them. "collects/mzlib/match.rkt" responsible (samth) "collects/mzlib/pconvert.rkt" responsible (robby) "collects/mzlib/plt-match.rkt" responsible (samth) +"collects/mzlib/private/shared-body.rkt" drdr:command-line #f "collects/mzlib/shared.rkt" responsible (robby) "collects/mzlib/traceld.rkt" drdr:command-line #f "collects/mzscheme" responsible (mflatt) @@ -879,7 +880,6 @@ path/s is either such a string or a list of them. "collects/racket/place" responsible (tewk) "collects/racket/place/distributed/examples/hello-world.rkt" drdr:command-line #f "collects/racket/private/generic.rkt" responsible (asumu stamourv) -"collects/racket/private/shared-body.rkt" drdr:command-line #f "collects/racklog" responsible (jay) "collects/rackunit" responsible (jay noel ryanc) "collects/rackunit/gui.rkt" responsible (ryanc) From 88a2382ecda339efe0540b246fbe7e9d89bc6d1d Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 19 Jul 2012 12:49:21 -0400 Subject: [PATCH 545/746] Revert "Fix unit test broken by mzlib movement" This reverts commit 3158acd61d5b367544932b4d4df61c2fa4b91491. --- collects/tests/units/test-runtime.rktl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/tests/units/test-runtime.rktl b/collects/tests/units/test-runtime.rktl index ddfd57e27b..ef94d5abc8 100644 --- a/collects/tests/units/test-runtime.rktl +++ b/collects/tests/units/test-runtime.rktl @@ -1,5 +1,5 @@ (require "test-harness.rkt" - racket/private/unit-runtime) + mzlib/private/unit-runtime) ;; check-unit (test-runtime-error exn:fail:contract? "check-unit: not a unit" From 8992b82e046141ef6142c857ffcb587ae67e8fab Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Thu, 19 Jul 2012 12:51:14 -0400 Subject: [PATCH 546/746] Revert "Moved some mzlib library implementations to racket" This reverts commit 403aaac7d4c32132223f06e059df439cceda7a2e. Conflicts: collects/racket/place.rkt --- collects/compiler/embed-unit.rkt | 2 +- collects/file/gunzip.rkt | 933 +------ collects/file/gzip.rkt | 2244 +--------------- collects/file/zip.rkt | 271 +- collects/lang/private/teach-shared.rkt | 2 +- collects/mzlib/a-signature.rkt | 4 +- collects/mzlib/control.rkt | 268 +- collects/mzlib/date.rkt | 367 ++- collects/mzlib/deflate.rkt | 2244 +++++++++++++++- collects/mzlib/etc.rkt | 2 +- collects/mzlib/inflate.rkt | 931 ++++++- collects/mzlib/port.rkt | 1853 ++++++++++++- collects/{racket => mzlib}/private/info.rkt | 0 collects/{racket => mzlib}/private/port.rkt | 2 +- .../private/runtime-path-table.rkt | 0 .../{racket => mzlib}/private/shared-body.rkt | 0 .../{racket => mzlib}/private/streams.rkt | 2 +- .../this-expression-source-directory.rkt | 0 .../private/unit-compiletime.rkt | 0 .../private/unit-contract-syntax.rkt | 0 .../private/unit-contract.rkt | 0 .../private/unit-keywords.rkt | 0 .../private/unit-runtime.rkt | 0 .../{racket => mzlib}/private/unit-syntax.rkt | 0 .../{racket => mzlib}/private/unit-utils.rkt | 0 collects/mzlib/process.rkt | 207 +- collects/mzlib/runtime-path.rkt | 178 +- collects/mzlib/shared.rkt | 21 +- collects/mzlib/unit-exptime.rkt | 27 +- collects/mzlib/unit.rkt | 2326 +++++++++++++++- collects/mzlib/zip.rkt | 271 +- collects/racket/control.rkt | 270 +- collects/racket/date.rkt | 370 +-- collects/racket/place.rkt | 2 +- collects/racket/port.rkt | 1851 +------------ collects/racket/pretty.rkt | 2 +- collects/racket/runtime-path.rkt | 179 +- collects/racket/shared.rkt | 19 +- collects/racket/signature/lang.rkt | 4 +- collects/racket/system.rkt | 210 +- collects/racket/unit-exptime.rkt | 27 +- collects/racket/unit.rkt | 2345 +---------------- collects/scheme/unit.rkt | 14 +- collects/scribblings/reference/units.scrbl | 4 +- collects/tests/units/test-unit.rktl | 4 +- 45 files changed, 8685 insertions(+), 8771 deletions(-) rename collects/{racket => mzlib}/private/info.rkt (100%) rename collects/{racket => mzlib}/private/port.rkt (98%) rename collects/{racket => mzlib}/private/runtime-path-table.rkt (100%) rename collects/{racket => mzlib}/private/shared-body.rkt (100%) rename collects/{racket => mzlib}/private/streams.rkt (98%) rename collects/{racket => mzlib}/private/this-expression-source-directory.rkt (100%) rename collects/{racket => mzlib}/private/unit-compiletime.rkt (100%) rename collects/{racket => mzlib}/private/unit-contract-syntax.rkt (100%) rename collects/{racket => mzlib}/private/unit-contract.rkt (100%) rename collects/{racket => mzlib}/private/unit-keywords.rkt (100%) rename collects/{racket => mzlib}/private/unit-runtime.rkt (100%) rename collects/{racket => mzlib}/private/unit-syntax.rkt (100%) rename collects/{racket => mzlib}/private/unit-utils.rkt (100%) diff --git a/collects/compiler/embed-unit.rkt b/collects/compiler/embed-unit.rkt index b8f4a26499..28181c1c53 100644 --- a/collects/compiler/embed-unit.rkt +++ b/collects/compiler/embed-unit.rkt @@ -966,7 +966,7 @@ (if (null? runtimes) #f (let* ([table-sym (module-path-index-resolve - (module-path-index-join '(lib "runtime-path-table.rkt" "racket" "private") + (module-path-index-join '(lib "runtime-path-table.rkt" "mzlib" "private") #f))] [table-path (resolved-module-path-name table-sym)]) (assoc (normalize table-path) l)))]) diff --git a/collects/file/gunzip.rkt b/collects/file/gunzip.rkt index 5fa4b7aea8..4a4ed855c6 100644 --- a/collects/file/gunzip.rkt +++ b/collects/file/gunzip.rkt @@ -1,931 +1,4 @@ -#lang racket/base -(require (for-syntax racket/base)) - - (provide inflate - gunzip-through-ports - gunzip) - -#| - -/* inflate.c -- Not copyrighted 1992 by Mark Adler - version c10p1, 10 January 1993 */ -; Taken from the gzip source distribution -; Translated directly from C (obviously) by Matthew, April 1997 - -/* You can do whatever you like with this source file, though I would - prefer that if you modify it and redistribute it that you include - comments to that effect with your name and the date. Thank you. - [The history has been moved to the file ChangeLog.] - ; ChangeLog is distributed with the gzip source. - */ - -/* - Inflate deflated (PKZIP's method 8 compressed) data. The compression - method searches for as much of the current string of bytes (up to a - length of 258) in the previous 32K bytes. If it doesn't find any - matches (of at least length 3), it codes the next byte. Otherwise, it - codes the length of the matched string and its distance backwards from - the current position. There is a single Huffman code that codes both - single bytes (called "literals") and match lengths. A second Huffman - code codes the distance information, which follows a length code. Each - length or distance code actually represents a base value and a number - of "extra" (sometimes zero) bits to get to add to the base value. At - the end of each deflated block is a special end-of-block (EOB) literal/ - length code. The decoding process is basically: get a literal/length - code; if EOB then done; if a literal, emit the decoded byte; if a - length then get the distance and emit the referred-to bytes from the - sliding window of previously emitted data. - - There are (currently) three kinds of inflate blocks: stored, fixed, and - dynamic. The compressor deals with some chunk of data at a time, and - decides which method to use on a chunk-by-chunk basis. A chunk might - typically be 32K or 64K. If the chunk is uncompressible, then the - "stored" method is used. In this case, the bytes are simply stored as - is, eight bits per byte, with none of the above coding. The bytes are - preceded by a count, since there is no longer an EOB code. - - If the data is compressible, then either the fixed or dynamic methods - are used. In the dynamic method, the compressed data is preceded by - an encoding of the literal/length and distance Huffman codes that are - to be used to decode this block. The representation is itself Huffman - coded, and so is preceded by a description of that code. These code - descriptions take up a little space, and so for small blocks, there is - a predefined set of codes, called the fixed codes. The fixed method is - used if the block codes up smaller that way (usually for quite small - chunks), otherwise the dynamic method is used. In the latter case, the - codes are customized to the probabilities in the current block, and so - can code it much better than the pre-determined fixed codes. - - The Huffman codes themselves are decoded using a mutli-level table - lookup, in order to maximize the speed of decoding plus the speed of - building the decoding tables. See the comments below that precede the - lbits and dbits tuning parameters. - */ - - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarly, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - -|# - -#| -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). - Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 - means that v is a literal, 16 < e < 32 means that v is a pointer to - the next table, which codes e - 16 bits, and lastly e == 99 indicates - an unused code. If a code with e == 99 is looked up, this implies an - error in the data. */ -|# - - (define-struct huft (e b v) #:mutable) - - (define (huft-copy dest src) - (set-huft-e! dest (huft-e src)) - (set-huft-b! dest (huft-b src)) - (set-huft-v! dest (huft-v src))) - - (define (step start < end add1 f) - (let loop ([i start]) - (when (< i end) - (f i) - (loop (add1 i))))) - - (define (subvector v offset) - (let* ([len (- (vector-length v) offset)] - [new (make-vector len)]) - (step 0 < len add1 - (lambda (i) - (vector-set! new i (vector-ref v (+ i offset))))) - new)) - - (define (build-vector n p) - (let ([v (make-vector n)]) - (step 0 < n add1 (lambda (i) (vector-set! v i (p i)))) - v)) - - ;; We know that inflating will be a bottleneck, so we might as - ;; well help out the compiler... - (define-syntax define-const - (syntax-rules () - [(_ id v) (define-syntax id (make-const #'v))])) - (define-for-syntax (make-const val) - (make-set!-transformer - (lambda (stx) - (syntax-case stx (set!) - [(set! id . _) (raise-syntax-error (syntax-e #'id) - "cannot assign constant" - stx)] - [(id . rest) (quasisyntax/loc stx (#,val . rest))] - [id val])))) - -#| -/* The inflate algorithm uses a sliding 32K byte window on the uncompressed - stream to find repeated byte strings. This is implemented here as a - circular buffer. The index is updated simply by incrementing and then - and'ing with 0x7fff (32K-1). */ -|# - - (define-const WSIZE 32768) - - (define border - (vector - 16 17 18 0 8 7 9 6 10 5 11 4 12 3 13 2 14 1 15)) - - (define cplens - (vector - 3 4 5 6 7 8 9 10 11 13 15 17 19 23 27 31 - 35 43 51 59 67 83 99 115 131 163 195 227 258 0 0)) - ; /* note: see note #13 above about the 258 in this list. */ - (define cplext - (vector - 0 0 0 0 0 0 0 0 1 1 1 1 2 2 2 2 - 3 3 3 3 4 4 4 4 5 5 5 5 0 99 99)) ; /* 99==invalid */ - (define cpdist - (vector - 1 2 3 4 5 7 9 13 17 25 33 49 65 97 129 193 - 257 385 513 769 1025 1537 2049 3073 4097 6145 - 8193 12289 16385 24577)) - (define cpdext - (vector - 0 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6 - 7 7 8 8 9 9 10 10 11 11 - 12 12 13 13)) - - (define mask_bits - (vector - #x0000 - #x0001 #x0003 #x0007 #x000f #x001f #x003f #x007f #x00ff - #x01ff #x03ff #x07ff #x0fff #x1fff #x3fff #x7fff #xffff)) - - (define-const lbits 9) ; /* bits in base literal/length lookup table */ - (define-const dbits 6) ; /* bits in base distance lookup table */ - - - ; /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ - (define-const BMAX 16) ; /* maximum bit length of any code (16 for explode) */ - (define-const N_MAX 288) ; /* maximum number of codes in any set */ - -(define (inflate input-port output-port) - - (define slide (make-bytes WSIZE)) - (define wp 0) - - (define (flush-output len) - ; write out the data - (write-bytes slide output-port 0 len)) - - (define (check-flush) - (when (= wp WSIZE) - (flush-output WSIZE) - (set! wp 0))) - -#| -/* Macros for inflate() bit peeking and grabbing. - The usage is: - - NEEDBITS(j) - x = b & mask_bits[j]; - DUMPBITS(j) - - where NEEDBITS makes sure that b has at least j bits in it, and - DUMPBITS removes the bits from b. The macros use the variable k - for the number of bits in b. Normally, b and k are register - variables for speed, and are initialized at the beginning of a - routine that uses these macros from a global bit buffer and count. - - If we assume that EOB will be the longest code, then we will never - ask for bits with NEEDBITS that are beyond the end of the stream. - So, NEEDBITS should not read any more bytes than are needed to - meet the request. Then no bytes need to be "returned" to the buffer - at the end of the last block. - - However, this assumption is not true for fixed blocks--the EOB code - is 7 bits, but the other literal/length codes can be 8 or 9 bits. - (The EOB code is shorter than other codes because fixed blocks are - generally short. So, while a block always has an EOB, many other - literal/length codes have a significantly lower probability of - showing up at all.) However, by making the first table have a - lookup of seven bits, the EOB code will be found in that first - lookup, and so will not require that too many bits be pulled from - the stream. - */ -|# - - ;; We can't read the bytes outright, because we may - ;; look ahead. Assume that we need no more than 32 bytes - ;; look ahead, and peek in 4096-byte blocks. - (define MAX-LOOKAHEAD 32) - (define BUFFER-SIZE 4096) - (define buffer (make-bytes BUFFER-SIZE)) - (define buf-max 0) ; number of bytes in buffer - (define buf-pos 0) ; index into buffer = number of used peeked bytes - - (define bb 0) ; /* bit buffer */ - (define bk 0) ; /* bits in bit buffer */ - - (define (NEEDBITS n) - (when (< bk n) - (READBITS n))) - (define (READBITS n) - (if (= buf-pos buf-max) - (begin - (when (positive? buf-max) - (read-bytes! buffer input-port 0 (- buf-max MAX-LOOKAHEAD)) - ; (bytes-copy! buffer 0 buffer (- buf-max MAX-LOOKAHEAD) buf-max) - (set! buf-pos MAX-LOOKAHEAD)) - (let ([got (peek-bytes-avail! buffer buf-pos #f input-port buf-pos BUFFER-SIZE)]) - (if (eof-object? got) - (error 'inflate "unexpected end of file") - (set! buf-max (+ buf-pos got)))) - (READBITS n)) - (let ([v (bytes-ref buffer buf-pos)]) - (set! buf-pos (add1 buf-pos)) - (set! bb (+ bb (arithmetic-shift v bk))) - (set! bk (+ bk 8)) - (NEEDBITS n)))) - (define (DUMPBITS n) - (set! bb (arithmetic-shift bb (- n))) - (set! bk (- bk n))) - - (define (GETBITS n) - (NEEDBITS n) - (begin0 - bb - (DUMPBITS n))) - -#| -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ -|# - - (define (huft_build - b ; int vector /* code lengths in bits (all assumed <= BMAX) */ - n ; /* number of codes (assumed <= N_MAX) */ - s ; /* number of simple-valued codes (0..s-1) */ - d ; int vector /* list of base values for non-simple codes */ - e ; int vector /* list of extra bits for non-simple codes */ - m ; int /* maximum lookup bits, returns actual */ - incomp-ok?) - ; return: new-t new-m ok? - -#| -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return zero on success, one if - the given code set is incomplete (the tables are still built in this - case), two if the input is invalid (all zero length codes or an - oversubscribed set of lengths), and three if not enough memory. */ -|# - (define c (make-vector (add1 BMAX) 0)) - (define x (make-vector (add1 BMAX))) - (define v (make-vector N_MAX)) - - (define final-y 0) - (define t-result #f) - - ; (printf "n: ~s\n" n) - - (let/ec return - -#| -(if (= n 270) - (step 0 < n add1 - (lambda (i) (printf "b[~a] = ~a\n" i (vector-ref b i))))) -|# - - (step 0 < n add1 - (lambda (i) - (let ([pos (vector-ref b i)]) - (vector-set! c pos (add1 (vector-ref c pos)))))) - - (when (= n (vector-ref c 0)) - ; (printf "zero\n") - (return #f 0 #t)) - -#| -(when (= n 270) - (step 0 <= BMAX add1 - (lambda (i) - (printf "c[~s]: ~s\n" i (vector-ref c i))))) -|# - - ; /* Find minimum and maximum length, bound m-result by those */ - (let* ([j ; min-code-length - (let loop ([j 1]) - (cond - [(> j BMAX) j] - [(positive? (vector-ref c j)) j] - [else (loop (add1 j))]))] - [k j] - [i ; max-code-length - (let loop ([i BMAX]) - (cond - [(zero? i) 0] - [(positive? (vector-ref c i)) i] - [else (loop (sub1 i))]))] - [g i] - [l (min (max m j) i)] - [m-result l]) - ; (printf "min: ~s max: ~s\n" k g) - ; /* Adjust last length count to fill out codes, if needed */ - (let-values ([(y j) - (let loop ([y (arithmetic-shift 1 j)][j j]) - (if (>= j i) - (values y j) - (let ([new-y (- y (vector-ref c j))]) - (if (negative? new-y) - (begin - (error 'inflate - "bad input: more codes than bits") - (return null m-result #f)) - (loop (* new-y 2) (add1 j))))))]) - ; (printf "loop y: ~s\n" y) - (let ([y (- y (vector-ref c i))]) - (when (negative? y) - (error 'inflate "bad input: more codes than bits") - (return #f m-result #f)) - ; (printf "set c[~s] ~s + ~s\n" i (vector-ref c i) y) - (vector-set! c i (+ (vector-ref c i) y)) - (set! final-y y))) - ; /* Generate starting offsets into the value table for each length */ - (vector-set! x 1 0) - (let* ([j (let loop ([i (sub1 i)][x-pos 2][c-pos 1][j 0]) - (if (zero? i) - j - (let ([v (vector-ref c c-pos)]) - (vector-set! x x-pos (+ j v)) - (loop (sub1 i) (add1 x-pos) (add1 c-pos) (+ j v)))))]) - ; /* Make a table of values in order of bit lengths */ - (let loop ([i 0][b-pos 0]) - (let ([j (vector-ref b b-pos)]) - (unless (zero? j) - (let ([xj (vector-ref x j)]) - (vector-set! x j (add1 xj)) - (vector-set! v xj i))) - (let ([new-i (add1 i)]) - (when (< new-i n) - (loop new-i (add1 b-pos)))))) - - ; /* Generate the Huffman codes and for each, make the table entries */ - (vector-set! x 0 0) ; /* first Huffman code is zero */ - (let ([v-pos 0] ; /* grab values in bit order */ - [i 0] ; /* the Huffman code of length k bits for value *p */ - [h -1] ; /* no tables yet--level -1 */ - [w (- l)] ; /* bits decoded == (l * h) */ - [u (make-vector BMAX)] ; /* table stack */ - [q null] ; /* points to current table */ - [z 0] ; /* number of entries in current table */ - [r (make-huft 0 0 0)]) ; /* table entry for structure assignment */ - ; /* go through the bit lengths (k already is bits in shortest code) */ - (let k-loop ([k k]) - ; (printf "k: ~s\n" k) - (when (<= k g) - (let ([a (vector-ref c k)]) - (let a-loop ([a (sub1 a)]) - (unless (negative? a) - ; (printf "a: ~s\n" a) - ; /* here i is the Huffman code of length k bits for value *p */ - ; /* make tables up to required level */ - (let kwl-loop () - (when (> k (+ w l)) - (set! h (add1 h)) - (set! w (+ w l)) ; /* previous table always l bits */ - - ; /* compute minimum size table less than or equal to l bits */ - (set! z (min (- g w) l)) ; /* upper limit on table size */ - - ; (printf "z: ~s k: ~s w: ~s\n" z k w) - - (let* ([j (- k w)] - [f (arithmetic-shift 1 j)]) - (when (> f (add1 a)) ; /* try a k-w bit table */ - ; /* too few codes for k-w bit table */ - (set! f (- f a 1)) ; /* deduct codes from patterns left */ - ; /* try smaller tables up to z bits */ - (let loop ([c-pos k]) - (set! j (add1 j)) - (when (< j z) - (set! f (* f 2)) - (let* ([c-pos (add1 c-pos)] - [cv (vector-ref c c-pos)]) - (if (<= f cv) - (void) ; /* enough codes to use up j bits */ - (begin - (set! f (- f cv)) ; /* else deduct codes from patterns */ - (loop c-pos))))))) - (set! z (arithmetic-shift 1 j)) ; /* table entries for j-bit table */ - - ; /* allocate and link in new table */ - ; (printf "alloc: ~a\n" z) - (set! q (build-vector z (lambda (i) (make-huft 0 0 0)))) - - (when (not t-result) - (set! t-result q)) - - (vector-set! u h q) - - ; /* connect to last table, if there is one */ - (unless (zero? h) - (vector-set! x h i) ; /* save pattern for backing up */ - (set-huft-b! r l) ; /* bits to dump before this table */ - (set-huft-e! r (+ j 16)); /* bits in this table */ - (set-huft-v! r q) ; /* pointer to this table */ - (set! j (arithmetic-shift i (- l w))) - ; /* connect to last table: */ - (huft-copy (vector-ref (vector-ref u (sub1 h)) j) r))) - - (kwl-loop))) - - (set-huft-b! r (- k w)) ; cast uch (- k w) if needed - (if (>= v-pos n) - (set-huft-e! r 99) ; /* out of values--invalid code */ - (let ([vv (vector-ref v v-pos)]) - ; (printf "*p: ~s s: ~s\n" vv s) - (if (< vv s) - (begin - (set-huft-e! r (if (< vv 256) 16 15)) ; /* 256 is end-of-block code */ - (set-huft-v! r vv)) ; /* simple code is just the value */ - (begin - (set-huft-e! r (vector-ref e (- vv s))) ; /* non-simple--look up in lists */ - (set-huft-v! r (vector-ref d (- vv s))))) - (set! v-pos (add1 v-pos)))) - ; /* fill code-like entries with r */ - ; (printf "i: ~s w: ~s k: ~s\n" i w k) - (let ([f (arithmetic-shift 1 (- k w))]) ; /* i repeats in table every f entries */ - (let loop ([j (arithmetic-shift i (- w))]) - (when (< j z) - (huft-copy (vector-ref q j) r) - (loop (+ j f))))) - ; /* backwards increment the k-bit code i */ - (let loop ([j (arithmetic-shift 1 (sub1 k))]) - (if (positive? (bitwise-and i j)) - (begin - (set! i (bitwise-xor i j)) - (loop (arithmetic-shift j -1))) - (set! i (bitwise-xor i j)))) - ; /* backup over finished tables */ - (let loop () - (unless (= (vector-ref x h) (bitwise-and i (sub1 (arithmetic-shift 1 w)))) - (set! h (sub1 h)) ; /* don't need to update q */ - (set! w (- w l)) - (loop))) - - (a-loop (sub1 a)))) - (k-loop (add1 k))))) - - ; /* Return #f as third if we were given an incomplete table */ - ; (printf "done: ~s ~s\n" final-y g) - (let ([ok? (or incomp-ok? - (not (and (not (zero? final-y)) - (not (= g 1)))))]) - (unless ok? - (error 'inflate "incomplete table")) - (values t-result m-result ok?))))))) - - (define (inflate_codes - tl ; vector of hufts ; /* literal/length tables */ - td ; vector of hufts ; /* distance decoder tables */ - bl ; /* number of bits decoded by tl */ - bd) ; /* number of bits decoded by td[] */ - ; /* inflate (decompress) the codes in a deflated (compressed) block. - ; Return an error code or zero if it all goes ok. */ - - ; /* inflate the coded data */ - - ; /* precompute masks for speed */ - (define ml (vector-ref mask_bits bl)) - (define md (vector-ref mask_bits bd)) - (define t (void)) - (define e 0) - (define n 0) - (define d 0) - - (let/ec return - - (define (jump-to-next) - (let loop () - (when (= e 99) - (error 'inflate "bad inflate code") - (return #f)) - (DUMPBITS (huft-b t)) - (set! e (- e 16)) - (NEEDBITS e) - (set! t (vector-ref (huft-v t) (bitwise-and bb (vector-ref mask_bits e)))) - (set! e (huft-e t)) - (when (> e 16) - (loop)))) - - (let loop () ; /* do until end of block */ - (NEEDBITS bl) - (set! t (vector-ref tl (bitwise-and bb ml))) - ; (printf "t->e: ~s t->b: ~s\n" (huft-e t) (huft-b t)) - (set! e (huft-e t)) - (when (> e 16) - (jump-to-next)) - (DUMPBITS (huft-b t)) - ; (printf "e: ~s\n" e) - (if (= e 16) ; /* then it's a literal */ - (begin - (bytes-set! slide wp (huft-v t)) - (set! wp (add1 wp)) - (check-flush)) - (begin ; /* it's an EOB or a length */ - ; /* exit if end of block */ - (when (= e 15) - (return #t)) - - ; /* get length of block to copy */ - (NEEDBITS e) - (set! n (+ (huft-v t) (bitwise-and bb (vector-ref mask_bits e)))) - (DUMPBITS e) - ; (printf "n: ~s bb: ~s md: ~s\n" n bb md) - - ; /* decode distance of block to copy */ - (NEEDBITS bd) - (set! t (vector-ref td (bitwise-and bb md))) - ; (printf "t->e: ~s t->b: ~s\n" (huft-e t) (huft-b t)) - (set! e (huft-e t)) - ; (printf "e: ~s\n" e) - (when (> e 16) - (jump-to-next)) - (DUMPBITS (huft-b t)) - ; (printf "e: ~s\n" e) - - (NEEDBITS e) - (set! d (modulo (- wp (huft-v t) (bitwise-and bb (vector-ref mask_bits e))) WSIZE)) - (DUMPBITS e) - - ; (printf "wp: ~s t->v: ~s d: ~s\n" wp (huft-v t) d) - - ; /* do the copy */ - (let loop () - (set! d (bitwise-and d (sub1 WSIZE))) - (set! e (min n (- WSIZE (max d wp)))) - (set! n (- n e)) - (let loop () - (bytes-set! slide wp (bytes-ref slide d)) - (set! wp (add1 wp)) - (set! d (add1 d)) - (set! e (sub1 e)) - (unless (zero? e) - (loop))) - (check-flush) - (unless (zero? n) - (loop))))) - (loop)))) - - (define (inflate_stored) - ; /* "decompress" an inflated type 0 (stored) block. */ - - (let/ec return - - ; /* go to byte boundary */ - (DUMPBITS (bitwise-and bk 7)) - - ; /* get the length and its complement */ - (NEEDBITS 16) - (let ([n (bitwise-and bb #xffff)]) - (DUMPBITS 16) - (NEEDBITS 16) - (unless (= n (bitwise-and (bitwise-not bb) #xffff)) - (error 'inflate "error in compressed data") - (return #f)) ; /* error in compressed data */ - (DUMPBITS 16) - - ; /* read and output the compressed data */ - (let loop ([n n]) - (when (positive? n) - (NEEDBITS 8) - (bytes-set! slide wp (bitwise-and bb #xff)) - (set! wp (add1 wp)) - (check-flush) - (DUMPBITS 8) - (loop (sub1 n)))) - - #t))) - - (define (inflate_fixed) - ; /* decompress an inflated type 1 (fixed Huffman codes) block. We should - ; either replace this with a custom decoder, or at least precompute the - ; Huffman tables. */ - - (define l (make-vector 288)) - - (step 0 < 144 add1 (lambda (i) (vector-set! l i 8))) - (step 144 < 256 add1 (lambda (i) (vector-set! l i 9))) - (step 256 < 280 add1 (lambda (i) (vector-set! l i 7))) - (step 280 < 288 add1 (lambda (i) (vector-set! l i 8))) - - (let-values ([(tl bl ok?) - (huft_build l 288 257 cplens cplext 7 #f)]) - - (if (not ok?) - #f - (begin - (step 0 < 30 add1 (lambda (i) (vector-set! l i 5))) - (let-values ([(td bd ok?) - (huft_build l 30 0 cpdist cpdext 5 #t)]) - (if (not ok?) - #f - ; /* decompress until an end-of-block code */ - (inflate_codes tl td bl bd))))))) - - (define (inflate_dynamic) - ; /* decompress an inflated type 2 (dynamic Huffman codes) block. */ - - (begin ; let/ec return - - ; /* read in table lengths */ - ; (define junk1 (begin (NEEDBITS 5) (printf "~s ~s\n" bb bk))) - (define nl (+ 257 (bitwise-and (GETBITS 5) #x1f))) - ; (define junk2 (begin (NEEDBITS 5) (printf "~s ~s\n" bb bk))) - (define nd (+ 1 (bitwise-and (GETBITS 5) #x1f))) - ; (define junk3 (begin (NEEDBITS 4) (printf "~s ~s\n" bb bk))) - (define nb (+ 4 (bitwise-and (GETBITS 4) #xf))) - - ; (define junk8 (printf "~s ~s ~s\n" nl nd nb)) - - (define ll (make-vector (+ 286 30))) - (define i 0) - (define l 0) - - (if (or (> nl 286) (> nd 30)) - (begin - (error 'inflate "bad lengths") - #f) ; /* bad lengths */ - (begin - ; /* read in bit-length-code lengths */ - (step 0 < nb add1 - (lambda (j) - (vector-set! ll (vector-ref border j) (bitwise-and (GETBITS 3) 7)))) - (step nb < 19 add1 - (lambda (j) - (vector-set! ll (vector-ref border j) 0))) - - ; /* build decoding table for trees--single level, 7 bit lookup */ - (let-values ([(tl bl ok?) - (huft_build ll 19 19 null null 7 #f)]) - (if (not ok?) - #f - (begin - ; /* read in literal and distance code lengths */ - (let ([n (+ nl nd)] - [m (vector-ref mask_bits bl)]) - ; (printf "bl: ~s\n" bl) - (set! i 0) - (set! l 0) - (let loop () - (when (< i n) - (NEEDBITS bl) - (let* ([pos (bitwise-and bb m)] - [td (vector-ref tl pos)] - [dmp (huft-b td)] - [j (huft-v td)] - [set-lit - (lambda (j l) - (when (> (+ i j) n) - (error 'inflate "bad hop") - #;(return #f)) - (let loop ([j j]) - (unless (zero? j) - (vector-set! ll i l) - (set! i (add1 i)) - (loop (sub1 j)))))]) - (DUMPBITS dmp) - ; (printf "pos: ~s j: ~s l: ~s i: ~s\n" pos j l i) - (cond - [(< j 16) ; /* length of code in bits (0..15) */ - (vector-set! ll i j) - (set! l j) ; /* save last length in l */ - (set! i (add1 i))] - [(= j 16) ; /* repeat last length 3 to 6 times */ - (let ([j (+ 3 (bitwise-and (GETBITS 2) 3))]) - (set-lit j l))] - [(= j 17) ; /* 3 to 10 zero length codes */ - (let ([j (+ 3 (bitwise-and (GETBITS 3) 7))]) - (set-lit j 0) - (set! l 0))] - [else ; /* j == 18: 11 to 138 zero length codes */ - (let ([j (+ 11 (bitwise-and (GETBITS 7) #x7f))]) - (set-lit j 0) - (set! l 0))])) - (loop))) - - ; /* build the decoding tables for literal/length and distance codes */ - (let-values ([(tl bl ok?) - (huft_build ll nl 257 cplens cplext lbits #f)]) - (if (not ok?) - (begin - (error 'inflate "incomplete code set") - #f) ; /* incomplete code set */ - (let-values ([(td bd ok?) - (huft_build (subvector ll nl) nd 0 cpdist cpdext dbits #f)]) - (if (not ok?) - (begin - (error 'inflate "incomplete code set") - #f) ; /* incomplete code set */ - ; /* decompress until an end-of-block code */ - (inflate_codes tl td bl bd))))))))))))) - - (define (inflate_block) - ; return values: /* last block flag */ ok? - ; /* decompress an inflated block */ - - (define e-result (bitwise-and (GETBITS 1) 1)) - - ; /* read in block type */ - (define t (bitwise-and (GETBITS 2) 3)) - - (values e-result - (case t - [(2) (inflate_dynamic)] - [(0) (inflate_stored)] - [(1) (inflate_fixed)] - [else (error 'inflate "unknown inflate type") - #f]))) - - ;;;;;;;;;;;;;;;;;;;;;;;; - ; inflate starts here - ;;;;;;;;;;;;;;;;;;;;;;;; - - ; /* decompress an inflated entry */ - ; /* initialize window, bit buffer */ - (set! wp 0) - (set! bk 0) - (set! bb 0) - - - ; /* decompress until the last block */ - (let loop () - (let-values ([(e ok?) (inflate_block)]) - (if ok? - (if (zero? e) - (loop) - (begin - ; /* Undo too much lookahead. The next read will be byte aligned so we - ; * can discard unused bits in the last meaningful byte. - ; */ - (let loop () - (when (>= bk 8) - (set! bk (- bk 8)) - (set! buf-pos (sub1 buf-pos)) - (loop))) - (read-bytes! buffer input-port 0 buf-pos) - (flush-output wp) - #t = (void))) - #f)))) - - (define make-small-endian - (case-lambda - [(a b) (+ a (arithmetic-shift b 8))] - [(a b c d) (+ a - (arithmetic-shift b 8) - (arithmetic-shift c 16) - (arithmetic-shift d 24))])) - - (define (do-gunzip in out name-filter) - (let ([header1 (read-byte in)] - [header2 (read-byte in)]) - (unless (and (= header1 #o037) (= header2 #o213)) - (error 'gnu-unzip "bad header"))) - (let ([compression-type (read-byte in)]) - (unless (= compression-type #o010) - (error 'gnu-unzip "unknown compression type"))) - (let* ([flags (read-byte in)] - [ascii? (positive? (bitwise-and flags #b1))] - [continuation? (positive? (bitwise-and flags #b10))] - [has-extra-field? (positive? (bitwise-and flags #b100))] - [has-original-filename? (positive? (bitwise-and flags #b1000))] - [has-comment? (positive? (bitwise-and flags #b10000))] - [encrypted? (positive? (bitwise-and flags #b100000))]) - (when encrypted? - (error 'gnu-unzip "cannot unzip encrypted file")) - (when continuation? - (error 'gnu-unzip "cannot handle multi-part files")) - (let ([unix-mod-time (make-small-endian (read-byte in) (read-byte in) - (read-byte in) (read-byte in))] - [extra-flags (read-byte in)] - [source-os (read-byte in)]) - (when continuation? - (let ([part-number (make-small-endian (read-byte in) (read-byte in))]) - 'ok)) - (when has-extra-field? - (let ([len (make-small-endian (read-byte in) (read-byte in))]) - (let loop ([len len]) - (unless (zero? len) - (read-byte in) - (loop (sub1 len)))))) - (let* ([read-null-term-string - (lambda () - (let loop ([s null]) - (let ([r (read-byte in)]) - (if (zero? r) - (list->bytes (reverse s)) - (loop (cons r s))))))] - [original-filename (and has-original-filename? - (read-null-term-string))] - [comment (and has-comment? (read-null-term-string))]) - (when encrypted? - (let loop ([n 12]) - (unless (zero? n) - (read-byte in) - (loop (sub1 n))))) - - (let-values ([(out close?) (if out - (values out #f) - (let-values ([(fn orig?) - (if original-filename - (values (bytes->path original-filename) #t) - (values "unzipped" #f))]) - (values (open-output-file (name-filter fn orig?) #:exists 'truncate) - #t)))]) - (dynamic-wind - void - (lambda () (begin0 (inflate in out) - (read-bytes 8 in))) ; read CRC32 and ISIZE - (lambda () (when close? (close-output-port out))))))))) - - (define (gunzip-through-ports in out) - (do-gunzip in out void)) - - (define gunzip - (case-lambda - [(src) (gunzip src (lambda (name from-file?) name))] - [(src name-filter) - (let ([in (open-input-file src #:mode 'binary)]) - (dynamic-wind - void - (lambda () (do-gunzip in #f name-filter)) - (lambda () (close-input-port in))))])) +#lang scheme/base +(require mzlib/inflate) +(provide (all-from-out mzlib/inflate)) diff --git a/collects/file/gzip.rkt b/collects/file/gzip.rkt index 757c426d77..3009ceb9c7 100644 --- a/collects/file/gzip.rkt +++ b/collects/file/gzip.rkt @@ -1,2242 +1,4 @@ -#| -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1992-1993 Jean-loup Gailly - */ -|# -;; Taken from the gzip source distribution -;; Translated directly from C (obviously) by Matthew, July 2000 +#lang scheme/base -;; *** The original version that this code was taken from was -;; distributed with a GPL license, but later the code (later version of -;; it) was also included in zlib, which is distributed with an -;; LGPL-compatible license. I (Eli Barzilay) have tried to contact the -;; author, but no reply yet. - -(module deflate mzscheme - - (provide deflate gzip-through-ports gzip) - - (require mzlib/unit200) - - (define (vector-ref* v i) - (let ([r (vector-ref v i)]) - (if (<= 0 r 255) r (error 'vector-ref "BOOM: ~s" r)))) - - (define (vector-set!* v i n) - (if (<= 0 n 255) (vector-set! v i n) (error 'vector-ref "BOOM!: ~s" n))) - - (define-syntax INSERT_STRING - (syntax-rules () - [(_ s match_head UPDATE_HASH window-vec head-vec prev-vec ins_h) - (begin (UPDATE_HASH (bytes-ref window-vec (+ s MIN_MATCH-1))) - (let ([mh (vector-ref head-vec (+ ins_h head-vec-delta))]) - (set! match_head mh) - (vector-set! prev-vec (bitwise-and s WMASK) mh)) - (vector-set! head-vec (+ head-vec-delta ins_h) s))])) - - (define-syntax pqremove - (syntax-rules () - [(_ tree top heap heap_len SMALLEST) - (begin (set! top (vector-ref heap SMALLEST)) - (vector-set! heap SMALLEST (vector-ref heap heap_len)) - (set! heap_len (sub1 heap_len)) - (pqdownheap tree SMALLEST))])) - - (define-syntax DEBUG (lambda (stx) #'(void))) - - (define-syntax Assert (lambda (stx) #'(void))) - - (define-syntax for - (syntax-rules (:= then do) - [(for n := start < end do body ...) - (for n := start then add1 < end do body ...)] - [(for n := start then next < end do body ...) - (let ([endval end]) - (let loop ([n start]) - (when (< n endval) body ... (loop (next n)))))])) - - (define-struct gzbytes (bytes offset)) - (define (gzbytes-ref v o) - (bytes-ref (gzbytes-bytes v) (+ (gzbytes-offset v) o))) - (define (gzbytes-set! v o x) - (bytes-set! (gzbytes-bytes v) (+ (gzbytes-offset v) o) x)) - (define (gzbytes+ v o) - (make-gzbytes (gzbytes-bytes v) (+ (gzbytes-offset v) o))) - - (define (Trace stderr str . args) - (apply eprintf str args)) - (define Tracevv Trace) - (define Tracev Trace) - (define (Tracec test . args) - (when test (apply Trace args))) - (define Tracecv Tracec) - (define stderr 'sdterr) - -#| -/* - * PURPOSE - * - * Identify new text as repetitions of old text within a fixed- - * length sliding window trailing behind the new text. - * - * DISCUSSION - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many info-zippers for bug reports and testing. - * - * REFERENCES - * - * APPNOTE.TXT documentation file in PKZIP 1.93a distribution. - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - * INTERFACE - * - * void lm_init (int pack_level, ush *flags) - * Initialize the "longest match" routines for a new file - * - * ulg deflate (void) - * Processes a new input file and return its compressed length. Sets - * the compressed length, crc, deflate flags and internal file - * attributes. - */ - -|# - - (define LEVEL 6) - - (define OUTBUFSIZ 16384);; /* output buffer size */ - (define INBUFSIZ #x8000);; /* input buffer size */ - (define INBUF_EXTRA 64) - - (define WSIZE #x8000) ;; /* window size--must be a power of two, and */ - ;; /* at least 32K for zip's deflate method */ - - (define MIN_MATCH 3) - (define MIN_MATCH-1 (- MIN_MATCH 1)) - (define MAX_MATCH 258) - ;; /* The minimum and maximum match lengths */ - - (define MIN_LOOKAHEAD (+ MAX_MATCH MIN_MATCH 1)) - ;; /* Minimum amount of lookahead, except at the end of the input file. - ;; * See for comments about the MIN_MATCH+1. - ;; */ - - (define MAX_DIST (- WSIZE MIN_LOOKAHEAD)) - ;; /* In order to simplify the code, particularly on 16 bit machines, match - ;; * distances are limited to MAX_DIST instead of WSIZE. - ;; */ - - (define HASH_BITS 15) - (define BITS 16) - - (define << arithmetic-shift) - (define (>> x y) (arithmetic-shift x (- y))) - (define EOF-const -1) - - ;; /* To save space (see unlzw.c), we overlay prev+head with tab_prefix and - ;; * window with tab_suffix. Check that we can do this: - ;; */ - (Assert - (when (> (<< WSIZE 1) (<< 1 BITS)) - (error "cannot overlay window with tab_suffix and prev with tab_prefix0"))) - (Assert - (when (> HASH_BITS (- BITS 1)) - (error "cannot overlay head with tab_prefix1"))) - - (define HASH_SIZE (<< 1 HASH_BITS)) - (define HASH_MASK (- HASH_SIZE 1)) - (define WMASK (- WSIZE 1)) - ;; /* HASH_SIZE and WSIZE must be powers of two */ - - (define NIL 0) - ;; /* Tail of hash chains */ - - (define FAST 4) - (define SLOW 2) - ;; /* speed options for the general purpose bit flag */ - - (define TOO_FAR 4096) - ;; /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - - (define bits_sent 0) - (define (isgraph c) #t) - -(define head-vec-delta WSIZE) - - ;; The gzip code wasn't defined for threads (or even to be - ;; multiply invoked), so we pack it up into a unit to - ;; invoke each time we need it. - - (define code - (unit - (import) - (export) - - -;; /* =========================================================================== -;; * Local data used by the "longest match" routines. -;; */ - -(define real-table (make-vector (<< 1 BITS) 0)) - -(define prev-vec real-table) -(define head-vec real-table) - -;; /* DECLARE(uch, window, 2L*WSIZE); */ -;; /* Sliding window. Input bytes are read into the second half of the window, -;; * and move to the first half later to keep a dictionary of at least WSIZE -;; * bytes. With this organization, matches are limited to a distance of -;; * WSIZE-MAX_MATCH bytes, but this ensures that IO is always -;; * performed with a length multiple of the block size. Also, it limits -;; * the window size to 64K, which is quite useful on MSDOS. -;; * To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would -;; * be less efficient). -;; */ - -;; /* DECLARE(Pos, prev, WSIZE); */ -;; /* Link to older string with same hash index. To limit the size of this -;; * array to 64K, this link is maintained only for the last 32K strings. -;; * An index in this array is thus a window index modulo 32K. -;; */ - -;; /* DECLARE(Pos, head, 1<= HASH_BITS -;; */ - -(define prev_length 0) -;; /* Length of the best match at previous step. Matches not greater than this -;; * are discarded. This is used in the lazy match evaluation. -;; */ - -(define strstart 0) ;; /* start of string to insert */ -(define match_start 0) ;; /* start of matching string */ -(define eofile #f) ;; /* flag set at end of input file */ -(define lookahead 0) ;; /* number of valid bytes ahead in window */ - -(define max_chain_length 0) -;; /* To speed up deflation, hash chains are never searched beyond this length. -;; * A higher limit improves compression ratio but degrades the speed. -;; */ - -(define max_lazy_match 0) -;; /* Attempt to find a better match only when the current match is strictly -;; * smaller than this value. This mechanism is used only for compression -;; * levels >= 4. -;; */ - -(define (max_insert_length) max_lazy_match) -;; /* Insert new strings in the hash table only if the match length -;; * is not greater than this length. This saves time but degrades compression. -;; * max_insert_length is used only for compression levels <= 3. -;; */ - -(define good_match 0) -;; /* Use a faster search when the previous match is longer than this */ - - -;; /* Values for max_lazy_match, good_match and max_chain_length, depending on -;; * the desired pack level (0..9). The values given below have been tuned to -;; * exclude worst case performance for pathological files. Better values may be -;; * found for specific files. -;; */ - -(define-struct config - (good_length ;; /* reduce lazy search above this match length */ - max_lazy ;; /* do not perform lazy search above this match length */ - nice_length ;; /* quit search above this match length */ - max_chain)) - -(define nice_match MAX_MATCH) -;; /* Stop searching when current match exceeds this */ - -(define configuration_table - (vector - ;; /* good lazy nice chain */ - (make-config 0 0 0 0) ;; /* 0 - store only */ - (make-config 4 4 8 4) ;; /* 1 - maximum speed, no lazy matches */ - (make-config 4 5 16 8) ;; /* 2 */ - (make-config 4 6 32 32) ;; /* 3 */ - - (make-config 4 4 16 16) ;; /* 4 - lazy matches */ - (make-config 8 16 32 32) ;; /* 5 */ - (make-config 8 16 128 128) ;; /* 6 */ - (make-config 8 32 128 256) ;; /* 7 */ - (make-config 32 128 258 1024) ;; /* 8 */ - (make-config 32 258 258 4096))) ;; /* 9 - maximum compression */ - -;; /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 -;; * For deflate_fast() (levels <= 3) good is ignored and lazy has a different -;; * meaning. -;; */ - -;; /* =========================================================================== -;; * Update a hash value with the given input byte -;; * IN assertion: all calls to to UPDATE_HASH are made with consecutive -;; * input characters, so that a running hash key can be computed from the -;; * previous key instead of complete recalculation each time. -;; */ -(define (UPDATE_HASH c) - (set! ins_h (bitwise-and (bitwise-xor (<< ins_h H_SHIFT) c) HASH_MASK))) - -;; /* =========================================================================== -;; * Insert string s in the dictionary and set match_head to the previous head -;; * of the hash chain (the most recent string with same hash key). Return -;; * the previous length of the hash chain. -;; * IN assertion: all calls to to INSERT_STRING are made with consecutive -;; * input characters and the first MIN_MATCH bytes of s are valid -;; * (except for the last MIN_MATCH-1 bytes of the input file). -;; */ -;; (define-macro INSERT_STRING ) - -;; /* =========================================================================== -;; * Initialize the "longest match" routines for a new file -;; */ -(define (lm_init pack_level) - ;; int pack_level; /* 0: store, 1: best speed, 9: best compression */ - - (when (or (< pack_level 1) - (> pack_level 9)) - (error "bad pack level")) - - ;; /* Initialize the hash table. */ - (for i := head-vec-delta < (+ head-vec-delta HASH_SIZE) do - (vector-set! head-vec i 0)) - - ;; /* prev will be initialized on the fly */ - - ;; /* Set the default configuration parameters: - ;; */ - (set! max_lazy_match (config-max_lazy (vector-ref configuration_table pack_level))) - (set! good_match (config-good_length (vector-ref configuration_table pack_level))) - (set! nice_match (config-nice_length (vector-ref configuration_table pack_level))) - (set! max_chain_length (config-max_chain (vector-ref configuration_table pack_level))) - - (let ([flag (cond - [(= pack_level 1) FAST] - [(= pack_level 9) SLOW] - [else 0])]) - ;; /* ??? reduce max_chain_length for binary files */ - - (set! strstart 0) - (set! block_start 0) - - (set! lookahead (read_buf 0 (* 2 WSIZE))) - - (if (or (= lookahead 0) (= lookahead EOF-const)) - (begin - (set! eofile #t) - (set! lookahead 0)) - (begin - (set! eofile #f) - ;; /* Make sure that we always have enough lookahead. This is important - ;; * if input comes from a device such as a tty. - ;; */ - (let loop () - (when (and (< lookahead MIN_LOOKAHEAD) - (not eofile)) - (fill_window))) - - (set! ins_h 0) - (for j := 0 < MIN_MATCH-1 do (UPDATE_HASH (bytes-ref window-vec j))) - (DEBUG (Trace stderr "hash init: ~a\n" ins_h)) - ;; /* If lookahead < MIN_MATCH, ins_h is garbage, but this is - ;; * not important since only literal bytes will be emitted. - ;; */ - )) - - flag)) - -;; /* =========================================================================== -;; * Set match_start to the longest match starting at the given string and -;; * return its length. Matches shorter or equal to prev_length are discarded, -;; * in which case the result is equal to prev_length and match_start is -;; * garbage. -;; * IN assertions: cur_match is the head of the hash chain for the current -;; * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 -;; */ - -;; Since longest_match is not called recursively or in multiple threads, we can -;; make this C-derived code have more C-like allocation by lifting out its local -;; variables. - -(define longest_match - (let ((cur_match 0) - (chain_length 0) - (scanpos 0) - (matchpos 0) - (len 0) - (best_len 0) - (limit NIL) - (strendpos 0) - (scan_end1 0) - (scan_end 0)) - - (define (longest_match _cur_match) - ;; IPos cur_match; /* current match */ - - (set! cur_match _cur_match) - - (set! chain_length max_chain_length) ;; /* max hash chain length */ - (set! scanpos strstart) ;; /* current string */ - (set! matchpos 0) ;; /* matched string */ - (set! len 0) ;; /* length of current match */ - (set! best_len prev_length) ;; /* best match length so far */ - (set! limit (if (> strstart MAX_DIST) - (- strstart MAX_DIST) - NIL)) - ;; /* Stop when cur_match becomes <= limit. To simplify the code, - ;; * we prevent matches with the string of window index 0. - ;; */ - - ;; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - ;; * It is easy to get rid of this optimization if necessary. - ;; */ - ;; #if HASH_BITS < 8 || MAX_MATCH != 258 - ;; error: Code too clever - ;; #endif - - (set! strendpos (+ strstart MAX_MATCH)) - (set! scan_end1 (bytes-ref window-vec (+ scanpos best_len -1))) - (set! scan_end (bytes-ref window-vec (+ scanpos best_len))) - - ;; /* Do not waste too much time if we already have a good match: */ - (when (>= prev_length good_match) - (set! chain_length (>> chain_length 2))) - - (Assert - (unless (<= strstart (- window_size MIN_LOOKAHEAD)) - (error "insufficient lookahead"))) - - (longest_match-loop) - - best_len) - - (define (continue) - (set! cur_match (vector-ref prev-vec (bitwise-and cur_match WMASK))) - (when (and (> cur_match limit) - (begin - (set! chain_length (sub1 chain_length)) - (positive? chain_length))) - (longest_match-loop))) - (define (*++scan) - (set! scanpos (add1 scanpos)) - (and (scanpos . < . window_size) ; the original C code can read past the end of the buffer - (bytes-ref window-vec scanpos))) - (define (*++match) - (set! matchpos (add1 matchpos)) - (bytes-ref window-vec matchpos)) - - (define (match-eight) - (when (and (eq? (*++scan) (*++match)) (eq? (*++scan) (*++match)) - (eq? (*++scan) (*++match)) (eq? (*++scan) (*++match)) - (eq? (*++scan) (*++match)) (eq? (*++scan) (*++match)) - (eq? (*++scan) (*++match)) (eq? (*++scan) (*++match)) - (< scanpos strendpos)) - (match-eight))) - - (define (longest_match-loop) - - (Assert - (unless (< cur_match strstart) - (error "no future"))) - - (set! matchpos cur_match) - - ;; /* Skip to next match if the match length cannot increase - ;; * or if the match length is less than 2: - ;; */ - - (if (or (not (eq? (bytes-ref window-vec (+ matchpos best_len)) scan_end)) - (not (eq? (bytes-ref window-vec (+ matchpos best_len -1)) scan_end1)) - (not (eq? (bytes-ref window-vec matchpos) (bytes-ref window-vec scanpos))) - (not (eq? (begin (set! matchpos (add1 matchpos)) - (bytes-ref window-vec matchpos)) - (bytes-ref window-vec (add1 scanpos))))) - (continue) - - (begin - ;; /* The check at best_len-1 can be removed because it will be made - ;; * again later. (This heuristic is not always a win.) - ;; * It is not necessary to compare scan[2] and match[2] since they - ;; * are always equal when the other bytes match, given that - ;; * the hash keys are equal and that HASH_BITS >= 8. - ;; */ - (set! scanpos (+ scanpos 2)) - (set! matchpos (+ matchpos 1)) - - ;; /* We check for insufficient lookahead only every 8th comparison; - ;; * the 256th check will be made at strstart+258. - ;; */ - (match-eight) - - (set! len (- MAX_MATCH (- strendpos scanpos))) - (set! scanpos (+ strendpos (- MAX_MATCH))) - (DEBUG (Trace stderr "Match: ~a\n" len)) - - (when (begin - (if (> len best_len) - (begin - (set! match_start cur_match) - (set! best_len len) - (if (>= len nice_match) - #f - (begin - (set! scan_end1 (bytes-ref window-vec (+ scanpos best_len -1))) - (set! scan_end (bytes-ref window-vec (+ scanpos best_len))) - #t))) - #t)) - (continue))))) - longest_match)) - -;; /* =========================================================================== -;; * Check that the match at match_start is indeed a match. -;; */ -;; -(define (check_match start match length) - #t) - -;; /* =========================================================================== -;; * Fill the window when the lookahead becomes insufficient. -;; * Updates strstart and lookahead, and sets eofile if end of input file. -;; * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 -;; * OUT assertions: at least one byte has been read, or eofile is set; -;; * file reads are performed for at least two bytes (required for the -;; * translate_eol option). -;; */ -(define (fill_window) - (define more (- window_size lookahead strstart)) - ;; /* Amount of free space at the end of the window. */ - - ;; /* If the window is almost full and there is insufficient lookahead, - ;; * move the upper half to the lower one to make room in the upper half. - ;; */ - (when (>= strstart (+ WSIZE MAX_DIST)) - (let ([bs (gzbytes-bytes window)] [ofs (gzbytes-offset window)]) - (bytes-copy! bs ofs bs (+ ofs WSIZE) (+ ofs WSIZE WSIZE))) - (set! match_start (- match_start WSIZE)) - (set! strstart (- strstart WSIZE)) ;; /* we now have strstart >= MAX_DIST: */ - - (set! block_start (- block_start WSIZE)) - - (for n := 0 < HASH_SIZE do - (let ([m (vector-ref head-vec (+ n head-vec-delta))]) - (vector-set! head-vec (+ n head-vec-delta) - (if (>= m WSIZE) (- m WSIZE) NIL)))) - - (for n := 0 < WSIZE do - (let ([m (vector-ref prev-vec n)]) - (vector-set! prev-vec n - (if (>= m WSIZE) (- m WSIZE) NIL))) - ;; /* If n is not on any hash chain, prev[n] is garbage but - ;; * its value will never be used. - ;; */ - ) - - (set! more (+ more WSIZE))) - - (when (not eofile) - (let ([n (read_buf (+ strstart lookahead) more)]) - (if (or (= n 0) (= n EOF-const)) - (set! eofile #t) - (set! lookahead (+ lookahead n)))))) - -;; /* =========================================================================== -;; * Flush the current block, with given end-of-file flag. -;; * IN assertion: strstart is set to the end of the current match. -;; */ -(define (FLUSH-BLOCK eof) - (flush_block (and (>= block_start 0) (gzbytes+ window block_start)) - (- strstart block_start) - eof)) - -;; /* =========================================================================== -;; * Same as above, but achieves better compression. We use a lazy -;; * evaluation for matches: a match is finally adopted only if there is -;; * no better match at the next window position. -;; */ -(define (do-deflate) - (define hash_head 0) ;; /* head of hash chain */ - (define prev_match 0) ;; /* previous match */ - (define flush #f) ;; /* set if current block must be flushed */ - (define match_available #f) ;; /* set if previous match exists */ - (define match_length MIN_MATCH-1) ;; /* length of best match */ - - ;; /* Process the input block. */ - (let dloop () - (when (not (zero? lookahead)) - (DEBUG (Trace stderr - "prep ~a ~a ~a ~a ~a ~a ~a ~a ~a ~a\n" hash_head prev_length match_length max_lazy_match strstart - ins_h (+ strstart MIN_MATCH-1) (bytes-ref window-vec (+ strstart MIN_MATCH-1)) - H_SHIFT HASH_MASK)) - - ;; /* Insert the string window[strstart .. strstart+2] in the - ;; * dictionary, and set hash_head to the head of the hash chain: - ;; */ - (INSERT_STRING strstart hash_head UPDATE_HASH window-vec head-vec prev-vec ins_h) - - (DEBUG (Trace stderr - "inh ~a ~a ~a ~a ~a ~a ~a\n" hash_head prev_length match_length max_lazy_match strstart - ins_h (bytes-ref window-vec (+ strstart MIN_MATCH-1)))) - - ;; /* Find the longest match, discarding those <= prev_length. - ;; */ - (set! prev_length match_length) - (set! prev_match match_start) - (set! match_length MIN_MATCH-1) - - (when (and (not (= hash_head NIL)) - (< prev_length max_lazy_match) - (<= (- strstart hash_head) MAX_DIST)) - ;; /* To simplify the code, we prevent matches with the string - ;; * of window index 0 (in particular we have to avoid a match - ;; * of the string with itself at the start of the input file). - ;; */ - (set! match_length (longest_match hash_head)) - (DEBUG (Trace stderr "blip ~a\n" match_length)) - ;; /* longest_match() sets match_start */ - (when (> match_length lookahead) - (set! match_length lookahead)) - - ;; /* Ignore a length 3 match if it is too distant: */ - (when (and (= match_length MIN_MATCH) - (> (- strstart match_start) TOO_FAR)) - ;; /* If prev_match is also MIN_MATCH, match_start is garbage - ;; * but we will ignore the current match anyway. - ;; */ - (set! match_length (sub1 match_length)))) - - ;; /* If there was a match at the previous step and the current - ;; * match is not better, output the previous match: - ;; */ - (cond - [(and (>= prev_length MIN_MATCH) - (<= match_length prev_length)) - (DEBUG (Trace stderr "x1\n")) - - (check_match (- strstart 1) prev_match prev_length) - - (set! flush (ct_tally (- strstart 1 prev_match) - (- prev_length MIN_MATCH))) - - ;; /* Insert in hash table all strings up to the end of the match. - ;; * strstart-1 and strstart are already inserted. - ;; */ - (set! lookahead (- lookahead (- prev_length 1))) - (set! prev_length (- prev_length 2)) - (let loop () - (set! strstart (add1 strstart)) - (INSERT_STRING strstart hash_head UPDATE_HASH window-vec head-vec prev-vec ins_h) - (DEBUG (Trace stderr - "inhx ~a ~a ~a ~a ~a ~a\n" hash_head prev_length max_lazy_match strstart - ins_h (bytes-ref window-vec (+ strstart MIN_MATCH -1)))) - ;; /* strstart never exceeds WSIZE-MAX_MATCH, so there are - ;; * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH - ;; * these bytes are garbage, but it does not matter since the - ;; * next lookahead bytes will always be emitted as literals. - ;; */ - (set! prev_length (sub1 prev_length)) - (when (not (= prev_length 0)) - (loop))) - (set! match_available #f) - (set! match_length MIN_MATCH-1) - (set! strstart (add1 strstart)) - (when flush - (DEBUG (Trace stderr "flush\n")) - (FLUSH-BLOCK 0) - (DEBUG (Trace stderr "flush done\n")) - (set! block_start strstart))] - - [match_available - (DEBUG (Trace stderr "x2\n")) - ;; /* If there was no match at the previous position, output a - ;; * single literal. If there was a match but the current match - ;; * is longer, truncate the previous match to a single literal. - ;; */ - ;; (Tracevv stderr "~c" (integer->char (vector-ref window-vec (- strstart 1)))) - (when (ct_tally 0 (bytes-ref window-vec (- strstart 1))) - (FLUSH-BLOCK 0) - (set! block_start strstart)) - (set! strstart (add1 strstart)) - (set! lookahead (sub1 lookahead))] - - [else - (DEBUG (Trace stderr "x3\n")) - ;; /* There is no previous match to compare with, wait for - ;; * the next step to decide. - ;; */ - (set! match_available #t) - (set! strstart (add1 strstart)) - (set! lookahead (sub1 lookahead))]) - - (Assert - (unless (and (<= strstart bytes_in) - (<= lookahead bytes_in)) - (error "a bit too far"))) - - ;; /* Make sure that we always have enough lookahead, except - ;; * at the end of the input file. We need MAX_MATCH bytes - ;; * for the next match, plus MIN_MATCH bytes to insert the - ;; * string following the next match. - ;; */ - (let loop () - (when (and (< lookahead MIN_LOOKAHEAD) - (not eofile)) - (DEBUG (Trace stderr "fill\n")) - (fill_window) - (loop))) - - (dloop))) - - (when match_available - (ct_tally 0 (bytes-ref window-vec (- strstart 1)))) - - (FLUSH-BLOCK 1)); /* eof */ - -#| -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1992-1993 Jean-loup Gailly - * This is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License, see the file COPYING. - */ - -/* - * PURPOSE - * - * Encode various sets of source values using variable-length - * binary code trees. - * - * DISCUSSION - * - * The PKZIP "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in the ZIP file in a compressed form - * which is itself a Huffman encoding of the lengths of - * all the code strings (in ascending order by source values). - * The actual code strings are reconstructed from the lengths in - * the UNZIP process, as described in the "application note" - * (APPNOTE.TXT) distributed as part of PKWARE's PKZIP program. - * - * REFERENCES - * - * Lynch, Thomas J. - * Data Compression: Techniques and Applications, pp. 53-55. - * Lifetime Learning Publications, 1985. ISBN 0-534-03418-7. - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - * - * INTERFACE - * - * void ct_init (ush *attr, int *methodp) - * Allocate the match buffer, initialize the various tables and save - * the location of the internal file attribute (ascii/binary) and - * method (DEFLATE/STORE) - * - * void ct_tally (int dist, int lc); - * Save the match info and tally the frequency counts. - * - * long flush_block (char *buf, ulg stored_len, int eof) - * Determine the best encoding for the current block: dynamic trees, - * static trees or store, and output the encoded block to the zip - * file. Returns the total compressed length for the file so far. - * - */ - -|# - -;; /* =========================================================================== -;; * Constants -;; */ - -(define MAX_BITS 15) -;; /* All codes must not exceed MAX_BITS bits */ - -(define MAX_BL_BITS 7) -;; /* Bit length codes must not exceed MAX_BL_BITS bits */ - -(define LENGTH_CODES 29) -;; /* number of length codes, not counting the special END_BLOCK code */ - -(define LITERALS 256) -;; /* number of literal bytes 0..255 */ - -(define END_BLOCK 256) -;; /* end of block literal code */ - -(define L_CODES (+ LITERALS 1 LENGTH_CODES)) -;; /* number of Literal or Length codes, including the END_BLOCK code */ - -(define D_CODES 30) -;; /* number of distance codes */ - -(define BL_CODES 19) -;; /* number of codes used to transfer the bit lengths */ - -(define extra_lbits ;; /* extra bits for each length code */ - (vector 0 0 0 0 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 0)) - -(define extra_dbits ;; /* extra bits for each distance code */ - (vector 0 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13)) - -(define extra_blbits ;; /* extra bits for each bit length code */ - (vector 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 7)) - -(define STORED_BLOCK 0) -(define STATIC_TREES 1) -(define DYN_TREES 2) -;; /* The three kinds of block type */ - -(define LIT_BUFSIZE #x8000) -(define DIST_BUFSIZE #x8000) -;; /* Sizes of match buffers for literals/lengths and distances. There are -;; * 4 reasons for limiting LIT_BUFSIZE to 64K: -;; * - frequencies can be kept in 16 bit counters -;; * - if compression is not successful for the first block, all input data is -;; * still in the window so we can still emit a stored block even when input -;; * comes from standard input. (This can also be done for all blocks if -;; * LIT_BUFSIZE is not greater than 32K.) -;; * - if compression is not successful for a file smaller than 64K, we can -;; * even emit a stored file instead of a stored block (saving 5 bytes). -;; * - creating new Huffman trees less frequently may not provide fast -;; * adaptation to changes in the input data statistics. (Take for -;; * example a binary file with poorly compressible code followed by -;; * a highly compressible string table.) Smaller buffer sizes give -;; * fast adaptation but have of course the overhead of transmitting trees -;; * more frequently. -;; * - I can't count above 4 -;; * The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save -;; * memory at the expense of compression). Some optimizations would be possible -;; * if we rely on DIST_BUFSIZE == LIT_BUFSIZE. -;; */ -(when (> LIT_BUFSIZE INBUFSIZ) - (error "cannot overlay l_buf and inbuf")) - -(define REP_3_6 16) -;; /* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -(define REPZ_3_10 17) -;; /* repeat a zero length 3-10 times (3 bits of repeat count) */ - -(define REPZ_11_138 18) -;; /* repeat a zero length 11-138 times (7 bits of repeat count) */ - -;; /* =========================================================================== -;; * Local data -;; */ - -;; /* Data structure describing a single value and its code string. */ -(define-struct ct_data (freq code dad len)) -;; union { -;; ush freq; ;; /* frequency count */ -;; ush code; ;; /* bit string */ -;; } fc; -;; union { -;; ush dad; ;; /* father node in Huffman tree */ -;; ush len; ;; /* length of bit string */ -;; } dl; -#| -(define ct_data-freq ct_data-freq/code) -(define ct_data-code ct_data-freq/code) -(define ct_data-dad ct_data-dad/len) -(define ct_data-len ct_data-dad/len) -(define set-ct_data-freq! set-ct_data-freq/code!) -(define set-ct_data-code! set-ct_data-freq/code!) -(define set-ct_data-dad! set-ct_data-dad/len!) -(define set-ct_data-len! set-ct_data-dad/len!) -(define (_make-ct_data f c d l) (make-ct_data (or f c) (or d l))) -|# -(define _make-ct_data make-ct_data) - -(define HEAP_SIZE (+ (* 2 L_CODES) 1)) -;; /* maximum heap size */ - -(define dyn_ltree (make-vector HEAP_SIZE 'uninit-dl)) ;; /* literal and length tree */ -(define dyn_dtree (make-vector (+ (* 2 D_CODES) 1) 'uninit-dd)) ;; /* distance tree */ - -(define static_ltree (make-vector (+ L_CODES 2) 'uninit-sl)) -;; /* The static literal tree. Since the bit lengths are imposed, there is no -;; * need for the L_CODES extra codes used during heap construction. However -;; * The codes 286 and 287 are needed to build a canonical tree (see ct_init -;; * below). -;; */ - -(define static_dtree (make-vector D_CODES 'uninit-sd)) -;; /* The static distance tree. (Actually a trivial tree since all codes use -;; * 5 bits.) -;; */ - -(define bl_tree (make-vector (+ (* 2 BL_CODES) 1) 'uninit-dl)) -;; /* Huffman tree for the bit lengths */ - -(define-struct tree_desc - (dyn_tree; ;; /* the dynamic tree */ - static_tree; ;; /* corresponding static tree or NULL */ - extra_bits; ;; /* extra bits for each code or NULL */ - extra_base; ;; /* base index for extra_bits */ - elems; ;; /* max number of elements in the tree */ - max_length; ;; /* max bit length for the codes */ - max_code)); ;; /* largest code with non zero frequency */ - -(define l_desc (make-tree_desc - dyn_ltree static_ltree extra_lbits - (+ LITERALS 1) L_CODES MAX_BITS 0)) - -(define d_desc (make-tree_desc - dyn_dtree static_dtree extra_dbits - 0 D_CODES MAX_BITS 0)) - -(define bl_desc (make-tree_desc - bl_tree #f extra_blbits - 0 BL_CODES MAX_BL_BITS 0)) - - -(define bl_count (make-vector (+ MAX_BITS 1) 0)) -;; /* number of codes at each bit length for an optimal tree */ - -(define bl_order - (vector 16 17 18 0 8 7 9 6 10 5 11 4 12 3 13 2 14 1 15)) -;; /* The lengths of the bit length codes are sent in order of decreasing -;; * probability, to avoid transmitting the lengths for unused bit length codes. -;; */ - -(define heap (make-vector (+ (* 2 L_CODES) 1) 0)) ;; /* heap used to build the Huffman trees */ -(define heap_len 0) ;; /* number of elements in the heap */ -(define heap_max 0) ;; /* element of largest frequency */ -;; /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. -;; * The same heap array is used to build all trees. -;; */ - -(define depth (make-vector (+ (* 2 L_CODES) 1) 0)) -;; /* Depth of each subtree used as tie breaker for trees of equal frequency */ - -(define length_code (make-vector (- MAX_MATCH MIN_MATCH -1) 0)) -;; /* length code for each normalized match length (0 == MIN_MATCH) */ - -(define dist_code (make-vector 512 0)) -;; /* distance codes. The first 256 values correspond to the distances -;; * 3 .. 258, the last 256 values correspond to the top 8 bits of -;; * the 15 bit distances. -;; */ - -(define base_length (make-vector LENGTH_CODES 0)) -;; /* First normalized length for each code (0 = MIN_MATCH) */ - -(define base_dist (make-vector D_CODES 0)) -;; /* First normalized distance for each code (0 = distance of 1) */ - -(define inbuf (make-bytes (+ INBUFSIZ INBUF_EXTRA) 0)) -(define l_buf inbuf) -;; /* DECLARE(uch, l_buf, LIT_BUFSIZE); buffer for literals or lengths */ - -(define d_buf (make-vector DIST_BUFSIZE 0)) -;; /* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */ - -(define flag_buf (make-vector (/ LIT_BUFSIZE 8) 0)) -;; /* flag_buf is a bit array distinguishing literals from lengths in -;; * l_buf, thus indicating the presence or absence of a distance. -;; */ - -(define last_lit 0) ;; /* running index in l_buf */ -(define last_dist 0) ;; /* running index in d_buf */ -(define last_flags 0) ;; /* running index in flag_buf */ -(define flags 0) ;; /* current flags not yet saved in flag_buf */ -(define flag_bit 0) ;; /* current bit used in flags */ -;; /* bits are filled in flags starting at bit 0 (least significant). -;; * Note: these flags are overkill in the current code since we don't -;; * take advantage of DIST_BUFSIZE == LIT_BUFSIZE. -;; */ - -(define opt_len 0); ;; /* bit length of current block with optimal trees */ -(define static_len 0); ;; /* bit length of current block with static trees */ - -(define compressed_len 0); ;; /* total bit length of compressed file */ - -(define input_len 0); ;; /* total byte length of input file */ -;; /* input_len is for debugging only since we can get it by other means. */ - -;; (define block_start 0); ;; /* window offset of current block */ -;; (define strstart 0); ;; /* window offset of current string */ - -(define (send_code c tree) - (send_bits (ct_data-code (vector-ref tree c)) - (ct_data-len (vector-ref tree c)))) -;; /* Send a code of the given tree. c and tree must not have side effects */ - -(define (d_code dist) - (if (< dist 256) - (vector-ref dist_code dist) - (vector-ref dist_code (+ 256 (>> dist 7))))) -;; /* Mapping from a distance to a distance code. dist is the distance - 1 and -;; * must not have side effects. dist_code[256] and dist_code[257] are never -;; * used. -;; */ - -;; /* =========================================================================== -;; * Allocate the match buffer, initialize the various tables and save the -;; * location of the internal file attribute (ascii/binary) and method -;; * (DEFLATE/STORE). -;; */ -(define (ct_init) - - (define length 0) ;; /* length value */ - (define dist 0) ;; /* distance index */ - - (set! compressed_len 0) - (set! input_len 0) - - (unless (ct_data? (vector-ref static_dtree 0)) ;; /* ct_init already called? */ - ;; /* Initialize the mapping length (0..255) -> length code (0..28) */ - (set! length 0) - (for code := 0 < (- LENGTH_CODES 1) do - (vector-set! base_length code length) - (for n := 0 < (<< 1 (vector-ref extra_lbits code)) do - (vector-set! length_code length code) - (set! length (add1 length)))) - - (Assert - (unless (= length 256) - (error "ct_init: length != 256"))) - - ;; /* Note that the length 255 (match length 258) can be represented - ;; * in two different ways: code 284 + 5 bits or code 285, so we - ;; * overwrite length_code[255] to use the best encoding: - ;; */ - (vector-set! length_code (- length 1) (- LENGTH_CODES 1)) - - ;; /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - (set! dist 0) - (for code := 0 < 16 do - (vector-set! base_dist code dist) - (for n := 0 < (<< 1 (vector-ref extra_dbits code)) do - (vector-set! dist_code dist code) - (set! dist (add1 dist)))) - - (Assert - (unless (= dist 256) - (error "ct_init: dist != 256"))) - (set! dist (>> dist 7)) ;; /* from now on, all distances are divided by 128 */ - (for code := 16 < D_CODES do - (vector-set! base_dist code (<< dist 7)) - (for n := 0 < (<< 1 (- (vector-ref extra_dbits code) 7)) do - (vector-set! dist_code (+ 256 dist) code) - (set! dist (add1 dist)))) - - (Assert - (unless (= dist 256) - (error "ct_init: 256+dist != 512"))) - - ;; /* Construct the codes of the static literal tree */ - (for bits := 0 <= MAX_BITS do - (vector-set! bl_count bits 0)) - - (let ([init-ltree - (lambda (s e v) - (for n := s <= e do - (vector-set! static_ltree n (_make-ct_data #f 0 #f v)) - (vector-set! bl_count v (add1 (vector-ref bl_count v)))))]) - (init-ltree 0 143 8) - (init-ltree 144 255 9) - (init-ltree 256 279 7) - (init-ltree 280 287 8)) - ;; /* Codes 286 and 287 do not exist, but we must include them in the - ;; * tree construction to get a canonical Huffman tree (longest code - ;; * all ones) - ;; */ - (gen_codes static_ltree (+ L_CODES 1)) - - ;; /* The static distance tree is trivial: */ - (for n := 0 < D_CODES do - (vector-set! static_dtree n - (_make-ct_data #f (bi_reverse n 5) #f 5))) - - ;; /* Initialize the first block of the first file: */ - (init_block))) - -;; /* =========================================================================== -;; * Initialize a new block. -;; */ -(define inited-once? #f) -(define (init_block) - (for n := 0 < (if inited-once? L_CODES HEAP_SIZE) do - (vector-set! dyn_ltree n (_make-ct_data 0 #f 0 #f))) - (for n := 0 < (if inited-once? D_CODES (+ (* 2 D_CODES) 1)) do - (vector-set! dyn_dtree n (_make-ct_data 0 #f 0 #f))) - (for n := 0 < (if inited-once? BL_CODES (+ (* 2 BL_CODES) 1)) do - (vector-set! bl_tree n (_make-ct_data 0 #f 0 #f))) - - (set! inited-once? #t) - - (set-ct_data-freq! (vector-ref dyn_ltree END_BLOCK) 1) - (set! opt_len 0) - (set! static_len 0) - (set! last_lit 0) - (set! last_dist 0) - (set! last_flags 0) - (set! flags 0) - (set! flag_bit 1)) - -(define SMALLEST 1) -;; /* Index within the heap array of least frequent node in the Huffman tree */ - - -;; /* =========================================================================== -;; * Remove the smallest element from the heap and recreate the heap with -;; * one less element. Updates heap and heap_len. -;; */ -;; (define-macro pqremove ) - -;; /* =========================================================================== -;; * Compares to subtrees, using the tree depth as tie breaker when -;; * the subtrees have equal frequency. This minimizes the worst case length. -;; */ -(define (smaller tree n m) - (or (< (ct_data-freq (vector-ref tree n)) (ct_data-freq (vector-ref tree m))) - (and (= (ct_data-freq (vector-ref tree n)) (ct_data-freq (vector-ref tree m))) - (<= (vector-ref depth n) (vector-ref depth m))))) - -;; /* =========================================================================== -;; * Restore the heap property by moving down the tree starting at node k, -;; * exchanging a node with the smallest of its two sons if necessary, stopping -;; * when the heap property is re-established (each father smaller than its -;; * two sons). -;; */ -(define (pqdownheap tree k) - ;; ct_data near *tree; /* the tree to restore */ - ;; int k; /* node to move down */ - - (define v (vector-ref heap k)) - (define j (<< k 1)) ;; /* left son of k */ - (let loop ([k k][j j]) - (if (<= j heap_len) - ;; /* Set j to the smallest of the two sons: */ - (let ([j (if (and (< j heap_len) - (smaller tree - (vector-ref heap (+ j 1)) - (vector-ref heap j))) - (add1 j) - j)]) - ;; /* Exit if v is smaller than both sons */ - (if (smaller tree v (vector-ref heap j)) - (vector-set! heap k v) - (begin - ;; /* Exchange v with the smallest son */ - (vector-set! heap k (vector-ref heap j)) - ;; /* And continue down the tree, setting j to the left son of k */ - (loop j (<< j 1))))) - (vector-set! heap k v)))) - -;; /* =========================================================================== -;; * Compute the optimal bit lengths for a tree and update the total bit length -;; * for the current block. -;; * IN assertion: the fields freq and dad are set, heap[heap_max] and -;; * above are the tree nodes sorted by increasing frequency. -;; * OUT assertions: the field len is set to the optimal bit length, the -;; * array bl_count contains the frequencies for each bit length. -;; * The length opt_len is updated; static_len is also updated if stree is -;; * not null. -;; */ -(define (gen_bitlen desc) - ;; tree_desc near *desc; ;; /* the tree descriptor */ - - (define tree (tree_desc-dyn_tree desc)) - (define extra (tree_desc-extra_bits desc)) - (define base (tree_desc-extra_base desc)) - (define max_code (tree_desc-max_code desc)) - (define max_length (tree_desc-max_length desc)) - (define stree (tree_desc-static_tree desc)) - (define n 0) (define m 0) ;; /* iterate over the tree elements */ - (define bits 0) ;; /* bit length */ - (define xbits 0) ;; /* extra bits */ - (define f 0); ;; /* frequency */ - (define overflow 0); ;; /* number of elements with bit length too large */ - (define h 0) - - (for bits := 0 <= MAX_BITS do - (vector-set! bl_count bits 0)) - - ;; /* In a first pass, compute the optimal bit lengths (which may - ;; * overflow in the case of the bit length tree). - ;; */ - (set-ct_data-len! (vector-ref tree (vector-ref heap heap_max)) 0) ;; /* root of the heap */ - - (for h := (+ 1 heap_max) < HEAP_SIZE do - (set! n (vector-ref heap h)) - (set! bits (+ (ct_data-len (vector-ref tree (ct_data-dad (vector-ref tree n)))) 1)) - (when (> bits max_length) - (set! bits max_length) - (set! overflow (add1 overflow))) - (set-ct_data-len! (vector-ref tree n) bits) - ;; /* We overwrite tree[n].Dad which is no longer needed */ - (unless (> n max_code) - ;; /* leaf node */ - (vector-set! bl_count bits (add1 (vector-ref bl_count bits))) - (set! xbits 0) - (when (>= n base) - (set! xbits (vector-ref extra (- n base)))) - (set! f (ct_data-freq (vector-ref tree n))) - (set! opt_len (+ opt_len (* f (+ bits xbits)))) - (when stree - (set! static_len - (+ static_len - (* f (+ (ct_data-len (vector-ref stree n)) xbits))))))) - - (unless (= overflow 0) - - (DEBUG (Trace stderr "\nbit length overflow\n")) - ;; /* This happens for example on obj2 and pic of the Calgary corpus */ - - ;; /* Find the first bit length which could increase: */ - (let loop () - (set! bits (- max_length 1)) - (let loop () - (when (= (vector-ref bl_count bits) 0) - (set! bits (sub1 bits)) - (loop))) - (vector-set! bl_count bits (sub1 (vector-ref bl_count bits))) - (vector-set! bl_count (+ bits 1) (+ (vector-ref bl_count (+ bits 1)) 2)) - (vector-set! bl_count max_length (sub1 (vector-ref bl_count max_length))) - ;; /* The brother of the overflow item also moves one step up, - ;; * but this does not affect bl_count[max_length] - ;; */ - (set! overflow (- overflow 2)) - (when (> overflow 0) - (loop))) - - (set! h HEAP_SIZE) - ;; /* Now recompute all bit lengths, scanning in increasing frequency. - ;; * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - ;; * lengths instead of fixing only the wrong ones. This idea is taken - ;; * from 'ar' written by Haruhiko Okumura.) - ;; */ - (for bits := max_length then sub1 > 0 do - (set! n (vector-ref bl_count bits)) - (let loop () - (when (not (= n 0)) - (set! h (sub1 h)) - (set! m (vector-ref heap h)) - (if (> m max_code) - (loop) - (begin - (when (not (= (ct_data-len (vector-ref tree m)) bits)) - (set! opt_len - (+ opt_len (* (- bits (ct_data-len (vector-ref tree m))) - (ct_data-freq (vector-ref tree m)))))) - (set-ct_data-len! (vector-ref tree m) bits) - (set! n (sub1 n)) - (loop)))))))) - -;; /* =========================================================================== -;; * Generate the codes for a given tree and bit counts (which need not be -;; * optimal). -;; * IN assertion: the array bl_count contains the bit length statistics for -;; * the given tree and the field len is set for all tree elements. -;; * OUT assertion: the field code is set for all tree elements of non -;; * zero code length. -;; */ -(define (gen_codes tree max_code) - ;; ct_data near *tree; /* the tree to decorate */ - ;; int max_code; /* largest code with non zero frequency */ - - (define next_code (make-vector (+ MAX_BITS 1) 0)) ;; /* next code value for each bit length */ - (define code 0) ;; /* running code value */ - (define bits 0) ;; /* bit index */ - - ;; /* The distribution counts are first used to generate the code values - ;; * without bit reversal. - ;; */ - (for bits := 1 <= MAX_BITS do - (set! code (<< (+ code (vector-ref bl_count (- bits 1))) 1)) - (vector-set! next_code bits code)) - ;; /* Check that the bit counts in bl_count are consistent. The last code - ;; * must be all ones. - ;; */ - (Assert - (unless (= (+ code (vector-ref bl_count MAX_BITS)-1) - (- (<< 1 MAX_BITS) 1)) - "inconsistent bit counts")) - (DEBUG (Tracev stderr "\ngen_codes: max_code ~a " max_code)) - - (for n := 0 <= max_code do - (let ([len (ct_data-len (vector-ref tree n))]) - (unless (= len 0) - ;; /* Now reverse the bits */ - (let ([nc (vector-ref next_code len)]) - (set-ct_data-code! (vector-ref tree n) (bi_reverse nc len)) - (vector-set! next_code len (add1 nc))) - - (DEBUG (Tracec (not (eq? tree static_ltree)) - stderr - "\nn ~a ~c l ~a c ~x (~x) " - n #\space len - (or (ct_data-code (vector-ref tree n)) 0) - (or (- (vector-ref next_code len) 1) 0))))))) - -;; /* =========================================================================== -;; * Construct one Huffman tree and assigns the code bit strings and lengths. -;; * Update the total bit length for the current block. -;; * IN assertion: the field freq is set for all tree elements. -;; * OUT assertions: the fields len and code are set to the optimal bit length -;; * and corresponding code. The length opt_len is updated; static_len is -;; * also updated if stree is not null. The field max_code is set. -;; */ -(define (build_tree desc) - ;; tree_desc near *desc; ;; /* the tree descriptor */ - - (define tree (tree_desc-dyn_tree desc)) - (define stree (tree_desc-static_tree desc)) - (define elems (tree_desc-elems desc)) - (define n 0) (define m 0) ;; /* iterate over heap elements */ - (define max_code -1) ;; /* largest code with non zero frequency */ - (define node elems) ;; /* next internal node of the tree */ - - ;; /* Construct the initial heap, with least frequent element in - ;; * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - ;; * heap[0] is not used. - ;; */ - (set! heap_len 0) - (set! heap_max HEAP_SIZE) - - (for n := 0 < elems do - (DEBUG (Trace stderr "freq: ~a ~a\n" n (ct_data-freq (vector-ref tree n)))) - (if (not (= (ct_data-freq (vector-ref tree n)) 0)) - (begin (set! heap_len (add1 heap_len)) - (set! max_code n) - (vector-set! heap heap_len n) - (vector-set! depth n 0)) - (set-ct_data-len! (vector-ref tree n) 0))) - - (DEBUG (Trace stderr "Building: ~a ~a ~a\n" elems heap_len max_code)) - - ;; /* The pkzip format requires that at least one distance code exists, - ;; * and that at least one bit should be sent even if there is only one - ;; * possible code. So to avoid special checks later on we force at least - ;; * two codes of non zero frequency. - ;; */ - (let loop () - (when (< heap_len 2) - (let ([new (if (< max_code 2) - (begin - (set! max_code (add1 max_code)) - max_code) - 0)]) - (set! heap_len (add1 heap_len)) - (vector-set! heap heap_len new) - (set-ct_data-freq! (vector-ref tree new) 1) - (vector-set! depth new 0) - (set! opt_len (sub1 opt_len)) - (when stree - (set! static_len (- static_len (ct_data-len (vector-ref stree new))))) - ;; /* new is 0 or 1 so it does not have extra bits */ - (loop)))) - - (set-tree_desc-max_code! desc max_code) - - ;; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - ;; * establish sub-heaps of increasing lengths: - ;; */ - (for n := (quotient heap_len 2) then sub1 >= 1 do (pqdownheap tree n)) - - ;; /* Construct the Huffman tree by repeatedly combining the least two - ;; * frequent nodes. - ;; */ - (let loop () - ;; /* n = node of least frequency */ - (set! n (vector-ref heap SMALLEST)) - (vector-set! heap SMALLEST (vector-ref heap heap_len)) - (set! heap_len (sub1 heap_len)) - (pqdownheap tree SMALLEST) - - (set! m (vector-ref heap SMALLEST)) ;; /* m = node of next least frequency */ - - (set! heap_max (sub1 heap_max)) - (vector-set! heap heap_max n) ;; /* keep the nodes sorted by frequency */ - (set! heap_max (sub1 heap_max)) - (vector-set! heap heap_max m) - - ;; /* Create a new node father of n and m */ - (set-ct_data-freq! (vector-ref tree node) - (+ (ct_data-freq (vector-ref tree n)) - (ct_data-freq (vector-ref tree m)))) - (vector-set! depth node (+ (max (vector-ref depth n) - (vector-ref depth m)) - 1)) - (set-ct_data-dad! (vector-ref tree n) node) - (set-ct_data-dad! (vector-ref tree m) node) - - ;; /* and insert the new node in the heap */ - (vector-set! heap SMALLEST node) - (set! node (add1 node)) - (pqdownheap tree SMALLEST) - - (when (>= heap_len 2) - (loop))) - - (set! heap_max (sub1 heap_max)) - (vector-set! heap heap_max (vector-ref heap SMALLEST)) - - ;; /* At this point, the fields freq and dad are set. We can now - ;; * generate the bit lengths. - ;; */ - (gen_bitlen desc) - - (DEBUG (Trace stderr "Build: ~a\n" max_code)) - ;; /* The field len is now set, we can generate the bit codes */ - (gen_codes tree max_code)) - -;; /* =========================================================================== -;; * Scan a literal or distance tree to determine the frequencies of the codes -;; * in the bit length tree. Updates opt_len to take into account the repeat -;; * counts. (The contribution of the bit length codes will be added later -;; * during the construction of bl_tree.) -;; */ -(define (scan_tree tree max_code) - ;; ct_data near *tree; ;; /* the tree to be scanned */ - ;; int max_code; ;; /* and its largest code of non zero frequency */ - - (define prevlen -1) ;; /* last emitted length */ - (define curlen 0) ;; /* length of current code */ - (define nextlen (ct_data-len (vector-ref tree 0))) ;; /* length of next code */ - (define count 0) ;; /* repeat count of the current code */ - (define max_count 7) ;; /* max repeat count */ - (define min_count 4) ;; /* min repeat count */ - - (when (= nextlen 0) - (set! max_count 138) - (set! min_count 3)) - - (set-ct_data-len! (vector-ref tree (+ max_code 1)) #xffff) ;; /* guard */ - - (for n := 0 <= max_code do - (let/ec continue - (define (inc-bl_tree-freq which amt) - (set-ct_data-freq! (vector-ref bl_tree which) - (+ amt (ct_data-freq (vector-ref bl_tree which))))) - - (set! curlen nextlen) - (set! nextlen (ct_data-len (vector-ref tree (+ n 1)))) - (set! count (add1 count)) - - (cond [(and (< count max_count) (= curlen nextlen)) - (continue)] - [(< count min_count) - (inc-bl_tree-freq curlen count)] - [(not (= curlen 0)) - (when (not (= curlen prevlen)) - (inc-bl_tree-freq curlen 1)) - (inc-bl_tree-freq REP_3_6 1)] - [(<= count 10) - (inc-bl_tree-freq REPZ_3_10 1)] - [else - (inc-bl_tree-freq REPZ_11_138 1)]) - - (set! count 0) - (set! prevlen curlen) - - (cond [(= nextlen 0) (set! max_count 138) (set! min_count 3)] - [(= curlen nextlen) (set! max_count 6) (set! min_count 3)] - [else (set! max_count 7) (set! min_count 4)])))) - -;; /* =========================================================================== -;; * Send a literal or distance tree in compressed form, using the codes in -;; * bl_tree. -;; */ -(define (send_tree tree max_code) - ;; ct_data near *tree; ;; /* the tree to be scanned */ - ;; int max_code; ;; /* and its largest code of non zero frequency */ - - (define prevlen -1) ;; /* last emitted length */ - (define curlen 0) ;; /* length of current code */ - (define nextlen (ct_data-len (vector-ref tree 0))) ;; /* length of next code */ - (define count 0) ;; /* repeat count of the current code */ - (define max_count 7) ;; /* max repeat count */ - (define min_count 4) ;; /* min repeat count */ - - ;; /* tree[max_code+1].Len = -1; */ ;; /* guard already set */ - (when (= nextlen 0) - (set! max_count 138) - (set! min_count 3)) - - (for n := 0 <= max_code do - (let/ec continue - (set! curlen nextlen) - (set! nextlen (ct_data-len (vector-ref tree (+ n 1)))) - - (set! count (add1 count)) - (cond [(and (< count max_count) (= curlen nextlen)) - (continue)] - [(< count min_count) - (let loop () - (send_code curlen bl_tree) - (set! count (sub1 count)) - (when (not (= count 0)) (loop)))] - [(not (= curlen 0)) - (when (not (= curlen prevlen)) - (send_code curlen bl_tree) - (set! count (sub1 count))) - (Assert - (unless (>= 6 count 3) - (error " 3_6?"))) - (send_code REP_3_6 bl_tree) - (send_bits (- count 3) 2)] - [(<= count 10) - (send_code REPZ_3_10 bl_tree) - (send_bits (- count 3) 3)] - [else - (send_code REPZ_11_138 bl_tree) - (send_bits (- count 11) 7)]) - - (set! count 0) - (set! prevlen curlen) - - (cond [(= nextlen 0) (set! max_count 138) (set! min_count 3)] - [(= curlen nextlen) (set! max_count 6) (set! min_count 3)] - [else (set! max_count 7) (set! min_count 4)])))) - -;; /* =========================================================================== -;; * Construct the Huffman tree for the bit lengths and return the index in -;; * bl_order of the last bit length code to send. -;; */ -(define (build_bl_tree) - (define max_blindex 0) ;; /* index of last bit length code of non zero freq */ - - ;; /* Determine the bit length frequencies for literal and distance trees */ - (scan_tree dyn_ltree (tree_desc-max_code l_desc)) - (scan_tree dyn_dtree (tree_desc-max_code d_desc)) - - ;; /* Build the bit length tree: */ - (build_tree bl_desc) - ;; /* opt_len now includes the length of the tree representations, except - ;; * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - ;; */ - - ;; /* Determine the number of bit length codes to send. The pkzip format - ;; * requires that at least 4 bit length codes be sent. (appnote.txt says - ;; * 3 but the actual value used is 4.) - ;; */ - (set! max_blindex (- BL_CODES 1)) - (let loop () - (when (and (>= max_blindex 3) - (= (ct_data-len (vector-ref bl_tree - (vector-ref bl_order max_blindex))) - 0)) - (set! max_blindex (sub1 max_blindex)) - (loop))) - - ;; /* Update opt_len to include the bit length tree and counts */ - (set! opt_len (+ opt_len (* 3 (+ max_blindex 1)) 5 5 4)) - (DEBUG (Tracev stderr "\ndyn trees: dyn ~a, stat ~a" opt_len static_len)) - - max_blindex) - -;; /* =========================================================================== -;; * Send the header for a block using dynamic Huffman trees: the counts, the -;; * lengths of the bit length codes, the literal tree and the distance tree. -;; * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. -;; */ -(define (send_all_trees lcodes dcodes blcodes) - ;; int lcodes, dcodes, blcodes; ;; /* number of codes for each tree */ - - (Assert - (unless (and (>= lcodes 257) - (>= dcodes 1) - (>= blcodes 4)) - (error "not enough codes"))) - (Assert - (unless (and (<= lcodes L_CODES) - (<= dcodes D_CODES) - (<= blcodes BL_CODES)) - (error "too many codes ~a(~a) ~a(~a) ~a(~a)" - lcodes L_CODES - dcodes D_CODES - blcodes BL_CODES))) - - (DEBUG (Tracev stderr "\nbl counts: ")) - - (send_bits (- lcodes 257) 5) ;; /* not +255 as stated in appnote.txt */ - (send_bits (- dcodes 1) 5) - (send_bits (- blcodes 4) 4) ;; /* not -3 as stated in appnote.txt */ - (for rank := 0 < blcodes do - (DEBUG (Tracev stderr "\nbl code ~a " (vector-ref bl_order rank))) - (send_bits (ct_data-len (vector-ref bl_tree (vector-ref bl_order rank))) - 3)) - (DEBUG (Tracev stderr "\nbl tree: sent ~a" bits_sent)) - - (send_tree dyn_ltree (- lcodes 1)) ;; /* send the literal tree */ - (DEBUG (Tracev stderr "\nlit tree: sent ~a" bits_sent)) - - (send_tree dyn_dtree (- dcodes 1)) ;; /* send the distance tree */ - (DEBUG (Tracev stderr "\ndist tree: sent ~a" bits_sent))) - -;; /* =========================================================================== -;; * Determine the best encoding for the current block: dynamic trees, static -;; * trees or store, and output the encoded block to the zip file. This function -;; * returns the total compressed length for the file so far. -;; */ -(define (flush_block buf stored_len eof) - ;; char *buf; ;; /* input block, or NULL if too old */ - ;; ulg stored_len; ;; /* length of input block */ - ;; int eof; ;; /* true if this is the last block for a file */ - - (define opt_lenb 0) (define static_lenb 0) ;; /* opt_len and static_len in bytes */ - (define max_blindex 0) ;; /* index of last bit length code of non zero freq */ - - (vector-set! flag_buf last_flags flags) ;; /* Save the flags for the last 8 items */ - - ;; /* Construct the literal and distance trees */ - (build_tree l_desc) - (DEBUG (Tracev stderr "\nlit data: dyn ~a, stat ~a" opt_len static_len)) - - (build_tree d_desc) - (DEBUG (Tracev stderr "\ndist data: dyn ~a, stat ~a" opt_len static_len)) - ;; /* At this point, opt_len and static_len are the total bit lengths of - ;; * the compressed block data, excluding the tree representations. - ;; */ - - ;; /* Build the bit length tree for the above two trees, and get the index - ;; * in bl_order of the last bit length code to send. - ;; */ - (set! max_blindex (build_bl_tree)) - - ;; /* Determine the best encoding. Compute first the block length in bytes */ - (set! opt_lenb (>> (+ opt_len 3 7) 3)) - (set! static_lenb (>> (+ static_len 3 7) 3)) - (set! input_len (+ input_len stored_len)) ;; /* for debugging only */ - - (DEBUG (Trace stderr "\nopt ~a(~a) stat ~a(~a) stored ~a lit ~a dist ~a " - opt_lenb opt_len static_lenb static_len stored_len - last_lit last_dist)) - - (when (<= static_lenb opt_lenb) - (set! opt_lenb static_lenb)) - - ;; /* If compression failed and this is the first and last block, - ;; * and if the zip file can be seeked (to rewrite the local header), - ;; * the whole file is transformed into a stored file: - ;; */ - (cond - [(and buf (<= (+ stored_len 4) opt_lenb)) - ;; /* 4: two words for the lengths */ - - ;; /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - ;; * Otherwise we can't have processed more than WSIZE input bytes since - ;; * the last block flush, because compression would have been - ;; * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - ;; * transform a block into a stored block. - ;; */ - (send_bits (+ (<< STORED_BLOCK 1) eof) 3) ;; /* send block type */ - (set! compressed_len (bitwise-and (+ compressed_len 3 7) (bitwise-not 7))) - (set! compressed_len (+ compressed_len (<< (+ stored_len 4) 3))) - - (copy_block buf stored_len #t)] ;; /* with header */ - [(= static_lenb opt_lenb) - (send_bits (+ (<< STATIC_TREES 1) eof) 3) - (compress_block static_ltree static_dtree) - (set! compressed_len (+ compressed_len 3 static_len))] - [else - (send_bits (+ (<< DYN_TREES 1) eof) 3) - (send_all_trees (+ (tree_desc-max_code l_desc) 1) - (+ (tree_desc-max_code d_desc) 1) - (+ max_blindex 1)) - (compress_block dyn_ltree dyn_dtree) - (set! compressed_len (+ compressed_len 3 opt_len))]) - - ;; Assert - ;; (unless (= compressed_len bits_sent) - ;; (error "bad compressed size")) - (init_block) - - (when (not (= eof 0)) - (Assert - (unless (= input_len bytes_in) - (newline (current-error-port)) - (error 'eof "bad input size: ~a != ~a" input_len bytes_in))) - (bi_windup) - (set! compressed_len ;; /* align on byte boundary */ - (+ compressed_len 7))) - - (DEBUG (Tracev stderr "\ncomprlen ~a(~a) " (>> compressed_len 3) - (- compressed_len (* 7 eof)))) - - (>> compressed_len 3)) - -;; /* =========================================================================== -;; * Save the match info and tally the frequency counts. Return true if -;; * the current block must be flushed. -;; */ -(define ct_tally - (let ([dist 0]) - (lambda (_dist lc) - ;; int dist; ;; /* distance of matched string */ - ;; int lc; ;; /* match length-MIN_MATCH or unmatched char (if dist==0) */ - - (set! dist _dist) - - (bytes-set! l_buf last_lit lc) - (set! last_lit (add1 last_lit)) - (if (= dist 0) - ;; /* lc is the unmatched char */ - (set-ct_data-freq! (vector-ref dyn_ltree lc) - (add1 (ct_data-freq (vector-ref dyn_ltree lc)))) - (begin - ;; /* Here, lc is the match length - MIN_MATCH */ - (set! dist (sub1 dist)) ;; /* dist = match distance - 1 */ - (Assert - (unless (and (< dist MAX_DIST) - (<= lc (- MAX_MATCH MIN_MATCH)) - (< (d_code dist) D_CODES)) - (error "ct_tally: bad match"))) - - (let* ([i (+ (vector-ref length_code lc) LITERALS 1)] - [ct (vector-ref dyn_ltree i)]) - (DEBUG (Trace stderr "Set: ~a -> ~a\n" lc i)) - (set-ct_data-freq! ct (add1 (ct_data-freq ct)))) - (let ([ct (vector-ref dyn_dtree (d_code dist))]) - (set-ct_data-freq! ct (add1 (ct_data-freq ct)))) - - (vector-set! d_buf last_dist dist) - (set! last_dist (add1 last_dist)) - (set! flags (bitwise-ior flags flag_bit)))) - - (set! flag_bit (<< flag_bit 1)) - - ;; /* Output the flags if they fill a byte: */ - (when (= (bitwise-and last_lit 7) 0) - (vector-set! flag_buf last_flags flags) - (set! last_flags (add1 last_flags)) - (set! flags 0) (set! flag_bit 1)) - - (or - ;; /* Try to guess if it is profitable to stop the current block here */ - (and (and (> LEVEL 2) (= (bitwise-and last_lit #xfff) 0)) - (let () - ;; /* Compute an upper bound for the compressed length */ - (define out_length (* last_lit 8)) - (define in_length (- strstart block_start)) - - (for dcode := 0 < D_CODES do - (set! out_length - (+ out_length - (* (ct_data-freq (vector-ref dyn_dtree dcode)) - (+ 5 (vector-ref extra_dbits dcode)))))) - (set! out_length (>> out_length 3)) - (DEBUG (Trace stderr "\nlast_lit ~a, last_dist ~a, in ~a, out ~~~a(~a%) " - last_lit last_dist in_length out_length - (- 100 (/ (* out_length 100) in_length)))) - (and (< last_dist (quotient last_lit 2)) - (< out_length (quotient in_length 2))))) - - (or (= last_lit (- LIT_BUFSIZE 1)) - (= last_dist DIST_BUFSIZE)) - ;; /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K - ;; * on 16 bit machines and because stored blocks are restricted to - ;; * 64K-1 bytes. - ;; */ - )))) - -;; /* =========================================================================== -;; * Send the block data compressed using the given Huffman trees -;; */ -(define (compress_block ltree dtree) - ;; ct_data near *ltree; ;; /* literal tree */ - ;; ct_data near *dtree; ;; /* distance tree */ - - (define dist 0) ;; /* distance of matched string */ - (define lc 0) ;; /* match length or unmatched char (if dist == 0) */ - (define lx 0) ;; /* running index in l_buf */ - (define dx 0) ;; /* running index in d_buf */ - (define fx 0) ;; /* running index in flag_buf */ - (define flag 0) ;; /* current flags */ - (define code 0) ;; /* the code to send */ - (define extra 0) ;; /* number of extra bits to send */ - - (when (not (= last_lit 0)) - (let loop () - (when (= (bitwise-and lx 7) 0) - (set! flag (vector-ref flag_buf fx)) - (set! fx (add1 fx))) - - (set! lc (bytes-ref l_buf lx)) - (set! lx (add1 lx)) - - (cond - [(= (bitwise-and flag 1) 0) - (send_code lc ltree) ;; /* send a literal byte */ - (DEBUG '(Tracecv (isgraph lc) stderr " '~c' " (integer->char lc)))] - [else - ;; /* Here, lc is the match length - MIN_MATCH */ - (set! code (vector-ref length_code lc)) - (send_code (+ code LITERALS 1) ltree) ;; /* send the length code */ - (set! extra (vector-ref extra_lbits code)) - (when (not (= extra 0)) - (set! lc (- lc (vector-ref base_length code))) - (send_bits lc extra)) ;; /* send the extra length bits */ - (set! dist (vector-ref d_buf dx)) - (set! dx (add1 dx)) - - ;; /* Here, dist is the match distance - 1 */ - (set! code (d_code dist)) - (Assert - (unless (< code D_CODES) - (error "bad d_code"))) - - (send_code code dtree) ;; /* send the distance code */ - (set! extra (vector-ref extra_dbits code)) - (when (not (= extra 0)) - (set! dist (- dist (vector-ref base_dist code))) - (send_bits dist extra))]) ;; /* send the extra distance bits */ - ;; /* literal or match pair ? */ - (set! flag (>> flag 1)) - (when (< lx last_lit) - (loop)))) - - (send_code END_BLOCK ltree)) - -#| -/* bits.c -- output variable-length bit strings - * Copyright (C) 1992-1993 Jean-loup Gailly - * This is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License, see the file COPYING. - */ - - -/* - * PURPOSE - * - * Output variable-length bit strings. Compression can be done - * to a file or to memory. (The latter is not supported in this version.) - * - * DISCUSSION - * - * The PKZIP "deflate" file format interprets compressed file data - * as a sequence of bits. Multi-bit strings in the file may cross - * byte boundaries without restriction. - * - * The first bit of each byte is the low-order bit. - * - * The routines in this file allow a variable-length bit value to - * be output right-to-left (useful for literal values). For - * left-to-right output (useful for code strings from the tree routines), - * the bits must have been reversed first with bi_reverse(). - * - * For in-memory compression, the compressed bit stream goes directly - * into the requested output buffer. The input data is read in blocks - * by the mem_read() function. The buffer is limited to 64K on 16 bit - * machines. - * - * INTERFACE - * - * void bi_init (FILE *zipfile) - * Initialize the bit string routines. - * - * void send_bits (int value, int length) - * Write out a bit string, taking the source bits right to - * left. - * - * int bi_reverse (int value, int length) - * Reverse the bits of a bit string, taking the source bits left to - * right and emitting them right to left. - * - * void bi_windup (void) - * Write out any remaining bits in an incomplete byte. - * - * void copy_block(char *buf, unsigned len, int header) - * Copy a stored block to the zip file, storing first the length and - * its one's complement if requested. - * - */ -|# - -(define bytes_in 0) - -(define bi_buf 0) -;; /* Output buffer. bits are inserted starting at the bottom (least significant -;; * bits). -;; */ - -(define Buf_size (* 8 2)) -;; /* Number of bits used within bi_buf. (bi_buf might be implemented on -;; * more than 16 bits on some systems.) -;; */ - -(define bi_valid 0) -;; /* Number of valid bits in bi_buf. All bits above the last valid bit -;; * are always zero. -;; */ - -;; /* =========================================================================== -;; * Initialize the bit string routines. -;; */ -(define (bi_init) - (set! bi_buf 0) - (set! bi_valid 0) - (set! bits_sent 0)) - - -;; /* =========================================================================== -;; * Send a value on a given number of bits. -;; * IN assertion: length <= 16 and value fits in length bits. -;; */ -(define (send_bits value length) - ;; int value; /* value to send */ - ;; int length; /* number of bits */ - - (DEBUG (Tracev stderr " l ~a v ~x " length value)) - (Assert - (unless (and (> length 0) (<= length 15)) - (error "invalid length"))) - (set! bits_sent (+ bits_sent length)) - - ;; /* If not enough room in bi_buf, use (valid) bits from bi_buf and - ;; * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - ;; * unused bits in value. - ;; */ - (if (> bi_valid (- Buf_size length)) - (begin (put_short (bitwise-and (bitwise-ior bi_buf (<< value bi_valid)) - #xFFFF)) - (set! bi_buf (>> value (- Buf_size bi_valid))) - (set! bi_valid (+ bi_valid (- length Buf_size)))) - (begin (set! bi_buf (bitwise-ior bi_buf (<< value bi_valid))) - (set! bi_valid (+ bi_valid length))))) - -;; /* =========================================================================== -;; * Reverse the first len bits of a code, using straightforward code (a faster -;; * method would use a table) -;; * IN assertion: 1 <= len <= 15 -;; */ -(define (bi_reverse code len) - ;; unsigned code; /* the value to invert */ - ;; int len; /* its bit length */ - - (let loop ([res 0][code code][len len]) - (let ([res (<< (bitwise-ior res (bitwise-and code 1)) 1)]) - (if (> len 1) - (loop res (>> code 1) (sub1 len)) - (>> res 1))))) - -;; /* =========================================================================== -;; * Write out any remaining bits in an incomplete byte. -;; */ -(define (bi_windup) - (cond [(> bi_valid 8) (put_short bi_buf)] - [(> bi_valid 0) (put_byte bi_buf)]) - (set! bi_buf 0) - (set! bi_valid 0) - (set! bits_sent (bitwise-and (+ bits_sent 7) (bitwise-not 7)))) - -;; /* =========================================================================== -;; * Run a set of bytes through the crc shift register. If s is a NULL -;; * pointer, then initialize the crc shift register contents instead. -;; */ -(define crc #xffffffff) -(define (updcrc s n) - ;; uch *s; /* pointer to bytes to pump through */ - ;; unsigned n; /* number of bytes in s[] */ - (if s - (let loop ([c crc][p 0]) - (if (= p n) - (set! crc c) - (loop (bitwise-xor - (vector-ref crc_32_tab - (bitwise-and - (bitwise-xor c (bytes-ref window-vec (+ s p))) - #xff)) - (arithmetic-shift c -8)) - (add1 p)))) - (set! crc #xffffffff))) - -(define crc_32_tab - #(#x00000000 - #x77073096 #xee0e612c #x990951ba #x076dc419 - #x706af48f #xe963a535 #x9e6495a3 #x0edb8832 #x79dcb8a4 - #xe0d5e91e #x97d2d988 #x09b64c2b #x7eb17cbd #xe7b82d07 - #x90bf1d91 #x1db71064 #x6ab020f2 #xf3b97148 #x84be41de - #x1adad47d #x6ddde4eb #xf4d4b551 #x83d385c7 #x136c9856 - #x646ba8c0 #xfd62f97a #x8a65c9ec #x14015c4f #x63066cd9 - #xfa0f3d63 #x8d080df5 #x3b6e20c8 #x4c69105e #xd56041e4 - #xa2677172 #x3c03e4d1 #x4b04d447 #xd20d85fd #xa50ab56b - #x35b5a8fa #x42b2986c #xdbbbc9d6 #xacbcf940 #x32d86ce3 - #x45df5c75 #xdcd60dcf #xabd13d59 #x26d930ac #x51de003a - #xc8d75180 #xbfd06116 #x21b4f4b5 #x56b3c423 #xcfba9599 - #xb8bda50f #x2802b89e #x5f058808 #xc60cd9b2 #xb10be924 - #x2f6f7c87 #x58684c11 #xc1611dab #xb6662d3d #x76dc4190 - #x01db7106 #x98d220bc #xefd5102a #x71b18589 #x06b6b51f - #x9fbfe4a5 #xe8b8d433 #x7807c9a2 #x0f00f934 #x9609a88e - #xe10e9818 #x7f6a0dbb #x086d3d2d #x91646c97 #xe6635c01 - #x6b6b51f4 #x1c6c6162 #x856530d8 #xf262004e #x6c0695ed - #x1b01a57b #x8208f4c1 #xf50fc457 #x65b0d9c6 #x12b7e950 - #x8bbeb8ea #xfcb9887c #x62dd1ddf #x15da2d49 #x8cd37cf3 - #xfbd44c65 #x4db26158 #x3ab551ce #xa3bc0074 #xd4bb30e2 - #x4adfa541 #x3dd895d7 #xa4d1c46d #xd3d6f4fb #x4369e96a - #x346ed9fc #xad678846 #xda60b8d0 #x44042d73 #x33031de5 - #xaa0a4c5f #xdd0d7cc9 #x5005713c #x270241aa #xbe0b1010 - #xc90c2086 #x5768b525 #x206f85b3 #xb966d409 #xce61e49f - #x5edef90e #x29d9c998 #xb0d09822 #xc7d7a8b4 #x59b33d17 - #x2eb40d81 #xb7bd5c3b #xc0ba6cad #xedb88320 #x9abfb3b6 - #x03b6e20c #x74b1d29a #xead54739 #x9dd277af #x04db2615 - #x73dc1683 #xe3630b12 #x94643b84 #x0d6d6a3e #x7a6a5aa8 - #xe40ecf0b #x9309ff9d #x0a00ae27 #x7d079eb1 #xf00f9344 - #x8708a3d2 #x1e01f268 #x6906c2fe #xf762575d #x806567cb - #x196c3671 #x6e6b06e7 #xfed41b76 #x89d32be0 #x10da7a5a - #x67dd4acc #xf9b9df6f #x8ebeeff9 #x17b7be43 #x60b08ed5 - #xd6d6a3e8 #xa1d1937e #x38d8c2c4 #x4fdff252 #xd1bb67f1 - #xa6bc5767 #x3fb506dd #x48b2364b #xd80d2bda #xaf0a1b4c - #x36034af6 #x41047a60 #xdf60efc3 #xa867df55 #x316e8eef - #x4669be79 #xcb61b38c #xbc66831a #x256fd2a0 #x5268e236 - #xcc0c7795 #xbb0b4703 #x220216b9 #x5505262f #xc5ba3bbe - #xb2bd0b28 #x2bb45a92 #x5cb36a04 #xc2d7ffa7 #xb5d0cf31 - #x2cd99e8b #x5bdeae1d #x9b64c2b0 #xec63f226 #x756aa39c - #x026d930a #x9c0906a9 #xeb0e363f #x72076785 #x05005713 - #x95bf4a82 #xe2b87a14 #x7bb12bae #x0cb61b38 #x92d28e9b - #xe5d5be0d #x7cdcefb7 #x0bdbdf21 #x86d3d2d4 #xf1d4e242 - #x68ddb3f8 #x1fda836e #x81be16cd #xf6b9265b #x6fb077e1 - #x18b74777 #x88085ae6 #xff0f6a70 #x66063bca #x11010b5c - #x8f659eff #xf862ae69 #x616bffd3 #x166ccf45 #xa00ae278 - #xd70dd2ee #x4e048354 #x3903b3c2 #xa7672661 #xd06016f7 - #x4969474d #x3e6e77db #xaed16a4a #xd9d65adc #x40df0b66 - #x37d83bf0 #xa9bcae53 #xdebb9ec5 #x47b2cf7f #x30b5ffe9 - #xbdbdf21c #xcabac28a #x53b39330 #x24b4a3a6 #xbad03605 - #xcdd70693 #x54de5729 #x23d967bf #xb3667a2e #xc4614ab8 - #x5d681b02 #x2a6f2b94 #xb40bbe37 #xc30c8ea1 #x5a05df1b - #x2d02ef8d)) - -;; /* =========================================================================== -;; * Copy a stored block to the zip file, storing first the length and its -;; * one's complement if requested. -;; */ -(define (copy_block buf len header) - ;; char *buf; /* the input data */ - ;; unsigned len; /* its length */ - ;; int header; /* true if block header must be written */ - - (bi_windup);; /* align on byte boundary */ - - (when header - (put_short len) - (put_short (bitwise-and (bitwise-not len) #xFFFF)) - (set! bits_sent (+ bits_sent (* 2 16)))) - - (set! bits_sent (+ bits_sent (<< len 3))) - - (for pos := 0 < len do (put_byte (gzbytes-ref buf pos)))) - -;; /* =========================================================================== -;; * Read a new buffer from the current input file, perform end-of-line -;; * translation, and update the crc and input file size. -;; * IN assertion: size >= 2 (for end-of-line translation) -;; */ -(define (read_buf startpos size) - ;; char *buf; - ;; unsigned size; - - ;; Assert - ;; (unless (= insize 0) - ;; (error "inbuf not empty")) - - (let* ([s (read-bytes! window-vec ifd startpos (+ size startpos))] - [len (if (eof-object? s) EOF-const s)]) - (when (positive? len) - (updcrc startpos len) - (set! bytes_in (+ bytes_in len))) - len)) - -;; Assumes being called with c in 0..FF -(define-syntax put_byte - (syntax-rules () - [(_ c) - (begin (bytes-set! outbuf outcnt c) - (set! outcnt (add1 outcnt)) - (when (= outcnt OUTBUFSIZ) (flush_outbuf)))])) - -;; /* Output a 16 bit value, lsb first */ -;; Assumes being called with c in 0..FFFF -(define (put_short w) - (if (< outcnt (- OUTBUFSIZ 2)) - (begin (bytes-set! outbuf outcnt (bitwise-and #xFF w)) - (bytes-set! outbuf (add1 outcnt) (>> w 8)) - ;; this is not faster... - ;; (integer->integer-bytes w 2 #f #f outbuf outcnt) - (set! outcnt (+ outcnt 2))) - (begin (put_byte (bitwise-and #xFF w)) - (put_byte (>> w 8))))) - -;; /* Output a 32 bit value to the bit stream, lsb first */ -(define (put_long n) - (put_short (bitwise-and #xFFFF n)) - (put_short (bitwise-and #xFFFF (>> n 16)))) - -(define outcnt 0) -(define bytes_out 0) -(define outbuf (make-bytes OUTBUFSIZ)) - -;; /* =========================================================================== -;; * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. -;; * (used for the compressed data only) -;; */ -(define (flush_outbuf) - (unless (= outcnt 0) - - (write-bytes outbuf ofd 0 outcnt) - - (set! bytes_out (+ bytes_out outcnt)) - (set! outcnt 0))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(define ifd #f) -(define ofd #f) - -(define (deflate-inner in out) - (do-deflate)) - -(define (deflate in out) - - (set! bytes_in 0) - - (set! ifd in) - (set! ofd out) - (set! outcnt 0) - - (bi_init) - (ct_init) - (lm_init LEVEL) - - (deflate-inner in out) - - (flush_outbuf) - - (values bytes_in bytes_out (bitwise-xor crc #xffffffff))) - -(define (gzip-through-ports in out origname time_stamp) - - (define flags (if origname #x8 0)) ;; /* general purpose bit flags */ - - ;; make origname be a byte string - (set! origname (cond [(not origname) #f] - [(string? origname) (string->bytes/utf-8 origname)] - [(path? origname) (path->bytes origname)] - [else origname])) - - (set! bytes_in 0) - - (set! ifd in) - (set! ofd out) - (set! outcnt 0) - - ;; /* Write the header to the gzip file. See algorithm.doc for the format */ - (put_byte #o037) ;; /* magic header */ - (put_byte #o213) - (put_byte 8) ;; /* compression method */ - - (put_byte flags);; /* general flags */ - (put_long time_stamp); - - ;; /* Write deflated file to zip file */ - (updcrc #f 0) - - (bi_init) - (ct_init) - - (put_byte (lm_init LEVEL));; /* extra flags */ - (put_byte 3) ;; /* OS identifier */ - - (when origname - (for-each (lambda (b) (put_byte b)) (bytes->list origname)) - (put_byte 0)) - - (do-deflate) - - ;; /* Write the crc and uncompressed size */ - (put_long (bitwise-xor crc #xffffffff)) - (put_long bytes_in) - - (flush_outbuf)) - -(define (gzip infile outfile) - (let ([i (open-input-file infile)]) - (dynamic-wind - void - (lambda () - (let ([o (open-output-file outfile 'truncate/replace)]) - (dynamic-wind - void - (lambda () - (let ([name (with-handlers ([exn:fail? (lambda (x) #f)]) - (let-values ([(base name dir?) (split-path infile)]) - name))] - [timestamp (with-handlers ([exn:fail:filesystem? (lambda (x) 0)]) - (file-or-directory-modify-seconds infile))]) - (gzip-through-ports i o name timestamp))) - (lambda () (close-output-port o))))) - (lambda () (close-input-port i))))) - -(list gzip gzip-through-ports deflate))) - -(define gzip - (case-lambda - [(infile) (gzip infile (string-append infile ".gz"))] - [(infile outfile) ((car (invoke-unit code)) infile outfile)])) - -(define (gzip-through-ports in out origname time_stamp) - ((cadr (invoke-unit code)) in out origname time_stamp)) - -(define (deflate in out) - ((caddr (invoke-unit code)) in out)) - -) +(require mzlib/deflate) +(provide (all-from-out mzlib/deflate)) diff --git a/collects/file/zip.rkt b/collects/file/zip.rkt index e67c2dbf3e..562ae73f0e 100644 --- a/collects/file/zip.rkt +++ b/collects/file/zip.rkt @@ -1,269 +1,4 @@ -;; A modification of Dave Herman's zip module +#lang scheme/base -(module zip mzscheme - (require mzlib/deflate racket/file mzlib/kw) - - ;; =========================================================================== - ;; DATA DEFINITIONS - ;; =========================================================================== - - ;; An msdos-time or an msdos-date is an exact-integer in the respective format - ;; described at: - ;; - ;; http://msdn.microsoft.com/library/en-us/com/htm/cmf_a2c_25gl.asp - - ;; metadata : path * bytes * boolean * integer * integer * nat * integer - (define-struct metadata - (path name directory? time date compression attributes)) - - ;; header : metadata * exact-integer * nat * nat * nat - (define-struct header (metadata crc compressed uncompressed size)) - - ;; =========================================================================== - ;; CONSTANTS etc - ;; =========================================================================== - - (define *spec-version* 62) ; version 6.2 - (define *required-version* 20) ; version 2.0 - (define *compression-level* 8) ; I don't think this is configurable - (define *zip-comment* #"packed by Racket - http://racket-lang.org/") - - ;; PKZIP specification: - ;; http://www.pkware.com/company/standards/appnote/ - - (define *local-file-header* #x04034b50) - (define *archive-extra-record* #x08064b50) - (define *central-file-header* #x02014b50) - (define *digital-signature* #x05054b50) - (define *zip64-end-of-central-directory-record* #x06064b50) - (define *zip64-end-of-central-directory-locator* #x07064b50) - (define *end-of-central-directory-record* #x06054b50) - - (define *system* - (case (system-type) - [(unix oskit) 3] - [(windows) 0] - [(macos) 7] - [(macosx) 19])) - (define *os-specific-separator-regexp* - (case (system-type) - [(unix macosx oskit) #rx"/"] - [(windows) #rx"\\\\"] - [(macos) #rx":"])) - - (provide zip-verbose) - (define zip-verbose (make-parameter #f)) - - ;; =========================================================================== - ;; FILE CREATION - ;; =========================================================================== - - ;; date->msdos-time : date -> msdos-time - (define (date->msdos-time date) - (bitwise-ior (ceiling (/ (date-second date) 2)) - (arithmetic-shift (date-minute date) 5) - (arithmetic-shift (date-hour date) 11))) - - ;; date->msdos-date : date -> msdos-date - (define (date->msdos-date date) - (bitwise-ior (date-day date) - (arithmetic-shift (date-month date) 5) - (arithmetic-shift (- (date-year date) 1980) 9))) - - ;; seekable-port? : port -> boolean - (define (seekable-port? port) - (and (file-stream-port? port) - (with-handlers ([void (lambda (exn) #f)]) - (file-position port (file-position port)) - #t))) - - (define (write-int n size) - (write-bytes (integer->integer-bytes n size #f #f))) - - ;; zip-one-entry : metadata boolean -> header - (define (zip-one-entry metadata seekable?) - (let* ([directory? (metadata-directory? metadata)] - [path (metadata-path metadata)] - [filename (metadata-name metadata)] - [filename-length (bytes-length filename)] - [bits (if seekable? 0 #b1000)] - [time (metadata-time metadata)] - [date (metadata-date metadata)] - [compression (metadata-compression metadata)] - [mark1 #f] - [mark2 #f]) - (when (zip-verbose) - (eprintf "zip: compressing ~a...\n" filename)) - ;; write the contents to the output stream: - (write-int *local-file-header* 4) ; signature - (write-int *required-version* 2) ; version - (write-int bits 2) ; bits - (write-int compression 2) ; compression - (write-int time 2) ; time - (write-int date 2) ; date - (when seekable? (set! mark1 (file-position (current-output-port)))) - (write-int 0 4) ; crc-32 - (write-int 0 4) ; compressed - (write-int 0 4) ; uncompressed - (write-int filename-length 2) ; filename-length - (write-int 0 2) ; extra-length - (write-bytes filename) ; filename - (if directory? - (make-header metadata 0 0 0 (+ filename-length 30)) - (let-values ([(uncompressed compressed crc) - (with-input-from-file path - (lambda () - (deflate (current-input-port) - (current-output-port))))]) - (if seekable? - (begin (set! mark2 (file-position (current-output-port))) - (file-position (current-output-port) mark1)) - (write-int #x08074b50 4)) ; EXT signature - (write-int crc 4) ; crc-32 - (write-int compressed 4) ; compressed - (write-int uncompressed 4) ; uncompressed - (when seekable? (file-position (current-output-port) mark2)) - - ;; return the header information - (make-header metadata crc compressed uncompressed - (+ filename-length compressed - (if seekable? 30 46))))))) - - ;; write-end-of-central-directory : nat nat nat -> - (define (write-end-of-central-directory count start size) - (let ([comment-length (bytes-length *zip-comment*)]) - (write-int #x06054b50 4) ; signature - (write-int 0 2) ; # this disk - (write-int 0 2) ; # disk with start of central dir. - (write-int count 2) ; # entries in central dir. on this disk - (write-int count 2) ; # entries in central dir. - (write-int size 4) ; size of central dir. - (write-int start 4) ; offset of start of central dir. - (write-int comment-length 2) - (write-bytes *zip-comment*))) - - ;; write-central-directory : (listof header) -> - (define (write-central-directory headers) - (let ([count (length headers)]) - (let loop ([headers headers] [offset 0] [size 0]) - (if (null? headers) - ;; no digital signature (why?) - (write-end-of-central-directory count offset size) - (let* ([header (car headers)] - [metadata (header-metadata header)] - [filename-length (bytes-length (metadata-name metadata))] - [attributes (metadata-attributes metadata)] - [compression (metadata-compression metadata)] - [version (bitwise-ior *spec-version* - (arithmetic-shift *system* 8))]) - (write-int #x02014b50 4) - (write-int version 2) - (write-int *required-version* 2) - (write-int 0 2) - (write-int compression 2) - (write-int (metadata-time metadata) 2) - (write-int (metadata-date metadata) 2) - (write-int (header-crc header) 4) - (write-int (header-compressed header) 4) - (write-int (header-uncompressed header) 4) - (write-int filename-length 2) - (write-int 0 2) - (write-int 0 2) ; comment length - (write-int 0 2) - (write-int 0 2) ; internal attributes - (write-int attributes 4) ; external attributes - (write-int offset 4) - (write-bytes (metadata-name metadata)) - (loop (cdr headers) - (+ offset (header-size header)) - (+ size filename-length 46))))))) - - ;; The PKZIP specification includes an entry in the central directory for - ;; an entry's "external file attributes," which for standard ZIP files is - ;; the MS-DOS (i.e., FAT) directory attribute byte, and the Unix zip adds - ;; the Unix bits as the higher two bytes. - - ;; This is for reference - ;; (define *msdos:read-only* #x01) - ;; (define *msdos:hidden* #x02) - ;; (define *msdos:system* #x04) - ;; (define *msdos:volume* #x08) - ;; (define *msdos:directory* #x10) - ;; (define *msdos:archive* #x20) - ;; (define *unix:directory* #o40000) - ;; (define *unix:char-dev* #o20000) - ;; (define *unix:fifo* #o10000) - ;; (define *unix:suid* #o04000) - ;; (define *unix:sgid* #o02000) - ;; (define *unix:sticky* #o01000) - ;; (define *unix:owner-read* #o00400) - ;; (define *unix:owner-write* #o00200) - ;; (define *unix:owner-exe* #o00100) - ;; (define *unix:group-read* #o00040) - ;; (define *unix:group-write* #o00020) - ;; (define *unix:group-exe* #o00010) - ;; (define *unix:other-read* #o00004) - ;; (define *unix:other-write* #o00002) - ;; (define *unix:other-exe* #o00001) - (define (path-attributes path dir?) - (let ([dos (if dir? #x10 0)] - [unix (apply bitwise-ior (if dir? #o40000 0) - (map (lambda (p) - (case p - [(read) #o444] - [(write) #o200] ; mask out write bits - [(execute) #o111])) - (file-or-directory-permissions path)))]) - (bitwise-ior dos (arithmetic-shift unix 16)))) - - ;; with-trailing-slash : bytes -> bytes - (define (with-trailing-slash bytes) - (regexp-replace #rx#"/*$" bytes "/")) - - ;; with-slash-separator : bytes -> bytes - (define (with-slash-separator bytes) - (regexp-replace* *os-specific-separator-regexp* bytes #"/")) - - ;; build-metadata : relative-path -> metadata - (define (build-metadata path) - (let* ([mod (seconds->date (file-or-directory-modify-seconds path))] - [dir? (directory-exists? path)] - [path (cond [(path? path) path] - [(string? path) (string->path path)] - [(bytes? path) (bytes->path path)])] - [name (with-slash-separator (path->bytes path))] - [name (if dir? (with-trailing-slash name) name)] - [time (date->msdos-time mod)] - [date (date->msdos-date mod)] - [comp (if dir? 0 *compression-level*)] - [attr (path-attributes path dir?)]) - (make-metadata path name dir? time date comp attr))) - - ;; =========================================================================== - ;; FRONT END - ;; =========================================================================== - - ;; zip-write : (listof relative-path) -> - ;; writes a zip file to current-output-port - (provide zip->output) - (define/kw (zip->output files #:optional [out (current-output-port)]) - (parameterize ([current-output-port out]) - (let* ([seekable? (seekable-port? (current-output-port))] - [headers ; note: Racket's `map' is always left-to-right - (map (lambda (file) - (zip-one-entry (build-metadata file) seekable?)) - files)]) - (when (zip-verbose) - (eprintf "zip: writing headers...\n")) - (write-central-directory headers)) - (when (zip-verbose) - (eprintf "zip: done.\n")))) - - ;; zip : output-file paths -> - (provide zip) - (define (zip zip-file . paths) - (when (null? paths) (error 'zip "no paths specified")) - (with-output-to-file zip-file - (lambda () (zip->output (pathlist-closure paths))))) - - ) +(require mzlib/zip) +(provide (all-from-out mzlib/zip)) diff --git a/collects/lang/private/teach-shared.rkt b/collects/lang/private/teach-shared.rkt index d2c6090b92..f155cdaab1 100644 --- a/collects/lang/private/teach-shared.rkt +++ b/collects/lang/private/teach-shared.rkt @@ -20,4 +20,4 @@ (with-syntax ([undefined undefined-expr]) ;; Include the implementation. ;; See private/shared-body.rkt. - (include (lib "racket/private/shared-body.rkt"))))) + (include (lib "mzlib/private/shared-body.rkt"))))) diff --git a/collects/mzlib/a-signature.rkt b/collects/mzlib/a-signature.rkt index 6771c55db2..28026a6084 100644 --- a/collects/mzlib/a-signature.rkt +++ b/collects/mzlib/a-signature.rkt @@ -1,6 +1,6 @@ (module a-signature mzscheme - (require-for-syntax racket/private/unit-compiletime - racket/private/unit-syntax) + (require-for-syntax "private/unit-compiletime.rkt" + "private/unit-syntax.rkt") (require "unit.rkt") (provide (rename module-begin #%module-begin) diff --git a/collects/mzlib/control.rkt b/collects/mzlib/control.rkt index 44b48c6ada..d59f00ffb7 100644 --- a/collects/mzlib/control.rkt +++ b/collects/mzlib/control.rkt @@ -1,6 +1,268 @@ #lang racket/base -;; deprecated library, see `racket/control` +(require (for-syntax racket/base)) + +(provide call/prompt call/comp abort/cc + + abort + + fcontrol % + + control prompt control-at prompt-at + ;; `-at' variations expect a prompt tag + + shift reset shift-at reset-at + + control0 prompt0 control0-at prompt0-at + shift0 reset0 shift0-at reset0-at + + spawn + + splitter + + new-prompt set cupto) + +;; ---------------------------------------- + +(define call/prompt call-with-continuation-prompt) +(define call/comp call-with-composable-continuation) +(define abort/cc abort-current-continuation) + +;; ---------------------------------------- + +(define (abort . vals) + (abort-current-continuation + (default-continuation-prompt-tag) + (lambda () (apply values vals)))) + +;; ---------------------------------------- +;; Sitaram, PLDI'93 +;; The `%' here is compable with Sitaram & Felleisen, LSC'90, +;; since we make the handler optional. + +(define (fcontrol f #:tag [prompt-tag (default-continuation-prompt-tag)]) + (call-with-composable-continuation + (lambda (k) + (abort-current-continuation + prompt-tag + f + k)))) + +(define-syntax % + (syntax-rules () + [(_ expr handler #:tag prompt-tag) + (call-with-continuation-prompt + (lambda () expr) + prompt-tag + handler)] + [(_ expr handler) + (call-with-continuation-prompt + (lambda () expr) + (default-continuation-prompt-tag) + handler)] + [(_ expr) + (call-with-continuation-prompt + (lambda () expr))])) + +;; ---------------------------------------- +;; Predecessors of Sitaram, PLDI'93 +;; Felleisen, Wand, Friedman, & Duba, LFP'88 +;; Instead of `#', we use `prompt' as in Felleisen, POPL'88 +;; (where `control' is called `F') +;; See also Sitaram and Felleisen, LSC'90 + +;; Helpder function: abort-current-continuation/keep-prompt is +;; like abort-current-continuation, but it always leaves the +;; prompt in place, independent of the prompt's handler. +;; This is possible via call/cc (i.e., it must be possible +;; to abort and keep a prompt, because call/cc needs it). +(define (abort-current-continuation/keep-prompt tag thunk) + ((call-with-continuation-prompt + (lambda () + ((call-with-current-continuation + (lambda (k) (lambda () k)) + tag))) + tag) + thunk)) + +;; call-with-control, parameterized over whether to keep the +;; prompt (if the prompt's handler gives us the option of +;; removing it). The generated function is the same +;; as fcontrol when `abort-cc' is `abort-current-continuation'. +(define (make-call-with-control abort-cc) + ;; Uses call/cc to always keep the enclosing prompt. + (letrec ([call-with-control + (case-lambda + [(f) (call-with-control f (default-continuation-prompt-tag))] + [(f tag) (call-with-composable-continuation + (lambda (k) + (abort-cc + tag + (lambda () + (f k)))) + tag)])]) + call-with-control)) + +(define call-with-control + (make-call-with-control abort-current-continuation/keep-prompt)) + +(define-syntax define-control-macros + (syntax-rules () + [(_ control control-at call-with-control) + (begin + (define-syntax (control stx) + (syntax-case stx () + [(control id expr0 expr (... ...)) + (identifier? #'id) + #'(call-with-control (lambda (id) expr0 expr (... ...)))])) + (define-syntax (control-at stx) + (syntax-case stx () + [(control-at tag id expr0 expr (... ...)) + (identifier? #'id) + #'(call-with-control (lambda (id) expr0 expr (... ...)) tag)])))])) + +(define-control-macros control control-at call-with-control) + +(define-syntax define-prompt-macros + (syntax-rules () + [(_ prompt prompt-at call-with-prompt) + (begin + (define-syntax prompt + (syntax-rules () + [(prompt expr0 expr (... ...)) + (call-with-prompt (lambda () expr0 expr (... ...)))])) + (define-syntax prompt-at + (syntax-rules () + [(prompt-at tag expr0 expr (... ...)) + (call-with-prompt (lambda () expr0 expr (... ...)) tag)])))])) + +(define-prompt-macros prompt prompt-at call-with-continuation-prompt) + +;; ---------------------------------------- +;; Danvy & Filinski, LFP'90 + +;; call-with-shift, parameterized over whether to keep the prompt +;; (if the prompt's handler gives us the option of removing it), +;; and whether the new one is removable: +(define (make-call-with-shift abort-cc inserted-handler) + (letrec ([call-with-shift + (case-lambda + [(f) (call-with-shift f (default-continuation-prompt-tag))] + [(f tag) + (call-with-composable-continuation + (lambda (k) + (abort-cc + tag + (lambda () + (f (lambda vals + (call-with-continuation-prompt + (lambda () + (apply k vals)) + tag + inserted-handler)))))) + tag)])]) + call-with-shift)) + +(define call-with-shift + (make-call-with-shift abort-current-continuation/keep-prompt #f)) + +(define-control-macros shift shift-at call-with-shift) + +(define-prompt-macros reset reset-at call-with-continuation-prompt) + +;; ---------------------------------------- +;; Shan, SCHEME'04 +;; Kiselyov, Indiana CS TR-611, 2005 +;; +;; The `control0' and `shift0' here are closer to Kiselyov, in that +;; `control0' and `shift0' only behave as in Shan when paired with +;; `prompt0' or `reset0' (which are two names for the same thing). +;; When paired with `prompt' or `reset' (again, the same thing), +;; they act like `control' and `shift'. +;; +;; This difference is intentional. The programmer that inserts a +;; prompt should choose whether the current continuation is visible +;; or not. Note, also, that `control' and `shift' work whether +;; they're paired with `prompt'/`reset' or `prompt0'/`reset0'. + +(define call-with-control0 + ;; Uses abort-current-continuation, so that the prompt + ;; is removed --- if the prompt is willing to be removed. + (make-call-with-control abort-current-continuation)) + +(define call-with-shift0 + ;; Uses abort-current-continuation, so that the prompt + ;; is removed --- if the prompt is willing to be removed. + ;; The prompt installed with the captured continuation is + ;; itself willing to be removed. + (make-call-with-shift abort-current-continuation (lambda (thunk) (thunk)))) + +(define-control-macros control0 control0-at call-with-control0) + +(define-control-macros shift0 shift0-at call-with-shift0) + +(define call-with-prompt0 + (case-lambda + [(thunk) (call-with-prompt0 thunk (default-continuation-prompt-tag))] + [(thunk tag) + (call-with-continuation-prompt thunk tag (lambda (thunk) (thunk)))])) + +(define-prompt-macros prompt0 prompt0-at call-with-prompt0) + +(define-prompt-macros reset0 reset0-at call-with-prompt0) + +;; ---------------------------------------- +;; Hieb & Dybvig, PPOPP'90 + +(define (spawn f) + (let ([p (make-continuation-prompt-tag)]) + (call-with-continuation-prompt + (lambda () + (f (lambda (f) + (call-with-composable-continuation + (lambda (k) + (abort-current-continuation + p + (lambda () + (f (lambda vals + (call-with-continuation-prompt + (lambda () + (apply k vals)) + p + (lambda (thunk) (thunk)))))))) + p)))) + p + (lambda (thunk) (thunk))))) + +;; ---------------------------------------- +;; Queinnec & Serpette, POPL'91 + +(define (splitter receiver) + (let ([p (make-continuation-prompt-tag)]) + (call-with-continuation-prompt + (lambda () + (receiver (lambda (thunk) + (abort-current-continuation + p + thunk)) + (lambda (proc) + (call-with-composable-continuation + proc + p)))) + p + (lambda (thunk) (thunk))))) + +;; ---------------------------------------- +;; Gunter, Remy, & Rieke, FPLCA'95 +;; Unfortunately, the "prompt"s in Gunter et al. are what +;; we call "prompt tags". In our terminology, a "prompt" +;; is a tagged instance in a continuation. + +(define (new-prompt) (make-continuation-prompt-tag)) + +(define-syntax set (make-rename-transformer #'prompt0-at)) + +(define-syntax cupto (make-rename-transformer #'control0-at)) + +;; ---------------------------------------- -(require racket/control) -(provide (all-from-out racket/control)) diff --git a/collects/mzlib/date.rkt b/collects/mzlib/date.rkt index 558aea2485..c37deeabdd 100644 --- a/collects/mzlib/date.rkt +++ b/collects/mzlib/date.rkt @@ -1,6 +1,367 @@ #lang racket/base +(require racket/promise + racket/match + racket/list + racket/function + racket/contract/base) -;; deprecated library, see `racket/date` +(provide/contract + [current-date (-> date?)] + [date->seconds ((date?) (any/c) . ->* . exact-integer?)] + [date->string ((date?) (any/c) . ->* . string?)] + [date-display-format (parameter/c (symbols 'american 'chinese 'german 'indian 'irish 'julian 'iso-8601 'rfc2822))] + [find-seconds (((integer-in 0 61) + (integer-in 0 59) + (integer-in 0 23) + (integer-in 1 31) + (integer-in 1 12) + exact-nonnegative-integer?) + (any/c) + . ->* . + exact-integer?)] + [date->julian/scalinger (date? . -> . exact-integer?)] + [julian/scalinger->string (exact-integer? . -> . string?)]) -(require racket/date) -(provide (all-from-out racket/date)) +(define (current-date) + (seconds->date (current-seconds))) + +;; Support for Julian calendar added by Shriram; +;; current version only works until 2099 CE Gregorian + +(define date-display-format + (make-parameter 'american)) + +(define (month/number->string x) + (case x + [(12) "December"] [(1) "January"] [(2) "February"] + [(3) "March"] [(4) "April"] [(5) "May"] + [(6) "June"] [(7) "July"] [(8) "August"] + [(9) "September"] [(10) "October"] [(11) "November"] + [else ""])) + +(define (day/number->string x) + (case x + [(0) "Sunday"] + [(1) "Monday"] + [(2) "Tuesday"] + [(3) "Wednesday"] + [(4) "Thursday"] + [(5) "Friday"] + [(6) "Saturday"] + [else ""])) + +(define (add-zero n) + (if (< n 10) + (string-append "0" (number->string n)) + (number->string n))) + +(define (date->string date [time? #f]) + (define year (number->string (date-year date))) + (define num-month (number->string (date-month date))) + (define week-day (day/number->string (date-week-day date))) + (define week-day-num (date-week-day date)) + (define month (month/number->string (date-month date))) + (define day (number->string (date-day date))) + (define day-th + (if (<= 11 (date-day date) 13) + "th" + (case (modulo (date-day date) 10) + [(1) "st"] + [(2) "nd"] + [(3) "rd"] + [(0 4 5 6 7 8 9) "th"]))) + (define hour (date-hour date)) + (define am-pm (if (>= hour 12) "pm" "am")) + (define hour24 (add-zero hour)) + (define hour12 + (number->string + (cond + [(zero? hour) 12] + [(> hour 12) (- hour 12)] + [else hour]))) + (define minute (add-zero (date-minute date))) + (define second (add-zero (date-second date))) + (define-values + (day-strs time-strs) + (case (date-display-format) + [(american) + (values (list week-day ", " month " " day day-th ", " year) + (list " " hour12 ":" minute ":" second am-pm))] + [(chinese) + (values + (list year "/" num-month "/" day + " \u661F\u671F" (case (date-week-day date) + [(0) "\u5929"] + [(1) "\u4E00"] + [(2) "\u4E8C"] + [(3) "\u4e09"] + [(4) "\u56DB"] + [(5) "\u4E94"] + [(6) "\u516D"] + [else ""])) + (list " " hour24 ":" minute ":" second))] + [(indian) + (values (list day "-" num-month "-" year) + (list " " hour12 ":" minute ":" second am-pm))] + [(german) + (values (list day ". " + (case (date-month date) + [(1) "Januar"] + [(2) "Februar"] + [(3) "M\344rz"] + [(4) "April"] + [(5) "Mai"] + [(6) "Juni"] + [(7) "Juli"] + [(8) "August"] + [(9) "September"] + [(10) "Oktober"] + [(11) "November"] + [(12) "Dezember"] + [else ""]) + " " year) + (list ", " hour24 "." minute))] + [(irish) + (values (list week-day ", " day day-th " " month " " year) + (list ", " hour12 ":" minute am-pm))] + [(julian) + (values (list (julian/scalinger->string + (date->julian/scalinger date))) + (list ", " hour24 ":" minute ":" second))] + [(iso-8601) + (values + (list year "-" (add-zero (date-month date)) "-" (add-zero (date-day date))) + (list " " hour24 ":" minute ":" second))] + [(rfc2822) + (values + (list (substring week-day 0 3) ", " day " " (substring month 0 3) " " year) + (list* " " hour24 ":" minute ":" second " " + (let* ([delta (date-time-zone-offset date)] + [hours (quotient delta 3600)] + [minutes (modulo (quotient delta 60) 60)]) + (list + (if (negative? delta) "-" "+") + (add-zero (abs hours)) + (add-zero minutes)))))] + [else (error 'date->string "unknown date-display-format: ~s" + (date-display-format))])) + (apply string-append + (if time? + (append day-strs time-strs) + day-strs))) + +(define (leap-year? year) + (or (= 0 (modulo year 400)) + (and (= 0 (modulo year 4)) + (not (= 0 (modulo year 100)))))) + +;; it's not clear what months mean in this context -- use days +(define-struct date-offset (second minute hour day year)) + +(define (fixup s x) (if (< s 0) (+ s x) s)) +(define (date- date1 date2) + (define second (- (date-second date1) (date-second date2))) + (define minute + (+ (- (date-minute date1) (date-minute date2)) + (if (< second 0) -1 0))) + (define hour + (+ (- (date-hour date1) (date-hour date2)) + (if (< minute 0) -1 0) + (cond [(equal? (date-dst? date1) (date-dst? date2)) 0] + [(date-dst? date1) -1] + [(date-dst? date2) 1]))) + (define day + (+ (- (date-year-day date1) (date-year-day date2)) + (if (< hour 0) -1 0))) + (define year + (+ (- (date-year date1) (date-year date2)) + (if (< day 0) -1 0))) + (make-date-offset + (fixup second 60) + (fixup minute 60) + (fixup hour 24) + (fixup day (if (leap-year? (date-year date1)) 366 365)) + year)) + +(define (one-entry b) + (string-append + (number->string (first b)) + " " + (second b) + (if (= 1 (first b)) "" "s"))) +(define (date-offset->string date [seconds? #f]) + (define fields + (list (list (date-offset-year date) "year") + (list (date-offset-day date) "day") + (list (date-offset-hour date) "hour") + (list (date-offset-minute date) "minute") + (list (if seconds? (date-offset-second date) 0) "second"))) + (define non-zero-fields + (filter (negate (compose (curry = 0) first)) fields)) + (match non-zero-fields + [(list) ""] + [(list one) (one-entry one)] + [_ + (for/fold ([string ""]) + ([b (in-list non-zero-fields)]) + (cond + [(= 0 (first b)) string] + [(string=? string "") + (string-append "and " + (one-entry b) + string)] + [else (string-append (one-entry b) ", " string)]))])) + +(define (days-per-month year month) + (cond + [(and (= month 2) (leap-year? year)) 29] + [(= month 2) 28] + [(<= month 7) (+ 30 (modulo month 2))] + [else (+ 30 (- 1 (modulo month 2)))])) + +(define (find-extreme-date-seconds start offset) + (let/ec found + (letrec ([find-between + (lambda (lo hi) + (let ([mid (floor (/ (+ lo hi) 2))]) + (if (or (and (positive? offset) (= lo mid)) + (and (negative? offset) (= hi mid))) + (found lo) + (let ([mid-ok? + (with-handlers ([exn:fail? (lambda (exn) #f)]) + (seconds->date mid) + #t)]) + (if mid-ok? + (find-between mid hi) + (find-between lo mid))))))]) + (let loop ([lo start][offset offset]) + (let ([hi (+ lo offset)]) + (with-handlers ([exn:fail? + (lambda (exn) + ; failed - must be between lo & hi + (find-between lo hi))]) + (seconds->date hi)) + ; succeeded; double offset again + (loop hi (* 2 offset))))))) + +(define get-min-seconds + (let ([d (delay (find-extreme-date-seconds (current-seconds) -1))]) + (lambda () + (force d)))) +(define get-max-seconds + (let ([d (delay (find-extreme-date-seconds (current-seconds) 1))]) + (lambda () + (force d)))) + +(define (date->seconds date [local-time? #t]) + (find-seconds + (date-second date) + (date-minute date) + (date-hour date) + (date-day date) + (date-month date) + (date-year date) + local-time?)) + +(define (find-seconds sec min hour day month year [local-time? #t]) + (define (signal-error msg) + (error 'find-secs (string-append + msg + " (inputs: ~a ~a ~a ~a ~a ~a)") + sec min hour day month year)) + (let loop ([below-secs (get-min-seconds)] + [secs (floor (/ (+ (get-min-seconds) (get-max-seconds)) 2))] + [above-secs (get-max-seconds)]) + (let* ([date (seconds->date secs local-time?)] + [compare + (let loop ([inputs (list year month day + hour min sec)] + [tests (list (date-year date) + (date-month date) + (date-day date) + (date-hour date) + (date-minute date) + (date-second date))]) + (cond + [(null? inputs) 'equal] + [else (let ([input (car inputs)] + [test (car tests)]) + (if (= input test) + (loop (cdr inputs) (cdr tests)) + (if (<= input test) + 'input-smaller + 'test-smaller)))]))]) + ; (printf "~a ~a ~a\n" compare secs (date->string date)) + (cond + [(eq? compare 'equal) secs] + [(or (= secs below-secs) (= secs above-secs)) + (signal-error "non-existent date")] + [(eq? compare 'input-smaller) + (loop below-secs (floor (/ (+ secs below-secs) 2)) secs)] + [(eq? compare 'test-smaller) + (loop secs (floor (/ (+ above-secs secs) 2)) above-secs)])))) + +;; date->julian/scalinger : +;; date -> number [julian-day] + +;; Note: This code is correct until 2099 CE Gregorian + +(define (date->julian/scalinger date) + (define day (date-day date)) + (define month (date-month date)) + (define d-year (date-year date)) + (define year (+ 4712 d-year)) + (define adj-year (if (< month 3) (sub1 year) year)) + (define cycle-number (quotient adj-year 4)) + (define cycle-position (remainder adj-year 4)) + (define base-day (+ (* 1461 cycle-number) (* 365 cycle-position))) + (define month-day-number + (case month + ((3) 0) + ((4) 31) + ((5) 61) + ((6) 92) + ((7) 122) + ((8) 153) + ((9) 184) + ((10) 214) + ((11) 245) + ((12) 275) + ((1) 306) + ((2) 337))) + (define total-days (+ base-day month-day-number day)) + (define total-days/march-adjustment (+ total-days 59)) + (define gregorian-adjustment + (cond + ((< adj-year 1700) 11) + ((< adj-year 1800) 12) + (else 13))) + (define final-date + (- total-days/march-adjustment + gregorian-adjustment)) + final-date) + +;; julian/scalinger->string : +;; number [julian-day] -> string [julian-day-format] + +(define (julian/scalinger->string julian-day) + (apply string-append + (cons "JD " + (reverse + (let loop ((reversed-digits (map number->string + (let loop ((jd julian-day)) + (if (zero? jd) null + (cons (remainder jd 10) + (loop (quotient jd 10)))))))) + (cond + ((or (null? reversed-digits) + (null? (cdr reversed-digits)) + (null? (cdr (cdr reversed-digits))) + (null? (cdr (cdr (cdr reversed-digits))))) + (list (apply string-append (reverse reversed-digits)))) + (else (cons (apply string-append + (list " " + (caddr reversed-digits) + (cadr reversed-digits) + (car reversed-digits))) + (loop (cdr (cdr (cdr reversed-digits)))))))))))) diff --git a/collects/mzlib/deflate.rkt b/collects/mzlib/deflate.rkt index 31d33e2f17..9ebc7bc095 100644 --- a/collects/mzlib/deflate.rkt +++ b/collects/mzlib/deflate.rkt @@ -1,6 +1,2242 @@ -#lang racket/base +#| +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1992-1993 Jean-loup Gailly + */ +|# +;; Taken from the gzip source distribution +;; Translated directly from C (obviously) by Matthew, July 2000 -;; deprecated library, see `file/gzip` +;; *** The original version that this code was taken from was +;; distributed with a GPL license, but later the code (later version of +;; it) was also included in zlib, which is distributed with an +;; LGPL-compatible license. I (Eli Barzilay) have tried to contact the +;; author, but no reply yet. -(require file/gzip) -(provide (all-from-out file/gzip)) +(module deflate mzscheme + + (provide deflate gzip-through-ports gzip) + + (require "unit200.rkt") + + (define (vector-ref* v i) + (let ([r (vector-ref v i)]) + (if (<= 0 r 255) r (error 'vector-ref "BOOM: ~s" r)))) + + (define (vector-set!* v i n) + (if (<= 0 n 255) (vector-set! v i n) (error 'vector-ref "BOOM!: ~s" n))) + + (define-syntax INSERT_STRING + (syntax-rules () + [(_ s match_head UPDATE_HASH window-vec head-vec prev-vec ins_h) + (begin (UPDATE_HASH (bytes-ref window-vec (+ s MIN_MATCH-1))) + (let ([mh (vector-ref head-vec (+ ins_h head-vec-delta))]) + (set! match_head mh) + (vector-set! prev-vec (bitwise-and s WMASK) mh)) + (vector-set! head-vec (+ head-vec-delta ins_h) s))])) + + (define-syntax pqremove + (syntax-rules () + [(_ tree top heap heap_len SMALLEST) + (begin (set! top (vector-ref heap SMALLEST)) + (vector-set! heap SMALLEST (vector-ref heap heap_len)) + (set! heap_len (sub1 heap_len)) + (pqdownheap tree SMALLEST))])) + + (define-syntax DEBUG (lambda (stx) #'(void))) + + (define-syntax Assert (lambda (stx) #'(void))) + + (define-syntax for + (syntax-rules (:= then do) + [(for n := start < end do body ...) + (for n := start then add1 < end do body ...)] + [(for n := start then next < end do body ...) + (let ([endval end]) + (let loop ([n start]) + (when (< n endval) body ... (loop (next n)))))])) + + (define-struct gzbytes (bytes offset)) + (define (gzbytes-ref v o) + (bytes-ref (gzbytes-bytes v) (+ (gzbytes-offset v) o))) + (define (gzbytes-set! v o x) + (bytes-set! (gzbytes-bytes v) (+ (gzbytes-offset v) o) x)) + (define (gzbytes+ v o) + (make-gzbytes (gzbytes-bytes v) (+ (gzbytes-offset v) o))) + + (define (Trace stderr str . args) + (apply eprintf str args)) + (define Tracevv Trace) + (define Tracev Trace) + (define (Tracec test . args) + (when test (apply Trace args))) + (define Tracecv Tracec) + (define stderr 'sdterr) + +#| +/* + * PURPOSE + * + * Identify new text as repetitions of old text within a fixed- + * length sliding window trailing behind the new text. + * + * DISCUSSION + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many info-zippers for bug reports and testing. + * + * REFERENCES + * + * APPNOTE.TXT documentation file in PKZIP 1.93a distribution. + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + * INTERFACE + * + * void lm_init (int pack_level, ush *flags) + * Initialize the "longest match" routines for a new file + * + * ulg deflate (void) + * Processes a new input file and return its compressed length. Sets + * the compressed length, crc, deflate flags and internal file + * attributes. + */ + +|# + + (define LEVEL 6) + + (define OUTBUFSIZ 16384);; /* output buffer size */ + (define INBUFSIZ #x8000);; /* input buffer size */ + (define INBUF_EXTRA 64) + + (define WSIZE #x8000) ;; /* window size--must be a power of two, and */ + ;; /* at least 32K for zip's deflate method */ + + (define MIN_MATCH 3) + (define MIN_MATCH-1 (- MIN_MATCH 1)) + (define MAX_MATCH 258) + ;; /* The minimum and maximum match lengths */ + + (define MIN_LOOKAHEAD (+ MAX_MATCH MIN_MATCH 1)) + ;; /* Minimum amount of lookahead, except at the end of the input file. + ;; * See for comments about the MIN_MATCH+1. + ;; */ + + (define MAX_DIST (- WSIZE MIN_LOOKAHEAD)) + ;; /* In order to simplify the code, particularly on 16 bit machines, match + ;; * distances are limited to MAX_DIST instead of WSIZE. + ;; */ + + (define HASH_BITS 15) + (define BITS 16) + + (define << arithmetic-shift) + (define (>> x y) (arithmetic-shift x (- y))) + (define EOF-const -1) + + ;; /* To save space (see unlzw.c), we overlay prev+head with tab_prefix and + ;; * window with tab_suffix. Check that we can do this: + ;; */ + (Assert + (when (> (<< WSIZE 1) (<< 1 BITS)) + (error "cannot overlay window with tab_suffix and prev with tab_prefix0"))) + (Assert + (when (> HASH_BITS (- BITS 1)) + (error "cannot overlay head with tab_prefix1"))) + + (define HASH_SIZE (<< 1 HASH_BITS)) + (define HASH_MASK (- HASH_SIZE 1)) + (define WMASK (- WSIZE 1)) + ;; /* HASH_SIZE and WSIZE must be powers of two */ + + (define NIL 0) + ;; /* Tail of hash chains */ + + (define FAST 4) + (define SLOW 2) + ;; /* speed options for the general purpose bit flag */ + + (define TOO_FAR 4096) + ;; /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + + (define bits_sent 0) + (define (isgraph c) #t) + +(define head-vec-delta WSIZE) + + ;; The gzip code wasn't defined for threads (or even to be + ;; multiply invoked), so we pack it up into a unit to + ;; invoke each time we need it. + + (define code + (unit + (import) + (export) + + +;; /* =========================================================================== +;; * Local data used by the "longest match" routines. +;; */ + +(define real-table (make-vector (<< 1 BITS) 0)) + +(define prev-vec real-table) +(define head-vec real-table) + +;; /* DECLARE(uch, window, 2L*WSIZE); */ +;; /* Sliding window. Input bytes are read into the second half of the window, +;; * and move to the first half later to keep a dictionary of at least WSIZE +;; * bytes. With this organization, matches are limited to a distance of +;; * WSIZE-MAX_MATCH bytes, but this ensures that IO is always +;; * performed with a length multiple of the block size. Also, it limits +;; * the window size to 64K, which is quite useful on MSDOS. +;; * To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would +;; * be less efficient). +;; */ + +;; /* DECLARE(Pos, prev, WSIZE); */ +;; /* Link to older string with same hash index. To limit the size of this +;; * array to 64K, this link is maintained only for the last 32K strings. +;; * An index in this array is thus a window index modulo 32K. +;; */ + +;; /* DECLARE(Pos, head, 1<= HASH_BITS +;; */ + +(define prev_length 0) +;; /* Length of the best match at previous step. Matches not greater than this +;; * are discarded. This is used in the lazy match evaluation. +;; */ + +(define strstart 0) ;; /* start of string to insert */ +(define match_start 0) ;; /* start of matching string */ +(define eofile #f) ;; /* flag set at end of input file */ +(define lookahead 0) ;; /* number of valid bytes ahead in window */ + +(define max_chain_length 0) +;; /* To speed up deflation, hash chains are never searched beyond this length. +;; * A higher limit improves compression ratio but degrades the speed. +;; */ + +(define max_lazy_match 0) +;; /* Attempt to find a better match only when the current match is strictly +;; * smaller than this value. This mechanism is used only for compression +;; * levels >= 4. +;; */ + +(define (max_insert_length) max_lazy_match) +;; /* Insert new strings in the hash table only if the match length +;; * is not greater than this length. This saves time but degrades compression. +;; * max_insert_length is used only for compression levels <= 3. +;; */ + +(define good_match 0) +;; /* Use a faster search when the previous match is longer than this */ + + +;; /* Values for max_lazy_match, good_match and max_chain_length, depending on +;; * the desired pack level (0..9). The values given below have been tuned to +;; * exclude worst case performance for pathological files. Better values may be +;; * found for specific files. +;; */ + +(define-struct config + (good_length ;; /* reduce lazy search above this match length */ + max_lazy ;; /* do not perform lazy search above this match length */ + nice_length ;; /* quit search above this match length */ + max_chain)) + +(define nice_match MAX_MATCH) +;; /* Stop searching when current match exceeds this */ + +(define configuration_table + (vector + ;; /* good lazy nice chain */ + (make-config 0 0 0 0) ;; /* 0 - store only */ + (make-config 4 4 8 4) ;; /* 1 - maximum speed, no lazy matches */ + (make-config 4 5 16 8) ;; /* 2 */ + (make-config 4 6 32 32) ;; /* 3 */ + + (make-config 4 4 16 16) ;; /* 4 - lazy matches */ + (make-config 8 16 32 32) ;; /* 5 */ + (make-config 8 16 128 128) ;; /* 6 */ + (make-config 8 32 128 256) ;; /* 7 */ + (make-config 32 128 258 1024) ;; /* 8 */ + (make-config 32 258 258 4096))) ;; /* 9 - maximum compression */ + +;; /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 +;; * For deflate_fast() (levels <= 3) good is ignored and lazy has a different +;; * meaning. +;; */ + +;; /* =========================================================================== +;; * Update a hash value with the given input byte +;; * IN assertion: all calls to to UPDATE_HASH are made with consecutive +;; * input characters, so that a running hash key can be computed from the +;; * previous key instead of complete recalculation each time. +;; */ +(define (UPDATE_HASH c) + (set! ins_h (bitwise-and (bitwise-xor (<< ins_h H_SHIFT) c) HASH_MASK))) + +;; /* =========================================================================== +;; * Insert string s in the dictionary and set match_head to the previous head +;; * of the hash chain (the most recent string with same hash key). Return +;; * the previous length of the hash chain. +;; * IN assertion: all calls to to INSERT_STRING are made with consecutive +;; * input characters and the first MIN_MATCH bytes of s are valid +;; * (except for the last MIN_MATCH-1 bytes of the input file). +;; */ +;; (define-macro INSERT_STRING ) + +;; /* =========================================================================== +;; * Initialize the "longest match" routines for a new file +;; */ +(define (lm_init pack_level) + ;; int pack_level; /* 0: store, 1: best speed, 9: best compression */ + + (when (or (< pack_level 1) + (> pack_level 9)) + (error "bad pack level")) + + ;; /* Initialize the hash table. */ + (for i := head-vec-delta < (+ head-vec-delta HASH_SIZE) do + (vector-set! head-vec i 0)) + + ;; /* prev will be initialized on the fly */ + + ;; /* Set the default configuration parameters: + ;; */ + (set! max_lazy_match (config-max_lazy (vector-ref configuration_table pack_level))) + (set! good_match (config-good_length (vector-ref configuration_table pack_level))) + (set! nice_match (config-nice_length (vector-ref configuration_table pack_level))) + (set! max_chain_length (config-max_chain (vector-ref configuration_table pack_level))) + + (let ([flag (cond + [(= pack_level 1) FAST] + [(= pack_level 9) SLOW] + [else 0])]) + ;; /* ??? reduce max_chain_length for binary files */ + + (set! strstart 0) + (set! block_start 0) + + (set! lookahead (read_buf 0 (* 2 WSIZE))) + + (if (or (= lookahead 0) (= lookahead EOF-const)) + (begin + (set! eofile #t) + (set! lookahead 0)) + (begin + (set! eofile #f) + ;; /* Make sure that we always have enough lookahead. This is important + ;; * if input comes from a device such as a tty. + ;; */ + (let loop () + (when (and (< lookahead MIN_LOOKAHEAD) + (not eofile)) + (fill_window))) + + (set! ins_h 0) + (for j := 0 < MIN_MATCH-1 do (UPDATE_HASH (bytes-ref window-vec j))) + (DEBUG (Trace stderr "hash init: ~a\n" ins_h)) + ;; /* If lookahead < MIN_MATCH, ins_h is garbage, but this is + ;; * not important since only literal bytes will be emitted. + ;; */ + )) + + flag)) + +;; /* =========================================================================== +;; * Set match_start to the longest match starting at the given string and +;; * return its length. Matches shorter or equal to prev_length are discarded, +;; * in which case the result is equal to prev_length and match_start is +;; * garbage. +;; * IN assertions: cur_match is the head of the hash chain for the current +;; * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 +;; */ + +;; Since longest_match is not called recursively or in multiple threads, we can +;; make this C-derived code have more C-like allocation by lifting out its local +;; variables. + +(define longest_match + (let ((cur_match 0) + (chain_length 0) + (scanpos 0) + (matchpos 0) + (len 0) + (best_len 0) + (limit NIL) + (strendpos 0) + (scan_end1 0) + (scan_end 0)) + + (define (longest_match _cur_match) + ;; IPos cur_match; /* current match */ + + (set! cur_match _cur_match) + + (set! chain_length max_chain_length) ;; /* max hash chain length */ + (set! scanpos strstart) ;; /* current string */ + (set! matchpos 0) ;; /* matched string */ + (set! len 0) ;; /* length of current match */ + (set! best_len prev_length) ;; /* best match length so far */ + (set! limit (if (> strstart MAX_DIST) + (- strstart MAX_DIST) + NIL)) + ;; /* Stop when cur_match becomes <= limit. To simplify the code, + ;; * we prevent matches with the string of window index 0. + ;; */ + + ;; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + ;; * It is easy to get rid of this optimization if necessary. + ;; */ + ;; #if HASH_BITS < 8 || MAX_MATCH != 258 + ;; error: Code too clever + ;; #endif + + (set! strendpos (+ strstart MAX_MATCH)) + (set! scan_end1 (bytes-ref window-vec (+ scanpos best_len -1))) + (set! scan_end (bytes-ref window-vec (+ scanpos best_len))) + + ;; /* Do not waste too much time if we already have a good match: */ + (when (>= prev_length good_match) + (set! chain_length (>> chain_length 2))) + + (Assert + (unless (<= strstart (- window_size MIN_LOOKAHEAD)) + (error "insufficient lookahead"))) + + (longest_match-loop) + + best_len) + + (define (continue) + (set! cur_match (vector-ref prev-vec (bitwise-and cur_match WMASK))) + (when (and (> cur_match limit) + (begin + (set! chain_length (sub1 chain_length)) + (positive? chain_length))) + (longest_match-loop))) + (define (*++scan) + (set! scanpos (add1 scanpos)) + (and (scanpos . < . window_size) ; the original C code can read past the end of the buffer + (bytes-ref window-vec scanpos))) + (define (*++match) + (set! matchpos (add1 matchpos)) + (bytes-ref window-vec matchpos)) + + (define (match-eight) + (when (and (eq? (*++scan) (*++match)) (eq? (*++scan) (*++match)) + (eq? (*++scan) (*++match)) (eq? (*++scan) (*++match)) + (eq? (*++scan) (*++match)) (eq? (*++scan) (*++match)) + (eq? (*++scan) (*++match)) (eq? (*++scan) (*++match)) + (< scanpos strendpos)) + (match-eight))) + + (define (longest_match-loop) + + (Assert + (unless (< cur_match strstart) + (error "no future"))) + + (set! matchpos cur_match) + + ;; /* Skip to next match if the match length cannot increase + ;; * or if the match length is less than 2: + ;; */ + + (if (or (not (eq? (bytes-ref window-vec (+ matchpos best_len)) scan_end)) + (not (eq? (bytes-ref window-vec (+ matchpos best_len -1)) scan_end1)) + (not (eq? (bytes-ref window-vec matchpos) (bytes-ref window-vec scanpos))) + (not (eq? (begin (set! matchpos (add1 matchpos)) + (bytes-ref window-vec matchpos)) + (bytes-ref window-vec (add1 scanpos))))) + (continue) + + (begin + ;; /* The check at best_len-1 can be removed because it will be made + ;; * again later. (This heuristic is not always a win.) + ;; * It is not necessary to compare scan[2] and match[2] since they + ;; * are always equal when the other bytes match, given that + ;; * the hash keys are equal and that HASH_BITS >= 8. + ;; */ + (set! scanpos (+ scanpos 2)) + (set! matchpos (+ matchpos 1)) + + ;; /* We check for insufficient lookahead only every 8th comparison; + ;; * the 256th check will be made at strstart+258. + ;; */ + (match-eight) + + (set! len (- MAX_MATCH (- strendpos scanpos))) + (set! scanpos (+ strendpos (- MAX_MATCH))) + (DEBUG (Trace stderr "Match: ~a\n" len)) + + (when (begin + (if (> len best_len) + (begin + (set! match_start cur_match) + (set! best_len len) + (if (>= len nice_match) + #f + (begin + (set! scan_end1 (bytes-ref window-vec (+ scanpos best_len -1))) + (set! scan_end (bytes-ref window-vec (+ scanpos best_len))) + #t))) + #t)) + (continue))))) + longest_match)) + +;; /* =========================================================================== +;; * Check that the match at match_start is indeed a match. +;; */ +;; +(define (check_match start match length) + #t) + +;; /* =========================================================================== +;; * Fill the window when the lookahead becomes insufficient. +;; * Updates strstart and lookahead, and sets eofile if end of input file. +;; * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 +;; * OUT assertions: at least one byte has been read, or eofile is set; +;; * file reads are performed for at least two bytes (required for the +;; * translate_eol option). +;; */ +(define (fill_window) + (define more (- window_size lookahead strstart)) + ;; /* Amount of free space at the end of the window. */ + + ;; /* If the window is almost full and there is insufficient lookahead, + ;; * move the upper half to the lower one to make room in the upper half. + ;; */ + (when (>= strstart (+ WSIZE MAX_DIST)) + (let ([bs (gzbytes-bytes window)] [ofs (gzbytes-offset window)]) + (bytes-copy! bs ofs bs (+ ofs WSIZE) (+ ofs WSIZE WSIZE))) + (set! match_start (- match_start WSIZE)) + (set! strstart (- strstart WSIZE)) ;; /* we now have strstart >= MAX_DIST: */ + + (set! block_start (- block_start WSIZE)) + + (for n := 0 < HASH_SIZE do + (let ([m (vector-ref head-vec (+ n head-vec-delta))]) + (vector-set! head-vec (+ n head-vec-delta) + (if (>= m WSIZE) (- m WSIZE) NIL)))) + + (for n := 0 < WSIZE do + (let ([m (vector-ref prev-vec n)]) + (vector-set! prev-vec n + (if (>= m WSIZE) (- m WSIZE) NIL))) + ;; /* If n is not on any hash chain, prev[n] is garbage but + ;; * its value will never be used. + ;; */ + ) + + (set! more (+ more WSIZE))) + + (when (not eofile) + (let ([n (read_buf (+ strstart lookahead) more)]) + (if (or (= n 0) (= n EOF-const)) + (set! eofile #t) + (set! lookahead (+ lookahead n)))))) + +;; /* =========================================================================== +;; * Flush the current block, with given end-of-file flag. +;; * IN assertion: strstart is set to the end of the current match. +;; */ +(define (FLUSH-BLOCK eof) + (flush_block (and (>= block_start 0) (gzbytes+ window block_start)) + (- strstart block_start) + eof)) + +;; /* =========================================================================== +;; * Same as above, but achieves better compression. We use a lazy +;; * evaluation for matches: a match is finally adopted only if there is +;; * no better match at the next window position. +;; */ +(define (do-deflate) + (define hash_head 0) ;; /* head of hash chain */ + (define prev_match 0) ;; /* previous match */ + (define flush #f) ;; /* set if current block must be flushed */ + (define match_available #f) ;; /* set if previous match exists */ + (define match_length MIN_MATCH-1) ;; /* length of best match */ + + ;; /* Process the input block. */ + (let dloop () + (when (not (zero? lookahead)) + (DEBUG (Trace stderr + "prep ~a ~a ~a ~a ~a ~a ~a ~a ~a ~a\n" hash_head prev_length match_length max_lazy_match strstart + ins_h (+ strstart MIN_MATCH-1) (bytes-ref window-vec (+ strstart MIN_MATCH-1)) + H_SHIFT HASH_MASK)) + + ;; /* Insert the string window[strstart .. strstart+2] in the + ;; * dictionary, and set hash_head to the head of the hash chain: + ;; */ + (INSERT_STRING strstart hash_head UPDATE_HASH window-vec head-vec prev-vec ins_h) + + (DEBUG (Trace stderr + "inh ~a ~a ~a ~a ~a ~a ~a\n" hash_head prev_length match_length max_lazy_match strstart + ins_h (bytes-ref window-vec (+ strstart MIN_MATCH-1)))) + + ;; /* Find the longest match, discarding those <= prev_length. + ;; */ + (set! prev_length match_length) + (set! prev_match match_start) + (set! match_length MIN_MATCH-1) + + (when (and (not (= hash_head NIL)) + (< prev_length max_lazy_match) + (<= (- strstart hash_head) MAX_DIST)) + ;; /* To simplify the code, we prevent matches with the string + ;; * of window index 0 (in particular we have to avoid a match + ;; * of the string with itself at the start of the input file). + ;; */ + (set! match_length (longest_match hash_head)) + (DEBUG (Trace stderr "blip ~a\n" match_length)) + ;; /* longest_match() sets match_start */ + (when (> match_length lookahead) + (set! match_length lookahead)) + + ;; /* Ignore a length 3 match if it is too distant: */ + (when (and (= match_length MIN_MATCH) + (> (- strstart match_start) TOO_FAR)) + ;; /* If prev_match is also MIN_MATCH, match_start is garbage + ;; * but we will ignore the current match anyway. + ;; */ + (set! match_length (sub1 match_length)))) + + ;; /* If there was a match at the previous step and the current + ;; * match is not better, output the previous match: + ;; */ + (cond + [(and (>= prev_length MIN_MATCH) + (<= match_length prev_length)) + (DEBUG (Trace stderr "x1\n")) + + (check_match (- strstart 1) prev_match prev_length) + + (set! flush (ct_tally (- strstart 1 prev_match) + (- prev_length MIN_MATCH))) + + ;; /* Insert in hash table all strings up to the end of the match. + ;; * strstart-1 and strstart are already inserted. + ;; */ + (set! lookahead (- lookahead (- prev_length 1))) + (set! prev_length (- prev_length 2)) + (let loop () + (set! strstart (add1 strstart)) + (INSERT_STRING strstart hash_head UPDATE_HASH window-vec head-vec prev-vec ins_h) + (DEBUG (Trace stderr + "inhx ~a ~a ~a ~a ~a ~a\n" hash_head prev_length max_lazy_match strstart + ins_h (bytes-ref window-vec (+ strstart MIN_MATCH -1)))) + ;; /* strstart never exceeds WSIZE-MAX_MATCH, so there are + ;; * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + ;; * these bytes are garbage, but it does not matter since the + ;; * next lookahead bytes will always be emitted as literals. + ;; */ + (set! prev_length (sub1 prev_length)) + (when (not (= prev_length 0)) + (loop))) + (set! match_available #f) + (set! match_length MIN_MATCH-1) + (set! strstart (add1 strstart)) + (when flush + (DEBUG (Trace stderr "flush\n")) + (FLUSH-BLOCK 0) + (DEBUG (Trace stderr "flush done\n")) + (set! block_start strstart))] + + [match_available + (DEBUG (Trace stderr "x2\n")) + ;; /* If there was no match at the previous position, output a + ;; * single literal. If there was a match but the current match + ;; * is longer, truncate the previous match to a single literal. + ;; */ + ;; (Tracevv stderr "~c" (integer->char (vector-ref window-vec (- strstart 1)))) + (when (ct_tally 0 (bytes-ref window-vec (- strstart 1))) + (FLUSH-BLOCK 0) + (set! block_start strstart)) + (set! strstart (add1 strstart)) + (set! lookahead (sub1 lookahead))] + + [else + (DEBUG (Trace stderr "x3\n")) + ;; /* There is no previous match to compare with, wait for + ;; * the next step to decide. + ;; */ + (set! match_available #t) + (set! strstart (add1 strstart)) + (set! lookahead (sub1 lookahead))]) + + (Assert + (unless (and (<= strstart bytes_in) + (<= lookahead bytes_in)) + (error "a bit too far"))) + + ;; /* Make sure that we always have enough lookahead, except + ;; * at the end of the input file. We need MAX_MATCH bytes + ;; * for the next match, plus MIN_MATCH bytes to insert the + ;; * string following the next match. + ;; */ + (let loop () + (when (and (< lookahead MIN_LOOKAHEAD) + (not eofile)) + (DEBUG (Trace stderr "fill\n")) + (fill_window) + (loop))) + + (dloop))) + + (when match_available + (ct_tally 0 (bytes-ref window-vec (- strstart 1)))) + + (FLUSH-BLOCK 1)); /* eof */ + +#| +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1992-1993 Jean-loup Gailly + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License, see the file COPYING. + */ + +/* + * PURPOSE + * + * Encode various sets of source values using variable-length + * binary code trees. + * + * DISCUSSION + * + * The PKZIP "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in the ZIP file in a compressed form + * which is itself a Huffman encoding of the lengths of + * all the code strings (in ascending order by source values). + * The actual code strings are reconstructed from the lengths in + * the UNZIP process, as described in the "application note" + * (APPNOTE.TXT) distributed as part of PKWARE's PKZIP program. + * + * REFERENCES + * + * Lynch, Thomas J. + * Data Compression: Techniques and Applications, pp. 53-55. + * Lifetime Learning Publications, 1985. ISBN 0-534-03418-7. + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + * + * INTERFACE + * + * void ct_init (ush *attr, int *methodp) + * Allocate the match buffer, initialize the various tables and save + * the location of the internal file attribute (ascii/binary) and + * method (DEFLATE/STORE) + * + * void ct_tally (int dist, int lc); + * Save the match info and tally the frequency counts. + * + * long flush_block (char *buf, ulg stored_len, int eof) + * Determine the best encoding for the current block: dynamic trees, + * static trees or store, and output the encoded block to the zip + * file. Returns the total compressed length for the file so far. + * + */ + +|# + +;; /* =========================================================================== +;; * Constants +;; */ + +(define MAX_BITS 15) +;; /* All codes must not exceed MAX_BITS bits */ + +(define MAX_BL_BITS 7) +;; /* Bit length codes must not exceed MAX_BL_BITS bits */ + +(define LENGTH_CODES 29) +;; /* number of length codes, not counting the special END_BLOCK code */ + +(define LITERALS 256) +;; /* number of literal bytes 0..255 */ + +(define END_BLOCK 256) +;; /* end of block literal code */ + +(define L_CODES (+ LITERALS 1 LENGTH_CODES)) +;; /* number of Literal or Length codes, including the END_BLOCK code */ + +(define D_CODES 30) +;; /* number of distance codes */ + +(define BL_CODES 19) +;; /* number of codes used to transfer the bit lengths */ + +(define extra_lbits ;; /* extra bits for each length code */ + (vector 0 0 0 0 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 0)) + +(define extra_dbits ;; /* extra bits for each distance code */ + (vector 0 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13)) + +(define extra_blbits ;; /* extra bits for each bit length code */ + (vector 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 7)) + +(define STORED_BLOCK 0) +(define STATIC_TREES 1) +(define DYN_TREES 2) +;; /* The three kinds of block type */ + +(define LIT_BUFSIZE #x8000) +(define DIST_BUFSIZE #x8000) +;; /* Sizes of match buffers for literals/lengths and distances. There are +;; * 4 reasons for limiting LIT_BUFSIZE to 64K: +;; * - frequencies can be kept in 16 bit counters +;; * - if compression is not successful for the first block, all input data is +;; * still in the window so we can still emit a stored block even when input +;; * comes from standard input. (This can also be done for all blocks if +;; * LIT_BUFSIZE is not greater than 32K.) +;; * - if compression is not successful for a file smaller than 64K, we can +;; * even emit a stored file instead of a stored block (saving 5 bytes). +;; * - creating new Huffman trees less frequently may not provide fast +;; * adaptation to changes in the input data statistics. (Take for +;; * example a binary file with poorly compressible code followed by +;; * a highly compressible string table.) Smaller buffer sizes give +;; * fast adaptation but have of course the overhead of transmitting trees +;; * more frequently. +;; * - I can't count above 4 +;; * The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save +;; * memory at the expense of compression). Some optimizations would be possible +;; * if we rely on DIST_BUFSIZE == LIT_BUFSIZE. +;; */ +(when (> LIT_BUFSIZE INBUFSIZ) + (error "cannot overlay l_buf and inbuf")) + +(define REP_3_6 16) +;; /* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +(define REPZ_3_10 17) +;; /* repeat a zero length 3-10 times (3 bits of repeat count) */ + +(define REPZ_11_138 18) +;; /* repeat a zero length 11-138 times (7 bits of repeat count) */ + +;; /* =========================================================================== +;; * Local data +;; */ + +;; /* Data structure describing a single value and its code string. */ +(define-struct ct_data (freq code dad len)) +;; union { +;; ush freq; ;; /* frequency count */ +;; ush code; ;; /* bit string */ +;; } fc; +;; union { +;; ush dad; ;; /* father node in Huffman tree */ +;; ush len; ;; /* length of bit string */ +;; } dl; +#| +(define ct_data-freq ct_data-freq/code) +(define ct_data-code ct_data-freq/code) +(define ct_data-dad ct_data-dad/len) +(define ct_data-len ct_data-dad/len) +(define set-ct_data-freq! set-ct_data-freq/code!) +(define set-ct_data-code! set-ct_data-freq/code!) +(define set-ct_data-dad! set-ct_data-dad/len!) +(define set-ct_data-len! set-ct_data-dad/len!) +(define (_make-ct_data f c d l) (make-ct_data (or f c) (or d l))) +|# +(define _make-ct_data make-ct_data) + +(define HEAP_SIZE (+ (* 2 L_CODES) 1)) +;; /* maximum heap size */ + +(define dyn_ltree (make-vector HEAP_SIZE 'uninit-dl)) ;; /* literal and length tree */ +(define dyn_dtree (make-vector (+ (* 2 D_CODES) 1) 'uninit-dd)) ;; /* distance tree */ + +(define static_ltree (make-vector (+ L_CODES 2) 'uninit-sl)) +;; /* The static literal tree. Since the bit lengths are imposed, there is no +;; * need for the L_CODES extra codes used during heap construction. However +;; * The codes 286 and 287 are needed to build a canonical tree (see ct_init +;; * below). +;; */ + +(define static_dtree (make-vector D_CODES 'uninit-sd)) +;; /* The static distance tree. (Actually a trivial tree since all codes use +;; * 5 bits.) +;; */ + +(define bl_tree (make-vector (+ (* 2 BL_CODES) 1) 'uninit-dl)) +;; /* Huffman tree for the bit lengths */ + +(define-struct tree_desc + (dyn_tree; ;; /* the dynamic tree */ + static_tree; ;; /* corresponding static tree or NULL */ + extra_bits; ;; /* extra bits for each code or NULL */ + extra_base; ;; /* base index for extra_bits */ + elems; ;; /* max number of elements in the tree */ + max_length; ;; /* max bit length for the codes */ + max_code)); ;; /* largest code with non zero frequency */ + +(define l_desc (make-tree_desc + dyn_ltree static_ltree extra_lbits + (+ LITERALS 1) L_CODES MAX_BITS 0)) + +(define d_desc (make-tree_desc + dyn_dtree static_dtree extra_dbits + 0 D_CODES MAX_BITS 0)) + +(define bl_desc (make-tree_desc + bl_tree #f extra_blbits + 0 BL_CODES MAX_BL_BITS 0)) + + +(define bl_count (make-vector (+ MAX_BITS 1) 0)) +;; /* number of codes at each bit length for an optimal tree */ + +(define bl_order + (vector 16 17 18 0 8 7 9 6 10 5 11 4 12 3 13 2 14 1 15)) +;; /* The lengths of the bit length codes are sent in order of decreasing +;; * probability, to avoid transmitting the lengths for unused bit length codes. +;; */ + +(define heap (make-vector (+ (* 2 L_CODES) 1) 0)) ;; /* heap used to build the Huffman trees */ +(define heap_len 0) ;; /* number of elements in the heap */ +(define heap_max 0) ;; /* element of largest frequency */ +;; /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. +;; * The same heap array is used to build all trees. +;; */ + +(define depth (make-vector (+ (* 2 L_CODES) 1) 0)) +;; /* Depth of each subtree used as tie breaker for trees of equal frequency */ + +(define length_code (make-vector (- MAX_MATCH MIN_MATCH -1) 0)) +;; /* length code for each normalized match length (0 == MIN_MATCH) */ + +(define dist_code (make-vector 512 0)) +;; /* distance codes. The first 256 values correspond to the distances +;; * 3 .. 258, the last 256 values correspond to the top 8 bits of +;; * the 15 bit distances. +;; */ + +(define base_length (make-vector LENGTH_CODES 0)) +;; /* First normalized length for each code (0 = MIN_MATCH) */ + +(define base_dist (make-vector D_CODES 0)) +;; /* First normalized distance for each code (0 = distance of 1) */ + +(define inbuf (make-bytes (+ INBUFSIZ INBUF_EXTRA) 0)) +(define l_buf inbuf) +;; /* DECLARE(uch, l_buf, LIT_BUFSIZE); buffer for literals or lengths */ + +(define d_buf (make-vector DIST_BUFSIZE 0)) +;; /* DECLARE(ush, d_buf, DIST_BUFSIZE); buffer for distances */ + +(define flag_buf (make-vector (/ LIT_BUFSIZE 8) 0)) +;; /* flag_buf is a bit array distinguishing literals from lengths in +;; * l_buf, thus indicating the presence or absence of a distance. +;; */ + +(define last_lit 0) ;; /* running index in l_buf */ +(define last_dist 0) ;; /* running index in d_buf */ +(define last_flags 0) ;; /* running index in flag_buf */ +(define flags 0) ;; /* current flags not yet saved in flag_buf */ +(define flag_bit 0) ;; /* current bit used in flags */ +;; /* bits are filled in flags starting at bit 0 (least significant). +;; * Note: these flags are overkill in the current code since we don't +;; * take advantage of DIST_BUFSIZE == LIT_BUFSIZE. +;; */ + +(define opt_len 0); ;; /* bit length of current block with optimal trees */ +(define static_len 0); ;; /* bit length of current block with static trees */ + +(define compressed_len 0); ;; /* total bit length of compressed file */ + +(define input_len 0); ;; /* total byte length of input file */ +;; /* input_len is for debugging only since we can get it by other means. */ + +;; (define block_start 0); ;; /* window offset of current block */ +;; (define strstart 0); ;; /* window offset of current string */ + +(define (send_code c tree) + (send_bits (ct_data-code (vector-ref tree c)) + (ct_data-len (vector-ref tree c)))) +;; /* Send a code of the given tree. c and tree must not have side effects */ + +(define (d_code dist) + (if (< dist 256) + (vector-ref dist_code dist) + (vector-ref dist_code (+ 256 (>> dist 7))))) +;; /* Mapping from a distance to a distance code. dist is the distance - 1 and +;; * must not have side effects. dist_code[256] and dist_code[257] are never +;; * used. +;; */ + +;; /* =========================================================================== +;; * Allocate the match buffer, initialize the various tables and save the +;; * location of the internal file attribute (ascii/binary) and method +;; * (DEFLATE/STORE). +;; */ +(define (ct_init) + + (define length 0) ;; /* length value */ + (define dist 0) ;; /* distance index */ + + (set! compressed_len 0) + (set! input_len 0) + + (unless (ct_data? (vector-ref static_dtree 0)) ;; /* ct_init already called? */ + ;; /* Initialize the mapping length (0..255) -> length code (0..28) */ + (set! length 0) + (for code := 0 < (- LENGTH_CODES 1) do + (vector-set! base_length code length) + (for n := 0 < (<< 1 (vector-ref extra_lbits code)) do + (vector-set! length_code length code) + (set! length (add1 length)))) + + (Assert + (unless (= length 256) + (error "ct_init: length != 256"))) + + ;; /* Note that the length 255 (match length 258) can be represented + ;; * in two different ways: code 284 + 5 bits or code 285, so we + ;; * overwrite length_code[255] to use the best encoding: + ;; */ + (vector-set! length_code (- length 1) (- LENGTH_CODES 1)) + + ;; /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + (set! dist 0) + (for code := 0 < 16 do + (vector-set! base_dist code dist) + (for n := 0 < (<< 1 (vector-ref extra_dbits code)) do + (vector-set! dist_code dist code) + (set! dist (add1 dist)))) + + (Assert + (unless (= dist 256) + (error "ct_init: dist != 256"))) + (set! dist (>> dist 7)) ;; /* from now on, all distances are divided by 128 */ + (for code := 16 < D_CODES do + (vector-set! base_dist code (<< dist 7)) + (for n := 0 < (<< 1 (- (vector-ref extra_dbits code) 7)) do + (vector-set! dist_code (+ 256 dist) code) + (set! dist (add1 dist)))) + + (Assert + (unless (= dist 256) + (error "ct_init: 256+dist != 512"))) + + ;; /* Construct the codes of the static literal tree */ + (for bits := 0 <= MAX_BITS do + (vector-set! bl_count bits 0)) + + (let ([init-ltree + (lambda (s e v) + (for n := s <= e do + (vector-set! static_ltree n (_make-ct_data #f 0 #f v)) + (vector-set! bl_count v (add1 (vector-ref bl_count v)))))]) + (init-ltree 0 143 8) + (init-ltree 144 255 9) + (init-ltree 256 279 7) + (init-ltree 280 287 8)) + ;; /* Codes 286 and 287 do not exist, but we must include them in the + ;; * tree construction to get a canonical Huffman tree (longest code + ;; * all ones) + ;; */ + (gen_codes static_ltree (+ L_CODES 1)) + + ;; /* The static distance tree is trivial: */ + (for n := 0 < D_CODES do + (vector-set! static_dtree n + (_make-ct_data #f (bi_reverse n 5) #f 5))) + + ;; /* Initialize the first block of the first file: */ + (init_block))) + +;; /* =========================================================================== +;; * Initialize a new block. +;; */ +(define inited-once? #f) +(define (init_block) + (for n := 0 < (if inited-once? L_CODES HEAP_SIZE) do + (vector-set! dyn_ltree n (_make-ct_data 0 #f 0 #f))) + (for n := 0 < (if inited-once? D_CODES (+ (* 2 D_CODES) 1)) do + (vector-set! dyn_dtree n (_make-ct_data 0 #f 0 #f))) + (for n := 0 < (if inited-once? BL_CODES (+ (* 2 BL_CODES) 1)) do + (vector-set! bl_tree n (_make-ct_data 0 #f 0 #f))) + + (set! inited-once? #t) + + (set-ct_data-freq! (vector-ref dyn_ltree END_BLOCK) 1) + (set! opt_len 0) + (set! static_len 0) + (set! last_lit 0) + (set! last_dist 0) + (set! last_flags 0) + (set! flags 0) + (set! flag_bit 1)) + +(define SMALLEST 1) +;; /* Index within the heap array of least frequent node in the Huffman tree */ + + +;; /* =========================================================================== +;; * Remove the smallest element from the heap and recreate the heap with +;; * one less element. Updates heap and heap_len. +;; */ +;; (define-macro pqremove ) + +;; /* =========================================================================== +;; * Compares to subtrees, using the tree depth as tie breaker when +;; * the subtrees have equal frequency. This minimizes the worst case length. +;; */ +(define (smaller tree n m) + (or (< (ct_data-freq (vector-ref tree n)) (ct_data-freq (vector-ref tree m))) + (and (= (ct_data-freq (vector-ref tree n)) (ct_data-freq (vector-ref tree m))) + (<= (vector-ref depth n) (vector-ref depth m))))) + +;; /* =========================================================================== +;; * Restore the heap property by moving down the tree starting at node k, +;; * exchanging a node with the smallest of its two sons if necessary, stopping +;; * when the heap property is re-established (each father smaller than its +;; * two sons). +;; */ +(define (pqdownheap tree k) + ;; ct_data near *tree; /* the tree to restore */ + ;; int k; /* node to move down */ + + (define v (vector-ref heap k)) + (define j (<< k 1)) ;; /* left son of k */ + (let loop ([k k][j j]) + (if (<= j heap_len) + ;; /* Set j to the smallest of the two sons: */ + (let ([j (if (and (< j heap_len) + (smaller tree + (vector-ref heap (+ j 1)) + (vector-ref heap j))) + (add1 j) + j)]) + ;; /* Exit if v is smaller than both sons */ + (if (smaller tree v (vector-ref heap j)) + (vector-set! heap k v) + (begin + ;; /* Exchange v with the smallest son */ + (vector-set! heap k (vector-ref heap j)) + ;; /* And continue down the tree, setting j to the left son of k */ + (loop j (<< j 1))))) + (vector-set! heap k v)))) + +;; /* =========================================================================== +;; * Compute the optimal bit lengths for a tree and update the total bit length +;; * for the current block. +;; * IN assertion: the fields freq and dad are set, heap[heap_max] and +;; * above are the tree nodes sorted by increasing frequency. +;; * OUT assertions: the field len is set to the optimal bit length, the +;; * array bl_count contains the frequencies for each bit length. +;; * The length opt_len is updated; static_len is also updated if stree is +;; * not null. +;; */ +(define (gen_bitlen desc) + ;; tree_desc near *desc; ;; /* the tree descriptor */ + + (define tree (tree_desc-dyn_tree desc)) + (define extra (tree_desc-extra_bits desc)) + (define base (tree_desc-extra_base desc)) + (define max_code (tree_desc-max_code desc)) + (define max_length (tree_desc-max_length desc)) + (define stree (tree_desc-static_tree desc)) + (define n 0) (define m 0) ;; /* iterate over the tree elements */ + (define bits 0) ;; /* bit length */ + (define xbits 0) ;; /* extra bits */ + (define f 0); ;; /* frequency */ + (define overflow 0); ;; /* number of elements with bit length too large */ + (define h 0) + + (for bits := 0 <= MAX_BITS do + (vector-set! bl_count bits 0)) + + ;; /* In a first pass, compute the optimal bit lengths (which may + ;; * overflow in the case of the bit length tree). + ;; */ + (set-ct_data-len! (vector-ref tree (vector-ref heap heap_max)) 0) ;; /* root of the heap */ + + (for h := (+ 1 heap_max) < HEAP_SIZE do + (set! n (vector-ref heap h)) + (set! bits (+ (ct_data-len (vector-ref tree (ct_data-dad (vector-ref tree n)))) 1)) + (when (> bits max_length) + (set! bits max_length) + (set! overflow (add1 overflow))) + (set-ct_data-len! (vector-ref tree n) bits) + ;; /* We overwrite tree[n].Dad which is no longer needed */ + (unless (> n max_code) + ;; /* leaf node */ + (vector-set! bl_count bits (add1 (vector-ref bl_count bits))) + (set! xbits 0) + (when (>= n base) + (set! xbits (vector-ref extra (- n base)))) + (set! f (ct_data-freq (vector-ref tree n))) + (set! opt_len (+ opt_len (* f (+ bits xbits)))) + (when stree + (set! static_len + (+ static_len + (* f (+ (ct_data-len (vector-ref stree n)) xbits))))))) + + (unless (= overflow 0) + + (DEBUG (Trace stderr "\nbit length overflow\n")) + ;; /* This happens for example on obj2 and pic of the Calgary corpus */ + + ;; /* Find the first bit length which could increase: */ + (let loop () + (set! bits (- max_length 1)) + (let loop () + (when (= (vector-ref bl_count bits) 0) + (set! bits (sub1 bits)) + (loop))) + (vector-set! bl_count bits (sub1 (vector-ref bl_count bits))) + (vector-set! bl_count (+ bits 1) (+ (vector-ref bl_count (+ bits 1)) 2)) + (vector-set! bl_count max_length (sub1 (vector-ref bl_count max_length))) + ;; /* The brother of the overflow item also moves one step up, + ;; * but this does not affect bl_count[max_length] + ;; */ + (set! overflow (- overflow 2)) + (when (> overflow 0) + (loop))) + + (set! h HEAP_SIZE) + ;; /* Now recompute all bit lengths, scanning in increasing frequency. + ;; * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + ;; * lengths instead of fixing only the wrong ones. This idea is taken + ;; * from 'ar' written by Haruhiko Okumura.) + ;; */ + (for bits := max_length then sub1 > 0 do + (set! n (vector-ref bl_count bits)) + (let loop () + (when (not (= n 0)) + (set! h (sub1 h)) + (set! m (vector-ref heap h)) + (if (> m max_code) + (loop) + (begin + (when (not (= (ct_data-len (vector-ref tree m)) bits)) + (set! opt_len + (+ opt_len (* (- bits (ct_data-len (vector-ref tree m))) + (ct_data-freq (vector-ref tree m)))))) + (set-ct_data-len! (vector-ref tree m) bits) + (set! n (sub1 n)) + (loop)))))))) + +;; /* =========================================================================== +;; * Generate the codes for a given tree and bit counts (which need not be +;; * optimal). +;; * IN assertion: the array bl_count contains the bit length statistics for +;; * the given tree and the field len is set for all tree elements. +;; * OUT assertion: the field code is set for all tree elements of non +;; * zero code length. +;; */ +(define (gen_codes tree max_code) + ;; ct_data near *tree; /* the tree to decorate */ + ;; int max_code; /* largest code with non zero frequency */ + + (define next_code (make-vector (+ MAX_BITS 1) 0)) ;; /* next code value for each bit length */ + (define code 0) ;; /* running code value */ + (define bits 0) ;; /* bit index */ + + ;; /* The distribution counts are first used to generate the code values + ;; * without bit reversal. + ;; */ + (for bits := 1 <= MAX_BITS do + (set! code (<< (+ code (vector-ref bl_count (- bits 1))) 1)) + (vector-set! next_code bits code)) + ;; /* Check that the bit counts in bl_count are consistent. The last code + ;; * must be all ones. + ;; */ + (Assert + (unless (= (+ code (vector-ref bl_count MAX_BITS)-1) + (- (<< 1 MAX_BITS) 1)) + "inconsistent bit counts")) + (DEBUG (Tracev stderr "\ngen_codes: max_code ~a " max_code)) + + (for n := 0 <= max_code do + (let ([len (ct_data-len (vector-ref tree n))]) + (unless (= len 0) + ;; /* Now reverse the bits */ + (let ([nc (vector-ref next_code len)]) + (set-ct_data-code! (vector-ref tree n) (bi_reverse nc len)) + (vector-set! next_code len (add1 nc))) + + (DEBUG (Tracec (not (eq? tree static_ltree)) + stderr + "\nn ~a ~c l ~a c ~x (~x) " + n #\space len + (or (ct_data-code (vector-ref tree n)) 0) + (or (- (vector-ref next_code len) 1) 0))))))) + +;; /* =========================================================================== +;; * Construct one Huffman tree and assigns the code bit strings and lengths. +;; * Update the total bit length for the current block. +;; * IN assertion: the field freq is set for all tree elements. +;; * OUT assertions: the fields len and code are set to the optimal bit length +;; * and corresponding code. The length opt_len is updated; static_len is +;; * also updated if stree is not null. The field max_code is set. +;; */ +(define (build_tree desc) + ;; tree_desc near *desc; ;; /* the tree descriptor */ + + (define tree (tree_desc-dyn_tree desc)) + (define stree (tree_desc-static_tree desc)) + (define elems (tree_desc-elems desc)) + (define n 0) (define m 0) ;; /* iterate over heap elements */ + (define max_code -1) ;; /* largest code with non zero frequency */ + (define node elems) ;; /* next internal node of the tree */ + + ;; /* Construct the initial heap, with least frequent element in + ;; * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + ;; * heap[0] is not used. + ;; */ + (set! heap_len 0) + (set! heap_max HEAP_SIZE) + + (for n := 0 < elems do + (DEBUG (Trace stderr "freq: ~a ~a\n" n (ct_data-freq (vector-ref tree n)))) + (if (not (= (ct_data-freq (vector-ref tree n)) 0)) + (begin (set! heap_len (add1 heap_len)) + (set! max_code n) + (vector-set! heap heap_len n) + (vector-set! depth n 0)) + (set-ct_data-len! (vector-ref tree n) 0))) + + (DEBUG (Trace stderr "Building: ~a ~a ~a\n" elems heap_len max_code)) + + ;; /* The pkzip format requires that at least one distance code exists, + ;; * and that at least one bit should be sent even if there is only one + ;; * possible code. So to avoid special checks later on we force at least + ;; * two codes of non zero frequency. + ;; */ + (let loop () + (when (< heap_len 2) + (let ([new (if (< max_code 2) + (begin + (set! max_code (add1 max_code)) + max_code) + 0)]) + (set! heap_len (add1 heap_len)) + (vector-set! heap heap_len new) + (set-ct_data-freq! (vector-ref tree new) 1) + (vector-set! depth new 0) + (set! opt_len (sub1 opt_len)) + (when stree + (set! static_len (- static_len (ct_data-len (vector-ref stree new))))) + ;; /* new is 0 or 1 so it does not have extra bits */ + (loop)))) + + (set-tree_desc-max_code! desc max_code) + + ;; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + ;; * establish sub-heaps of increasing lengths: + ;; */ + (for n := (quotient heap_len 2) then sub1 >= 1 do (pqdownheap tree n)) + + ;; /* Construct the Huffman tree by repeatedly combining the least two + ;; * frequent nodes. + ;; */ + (let loop () + ;; /* n = node of least frequency */ + (set! n (vector-ref heap SMALLEST)) + (vector-set! heap SMALLEST (vector-ref heap heap_len)) + (set! heap_len (sub1 heap_len)) + (pqdownheap tree SMALLEST) + + (set! m (vector-ref heap SMALLEST)) ;; /* m = node of next least frequency */ + + (set! heap_max (sub1 heap_max)) + (vector-set! heap heap_max n) ;; /* keep the nodes sorted by frequency */ + (set! heap_max (sub1 heap_max)) + (vector-set! heap heap_max m) + + ;; /* Create a new node father of n and m */ + (set-ct_data-freq! (vector-ref tree node) + (+ (ct_data-freq (vector-ref tree n)) + (ct_data-freq (vector-ref tree m)))) + (vector-set! depth node (+ (max (vector-ref depth n) + (vector-ref depth m)) + 1)) + (set-ct_data-dad! (vector-ref tree n) node) + (set-ct_data-dad! (vector-ref tree m) node) + + ;; /* and insert the new node in the heap */ + (vector-set! heap SMALLEST node) + (set! node (add1 node)) + (pqdownheap tree SMALLEST) + + (when (>= heap_len 2) + (loop))) + + (set! heap_max (sub1 heap_max)) + (vector-set! heap heap_max (vector-ref heap SMALLEST)) + + ;; /* At this point, the fields freq and dad are set. We can now + ;; * generate the bit lengths. + ;; */ + (gen_bitlen desc) + + (DEBUG (Trace stderr "Build: ~a\n" max_code)) + ;; /* The field len is now set, we can generate the bit codes */ + (gen_codes tree max_code)) + +;; /* =========================================================================== +;; * Scan a literal or distance tree to determine the frequencies of the codes +;; * in the bit length tree. Updates opt_len to take into account the repeat +;; * counts. (The contribution of the bit length codes will be added later +;; * during the construction of bl_tree.) +;; */ +(define (scan_tree tree max_code) + ;; ct_data near *tree; ;; /* the tree to be scanned */ + ;; int max_code; ;; /* and its largest code of non zero frequency */ + + (define prevlen -1) ;; /* last emitted length */ + (define curlen 0) ;; /* length of current code */ + (define nextlen (ct_data-len (vector-ref tree 0))) ;; /* length of next code */ + (define count 0) ;; /* repeat count of the current code */ + (define max_count 7) ;; /* max repeat count */ + (define min_count 4) ;; /* min repeat count */ + + (when (= nextlen 0) + (set! max_count 138) + (set! min_count 3)) + + (set-ct_data-len! (vector-ref tree (+ max_code 1)) #xffff) ;; /* guard */ + + (for n := 0 <= max_code do + (let/ec continue + (define (inc-bl_tree-freq which amt) + (set-ct_data-freq! (vector-ref bl_tree which) + (+ amt (ct_data-freq (vector-ref bl_tree which))))) + + (set! curlen nextlen) + (set! nextlen (ct_data-len (vector-ref tree (+ n 1)))) + (set! count (add1 count)) + + (cond [(and (< count max_count) (= curlen nextlen)) + (continue)] + [(< count min_count) + (inc-bl_tree-freq curlen count)] + [(not (= curlen 0)) + (when (not (= curlen prevlen)) + (inc-bl_tree-freq curlen 1)) + (inc-bl_tree-freq REP_3_6 1)] + [(<= count 10) + (inc-bl_tree-freq REPZ_3_10 1)] + [else + (inc-bl_tree-freq REPZ_11_138 1)]) + + (set! count 0) + (set! prevlen curlen) + + (cond [(= nextlen 0) (set! max_count 138) (set! min_count 3)] + [(= curlen nextlen) (set! max_count 6) (set! min_count 3)] + [else (set! max_count 7) (set! min_count 4)])))) + +;; /* =========================================================================== +;; * Send a literal or distance tree in compressed form, using the codes in +;; * bl_tree. +;; */ +(define (send_tree tree max_code) + ;; ct_data near *tree; ;; /* the tree to be scanned */ + ;; int max_code; ;; /* and its largest code of non zero frequency */ + + (define prevlen -1) ;; /* last emitted length */ + (define curlen 0) ;; /* length of current code */ + (define nextlen (ct_data-len (vector-ref tree 0))) ;; /* length of next code */ + (define count 0) ;; /* repeat count of the current code */ + (define max_count 7) ;; /* max repeat count */ + (define min_count 4) ;; /* min repeat count */ + + ;; /* tree[max_code+1].Len = -1; */ ;; /* guard already set */ + (when (= nextlen 0) + (set! max_count 138) + (set! min_count 3)) + + (for n := 0 <= max_code do + (let/ec continue + (set! curlen nextlen) + (set! nextlen (ct_data-len (vector-ref tree (+ n 1)))) + + (set! count (add1 count)) + (cond [(and (< count max_count) (= curlen nextlen)) + (continue)] + [(< count min_count) + (let loop () + (send_code curlen bl_tree) + (set! count (sub1 count)) + (when (not (= count 0)) (loop)))] + [(not (= curlen 0)) + (when (not (= curlen prevlen)) + (send_code curlen bl_tree) + (set! count (sub1 count))) + (Assert + (unless (>= 6 count 3) + (error " 3_6?"))) + (send_code REP_3_6 bl_tree) + (send_bits (- count 3) 2)] + [(<= count 10) + (send_code REPZ_3_10 bl_tree) + (send_bits (- count 3) 3)] + [else + (send_code REPZ_11_138 bl_tree) + (send_bits (- count 11) 7)]) + + (set! count 0) + (set! prevlen curlen) + + (cond [(= nextlen 0) (set! max_count 138) (set! min_count 3)] + [(= curlen nextlen) (set! max_count 6) (set! min_count 3)] + [else (set! max_count 7) (set! min_count 4)])))) + +;; /* =========================================================================== +;; * Construct the Huffman tree for the bit lengths and return the index in +;; * bl_order of the last bit length code to send. +;; */ +(define (build_bl_tree) + (define max_blindex 0) ;; /* index of last bit length code of non zero freq */ + + ;; /* Determine the bit length frequencies for literal and distance trees */ + (scan_tree dyn_ltree (tree_desc-max_code l_desc)) + (scan_tree dyn_dtree (tree_desc-max_code d_desc)) + + ;; /* Build the bit length tree: */ + (build_tree bl_desc) + ;; /* opt_len now includes the length of the tree representations, except + ;; * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + ;; */ + + ;; /* Determine the number of bit length codes to send. The pkzip format + ;; * requires that at least 4 bit length codes be sent. (appnote.txt says + ;; * 3 but the actual value used is 4.) + ;; */ + (set! max_blindex (- BL_CODES 1)) + (let loop () + (when (and (>= max_blindex 3) + (= (ct_data-len (vector-ref bl_tree + (vector-ref bl_order max_blindex))) + 0)) + (set! max_blindex (sub1 max_blindex)) + (loop))) + + ;; /* Update opt_len to include the bit length tree and counts */ + (set! opt_len (+ opt_len (* 3 (+ max_blindex 1)) 5 5 4)) + (DEBUG (Tracev stderr "\ndyn trees: dyn ~a, stat ~a" opt_len static_len)) + + max_blindex) + +;; /* =========================================================================== +;; * Send the header for a block using dynamic Huffman trees: the counts, the +;; * lengths of the bit length codes, the literal tree and the distance tree. +;; * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. +;; */ +(define (send_all_trees lcodes dcodes blcodes) + ;; int lcodes, dcodes, blcodes; ;; /* number of codes for each tree */ + + (Assert + (unless (and (>= lcodes 257) + (>= dcodes 1) + (>= blcodes 4)) + (error "not enough codes"))) + (Assert + (unless (and (<= lcodes L_CODES) + (<= dcodes D_CODES) + (<= blcodes BL_CODES)) + (error "too many codes ~a(~a) ~a(~a) ~a(~a)" + lcodes L_CODES + dcodes D_CODES + blcodes BL_CODES))) + + (DEBUG (Tracev stderr "\nbl counts: ")) + + (send_bits (- lcodes 257) 5) ;; /* not +255 as stated in appnote.txt */ + (send_bits (- dcodes 1) 5) + (send_bits (- blcodes 4) 4) ;; /* not -3 as stated in appnote.txt */ + (for rank := 0 < blcodes do + (DEBUG (Tracev stderr "\nbl code ~a " (vector-ref bl_order rank))) + (send_bits (ct_data-len (vector-ref bl_tree (vector-ref bl_order rank))) + 3)) + (DEBUG (Tracev stderr "\nbl tree: sent ~a" bits_sent)) + + (send_tree dyn_ltree (- lcodes 1)) ;; /* send the literal tree */ + (DEBUG (Tracev stderr "\nlit tree: sent ~a" bits_sent)) + + (send_tree dyn_dtree (- dcodes 1)) ;; /* send the distance tree */ + (DEBUG (Tracev stderr "\ndist tree: sent ~a" bits_sent))) + +;; /* =========================================================================== +;; * Determine the best encoding for the current block: dynamic trees, static +;; * trees or store, and output the encoded block to the zip file. This function +;; * returns the total compressed length for the file so far. +;; */ +(define (flush_block buf stored_len eof) + ;; char *buf; ;; /* input block, or NULL if too old */ + ;; ulg stored_len; ;; /* length of input block */ + ;; int eof; ;; /* true if this is the last block for a file */ + + (define opt_lenb 0) (define static_lenb 0) ;; /* opt_len and static_len in bytes */ + (define max_blindex 0) ;; /* index of last bit length code of non zero freq */ + + (vector-set! flag_buf last_flags flags) ;; /* Save the flags for the last 8 items */ + + ;; /* Construct the literal and distance trees */ + (build_tree l_desc) + (DEBUG (Tracev stderr "\nlit data: dyn ~a, stat ~a" opt_len static_len)) + + (build_tree d_desc) + (DEBUG (Tracev stderr "\ndist data: dyn ~a, stat ~a" opt_len static_len)) + ;; /* At this point, opt_len and static_len are the total bit lengths of + ;; * the compressed block data, excluding the tree representations. + ;; */ + + ;; /* Build the bit length tree for the above two trees, and get the index + ;; * in bl_order of the last bit length code to send. + ;; */ + (set! max_blindex (build_bl_tree)) + + ;; /* Determine the best encoding. Compute first the block length in bytes */ + (set! opt_lenb (>> (+ opt_len 3 7) 3)) + (set! static_lenb (>> (+ static_len 3 7) 3)) + (set! input_len (+ input_len stored_len)) ;; /* for debugging only */ + + (DEBUG (Trace stderr "\nopt ~a(~a) stat ~a(~a) stored ~a lit ~a dist ~a " + opt_lenb opt_len static_lenb static_len stored_len + last_lit last_dist)) + + (when (<= static_lenb opt_lenb) + (set! opt_lenb static_lenb)) + + ;; /* If compression failed and this is the first and last block, + ;; * and if the zip file can be seeked (to rewrite the local header), + ;; * the whole file is transformed into a stored file: + ;; */ + (cond + [(and buf (<= (+ stored_len 4) opt_lenb)) + ;; /* 4: two words for the lengths */ + + ;; /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + ;; * Otherwise we can't have processed more than WSIZE input bytes since + ;; * the last block flush, because compression would have been + ;; * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + ;; * transform a block into a stored block. + ;; */ + (send_bits (+ (<< STORED_BLOCK 1) eof) 3) ;; /* send block type */ + (set! compressed_len (bitwise-and (+ compressed_len 3 7) (bitwise-not 7))) + (set! compressed_len (+ compressed_len (<< (+ stored_len 4) 3))) + + (copy_block buf stored_len #t)] ;; /* with header */ + [(= static_lenb opt_lenb) + (send_bits (+ (<< STATIC_TREES 1) eof) 3) + (compress_block static_ltree static_dtree) + (set! compressed_len (+ compressed_len 3 static_len))] + [else + (send_bits (+ (<< DYN_TREES 1) eof) 3) + (send_all_trees (+ (tree_desc-max_code l_desc) 1) + (+ (tree_desc-max_code d_desc) 1) + (+ max_blindex 1)) + (compress_block dyn_ltree dyn_dtree) + (set! compressed_len (+ compressed_len 3 opt_len))]) + + ;; Assert + ;; (unless (= compressed_len bits_sent) + ;; (error "bad compressed size")) + (init_block) + + (when (not (= eof 0)) + (Assert + (unless (= input_len bytes_in) + (newline (current-error-port)) + (error 'eof "bad input size: ~a != ~a" input_len bytes_in))) + (bi_windup) + (set! compressed_len ;; /* align on byte boundary */ + (+ compressed_len 7))) + + (DEBUG (Tracev stderr "\ncomprlen ~a(~a) " (>> compressed_len 3) + (- compressed_len (* 7 eof)))) + + (>> compressed_len 3)) + +;; /* =========================================================================== +;; * Save the match info and tally the frequency counts. Return true if +;; * the current block must be flushed. +;; */ +(define ct_tally + (let ([dist 0]) + (lambda (_dist lc) + ;; int dist; ;; /* distance of matched string */ + ;; int lc; ;; /* match length-MIN_MATCH or unmatched char (if dist==0) */ + + (set! dist _dist) + + (bytes-set! l_buf last_lit lc) + (set! last_lit (add1 last_lit)) + (if (= dist 0) + ;; /* lc is the unmatched char */ + (set-ct_data-freq! (vector-ref dyn_ltree lc) + (add1 (ct_data-freq (vector-ref dyn_ltree lc)))) + (begin + ;; /* Here, lc is the match length - MIN_MATCH */ + (set! dist (sub1 dist)) ;; /* dist = match distance - 1 */ + (Assert + (unless (and (< dist MAX_DIST) + (<= lc (- MAX_MATCH MIN_MATCH)) + (< (d_code dist) D_CODES)) + (error "ct_tally: bad match"))) + + (let* ([i (+ (vector-ref length_code lc) LITERALS 1)] + [ct (vector-ref dyn_ltree i)]) + (DEBUG (Trace stderr "Set: ~a -> ~a\n" lc i)) + (set-ct_data-freq! ct (add1 (ct_data-freq ct)))) + (let ([ct (vector-ref dyn_dtree (d_code dist))]) + (set-ct_data-freq! ct (add1 (ct_data-freq ct)))) + + (vector-set! d_buf last_dist dist) + (set! last_dist (add1 last_dist)) + (set! flags (bitwise-ior flags flag_bit)))) + + (set! flag_bit (<< flag_bit 1)) + + ;; /* Output the flags if they fill a byte: */ + (when (= (bitwise-and last_lit 7) 0) + (vector-set! flag_buf last_flags flags) + (set! last_flags (add1 last_flags)) + (set! flags 0) (set! flag_bit 1)) + + (or + ;; /* Try to guess if it is profitable to stop the current block here */ + (and (and (> LEVEL 2) (= (bitwise-and last_lit #xfff) 0)) + (let () + ;; /* Compute an upper bound for the compressed length */ + (define out_length (* last_lit 8)) + (define in_length (- strstart block_start)) + + (for dcode := 0 < D_CODES do + (set! out_length + (+ out_length + (* (ct_data-freq (vector-ref dyn_dtree dcode)) + (+ 5 (vector-ref extra_dbits dcode)))))) + (set! out_length (>> out_length 3)) + (DEBUG (Trace stderr "\nlast_lit ~a, last_dist ~a, in ~a, out ~~~a(~a%) " + last_lit last_dist in_length out_length + (- 100 (/ (* out_length 100) in_length)))) + (and (< last_dist (quotient last_lit 2)) + (< out_length (quotient in_length 2))))) + + (or (= last_lit (- LIT_BUFSIZE 1)) + (= last_dist DIST_BUFSIZE)) + ;; /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K + ;; * on 16 bit machines and because stored blocks are restricted to + ;; * 64K-1 bytes. + ;; */ + )))) + +;; /* =========================================================================== +;; * Send the block data compressed using the given Huffman trees +;; */ +(define (compress_block ltree dtree) + ;; ct_data near *ltree; ;; /* literal tree */ + ;; ct_data near *dtree; ;; /* distance tree */ + + (define dist 0) ;; /* distance of matched string */ + (define lc 0) ;; /* match length or unmatched char (if dist == 0) */ + (define lx 0) ;; /* running index in l_buf */ + (define dx 0) ;; /* running index in d_buf */ + (define fx 0) ;; /* running index in flag_buf */ + (define flag 0) ;; /* current flags */ + (define code 0) ;; /* the code to send */ + (define extra 0) ;; /* number of extra bits to send */ + + (when (not (= last_lit 0)) + (let loop () + (when (= (bitwise-and lx 7) 0) + (set! flag (vector-ref flag_buf fx)) + (set! fx (add1 fx))) + + (set! lc (bytes-ref l_buf lx)) + (set! lx (add1 lx)) + + (cond + [(= (bitwise-and flag 1) 0) + (send_code lc ltree) ;; /* send a literal byte */ + (DEBUG '(Tracecv (isgraph lc) stderr " '~c' " (integer->char lc)))] + [else + ;; /* Here, lc is the match length - MIN_MATCH */ + (set! code (vector-ref length_code lc)) + (send_code (+ code LITERALS 1) ltree) ;; /* send the length code */ + (set! extra (vector-ref extra_lbits code)) + (when (not (= extra 0)) + (set! lc (- lc (vector-ref base_length code))) + (send_bits lc extra)) ;; /* send the extra length bits */ + (set! dist (vector-ref d_buf dx)) + (set! dx (add1 dx)) + + ;; /* Here, dist is the match distance - 1 */ + (set! code (d_code dist)) + (Assert + (unless (< code D_CODES) + (error "bad d_code"))) + + (send_code code dtree) ;; /* send the distance code */ + (set! extra (vector-ref extra_dbits code)) + (when (not (= extra 0)) + (set! dist (- dist (vector-ref base_dist code))) + (send_bits dist extra))]) ;; /* send the extra distance bits */ + ;; /* literal or match pair ? */ + (set! flag (>> flag 1)) + (when (< lx last_lit) + (loop)))) + + (send_code END_BLOCK ltree)) + +#| +/* bits.c -- output variable-length bit strings + * Copyright (C) 1992-1993 Jean-loup Gailly + * This is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License, see the file COPYING. + */ + + +/* + * PURPOSE + * + * Output variable-length bit strings. Compression can be done + * to a file or to memory. (The latter is not supported in this version.) + * + * DISCUSSION + * + * The PKZIP "deflate" file format interprets compressed file data + * as a sequence of bits. Multi-bit strings in the file may cross + * byte boundaries without restriction. + * + * The first bit of each byte is the low-order bit. + * + * The routines in this file allow a variable-length bit value to + * be output right-to-left (useful for literal values). For + * left-to-right output (useful for code strings from the tree routines), + * the bits must have been reversed first with bi_reverse(). + * + * For in-memory compression, the compressed bit stream goes directly + * into the requested output buffer. The input data is read in blocks + * by the mem_read() function. The buffer is limited to 64K on 16 bit + * machines. + * + * INTERFACE + * + * void bi_init (FILE *zipfile) + * Initialize the bit string routines. + * + * void send_bits (int value, int length) + * Write out a bit string, taking the source bits right to + * left. + * + * int bi_reverse (int value, int length) + * Reverse the bits of a bit string, taking the source bits left to + * right and emitting them right to left. + * + * void bi_windup (void) + * Write out any remaining bits in an incomplete byte. + * + * void copy_block(char *buf, unsigned len, int header) + * Copy a stored block to the zip file, storing first the length and + * its one's complement if requested. + * + */ +|# + +(define bytes_in 0) + +(define bi_buf 0) +;; /* Output buffer. bits are inserted starting at the bottom (least significant +;; * bits). +;; */ + +(define Buf_size (* 8 2)) +;; /* Number of bits used within bi_buf. (bi_buf might be implemented on +;; * more than 16 bits on some systems.) +;; */ + +(define bi_valid 0) +;; /* Number of valid bits in bi_buf. All bits above the last valid bit +;; * are always zero. +;; */ + +;; /* =========================================================================== +;; * Initialize the bit string routines. +;; */ +(define (bi_init) + (set! bi_buf 0) + (set! bi_valid 0) + (set! bits_sent 0)) + + +;; /* =========================================================================== +;; * Send a value on a given number of bits. +;; * IN assertion: length <= 16 and value fits in length bits. +;; */ +(define (send_bits value length) + ;; int value; /* value to send */ + ;; int length; /* number of bits */ + + (DEBUG (Tracev stderr " l ~a v ~x " length value)) + (Assert + (unless (and (> length 0) (<= length 15)) + (error "invalid length"))) + (set! bits_sent (+ bits_sent length)) + + ;; /* If not enough room in bi_buf, use (valid) bits from bi_buf and + ;; * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + ;; * unused bits in value. + ;; */ + (if (> bi_valid (- Buf_size length)) + (begin (put_short (bitwise-and (bitwise-ior bi_buf (<< value bi_valid)) + #xFFFF)) + (set! bi_buf (>> value (- Buf_size bi_valid))) + (set! bi_valid (+ bi_valid (- length Buf_size)))) + (begin (set! bi_buf (bitwise-ior bi_buf (<< value bi_valid))) + (set! bi_valid (+ bi_valid length))))) + +;; /* =========================================================================== +;; * Reverse the first len bits of a code, using straightforward code (a faster +;; * method would use a table) +;; * IN assertion: 1 <= len <= 15 +;; */ +(define (bi_reverse code len) + ;; unsigned code; /* the value to invert */ + ;; int len; /* its bit length */ + + (let loop ([res 0][code code][len len]) + (let ([res (<< (bitwise-ior res (bitwise-and code 1)) 1)]) + (if (> len 1) + (loop res (>> code 1) (sub1 len)) + (>> res 1))))) + +;; /* =========================================================================== +;; * Write out any remaining bits in an incomplete byte. +;; */ +(define (bi_windup) + (cond [(> bi_valid 8) (put_short bi_buf)] + [(> bi_valid 0) (put_byte bi_buf)]) + (set! bi_buf 0) + (set! bi_valid 0) + (set! bits_sent (bitwise-and (+ bits_sent 7) (bitwise-not 7)))) + +;; /* =========================================================================== +;; * Run a set of bytes through the crc shift register. If s is a NULL +;; * pointer, then initialize the crc shift register contents instead. +;; */ +(define crc #xffffffff) +(define (updcrc s n) + ;; uch *s; /* pointer to bytes to pump through */ + ;; unsigned n; /* number of bytes in s[] */ + (if s + (let loop ([c crc][p 0]) + (if (= p n) + (set! crc c) + (loop (bitwise-xor + (vector-ref crc_32_tab + (bitwise-and + (bitwise-xor c (bytes-ref window-vec (+ s p))) + #xff)) + (arithmetic-shift c -8)) + (add1 p)))) + (set! crc #xffffffff))) + +(define crc_32_tab + #(#x00000000 + #x77073096 #xee0e612c #x990951ba #x076dc419 + #x706af48f #xe963a535 #x9e6495a3 #x0edb8832 #x79dcb8a4 + #xe0d5e91e #x97d2d988 #x09b64c2b #x7eb17cbd #xe7b82d07 + #x90bf1d91 #x1db71064 #x6ab020f2 #xf3b97148 #x84be41de + #x1adad47d #x6ddde4eb #xf4d4b551 #x83d385c7 #x136c9856 + #x646ba8c0 #xfd62f97a #x8a65c9ec #x14015c4f #x63066cd9 + #xfa0f3d63 #x8d080df5 #x3b6e20c8 #x4c69105e #xd56041e4 + #xa2677172 #x3c03e4d1 #x4b04d447 #xd20d85fd #xa50ab56b + #x35b5a8fa #x42b2986c #xdbbbc9d6 #xacbcf940 #x32d86ce3 + #x45df5c75 #xdcd60dcf #xabd13d59 #x26d930ac #x51de003a + #xc8d75180 #xbfd06116 #x21b4f4b5 #x56b3c423 #xcfba9599 + #xb8bda50f #x2802b89e #x5f058808 #xc60cd9b2 #xb10be924 + #x2f6f7c87 #x58684c11 #xc1611dab #xb6662d3d #x76dc4190 + #x01db7106 #x98d220bc #xefd5102a #x71b18589 #x06b6b51f + #x9fbfe4a5 #xe8b8d433 #x7807c9a2 #x0f00f934 #x9609a88e + #xe10e9818 #x7f6a0dbb #x086d3d2d #x91646c97 #xe6635c01 + #x6b6b51f4 #x1c6c6162 #x856530d8 #xf262004e #x6c0695ed + #x1b01a57b #x8208f4c1 #xf50fc457 #x65b0d9c6 #x12b7e950 + #x8bbeb8ea #xfcb9887c #x62dd1ddf #x15da2d49 #x8cd37cf3 + #xfbd44c65 #x4db26158 #x3ab551ce #xa3bc0074 #xd4bb30e2 + #x4adfa541 #x3dd895d7 #xa4d1c46d #xd3d6f4fb #x4369e96a + #x346ed9fc #xad678846 #xda60b8d0 #x44042d73 #x33031de5 + #xaa0a4c5f #xdd0d7cc9 #x5005713c #x270241aa #xbe0b1010 + #xc90c2086 #x5768b525 #x206f85b3 #xb966d409 #xce61e49f + #x5edef90e #x29d9c998 #xb0d09822 #xc7d7a8b4 #x59b33d17 + #x2eb40d81 #xb7bd5c3b #xc0ba6cad #xedb88320 #x9abfb3b6 + #x03b6e20c #x74b1d29a #xead54739 #x9dd277af #x04db2615 + #x73dc1683 #xe3630b12 #x94643b84 #x0d6d6a3e #x7a6a5aa8 + #xe40ecf0b #x9309ff9d #x0a00ae27 #x7d079eb1 #xf00f9344 + #x8708a3d2 #x1e01f268 #x6906c2fe #xf762575d #x806567cb + #x196c3671 #x6e6b06e7 #xfed41b76 #x89d32be0 #x10da7a5a + #x67dd4acc #xf9b9df6f #x8ebeeff9 #x17b7be43 #x60b08ed5 + #xd6d6a3e8 #xa1d1937e #x38d8c2c4 #x4fdff252 #xd1bb67f1 + #xa6bc5767 #x3fb506dd #x48b2364b #xd80d2bda #xaf0a1b4c + #x36034af6 #x41047a60 #xdf60efc3 #xa867df55 #x316e8eef + #x4669be79 #xcb61b38c #xbc66831a #x256fd2a0 #x5268e236 + #xcc0c7795 #xbb0b4703 #x220216b9 #x5505262f #xc5ba3bbe + #xb2bd0b28 #x2bb45a92 #x5cb36a04 #xc2d7ffa7 #xb5d0cf31 + #x2cd99e8b #x5bdeae1d #x9b64c2b0 #xec63f226 #x756aa39c + #x026d930a #x9c0906a9 #xeb0e363f #x72076785 #x05005713 + #x95bf4a82 #xe2b87a14 #x7bb12bae #x0cb61b38 #x92d28e9b + #xe5d5be0d #x7cdcefb7 #x0bdbdf21 #x86d3d2d4 #xf1d4e242 + #x68ddb3f8 #x1fda836e #x81be16cd #xf6b9265b #x6fb077e1 + #x18b74777 #x88085ae6 #xff0f6a70 #x66063bca #x11010b5c + #x8f659eff #xf862ae69 #x616bffd3 #x166ccf45 #xa00ae278 + #xd70dd2ee #x4e048354 #x3903b3c2 #xa7672661 #xd06016f7 + #x4969474d #x3e6e77db #xaed16a4a #xd9d65adc #x40df0b66 + #x37d83bf0 #xa9bcae53 #xdebb9ec5 #x47b2cf7f #x30b5ffe9 + #xbdbdf21c #xcabac28a #x53b39330 #x24b4a3a6 #xbad03605 + #xcdd70693 #x54de5729 #x23d967bf #xb3667a2e #xc4614ab8 + #x5d681b02 #x2a6f2b94 #xb40bbe37 #xc30c8ea1 #x5a05df1b + #x2d02ef8d)) + +;; /* =========================================================================== +;; * Copy a stored block to the zip file, storing first the length and its +;; * one's complement if requested. +;; */ +(define (copy_block buf len header) + ;; char *buf; /* the input data */ + ;; unsigned len; /* its length */ + ;; int header; /* true if block header must be written */ + + (bi_windup);; /* align on byte boundary */ + + (when header + (put_short len) + (put_short (bitwise-and (bitwise-not len) #xFFFF)) + (set! bits_sent (+ bits_sent (* 2 16)))) + + (set! bits_sent (+ bits_sent (<< len 3))) + + (for pos := 0 < len do (put_byte (gzbytes-ref buf pos)))) + +;; /* =========================================================================== +;; * Read a new buffer from the current input file, perform end-of-line +;; * translation, and update the crc and input file size. +;; * IN assertion: size >= 2 (for end-of-line translation) +;; */ +(define (read_buf startpos size) + ;; char *buf; + ;; unsigned size; + + ;; Assert + ;; (unless (= insize 0) + ;; (error "inbuf not empty")) + + (let* ([s (read-bytes! window-vec ifd startpos (+ size startpos))] + [len (if (eof-object? s) EOF-const s)]) + (when (positive? len) + (updcrc startpos len) + (set! bytes_in (+ bytes_in len))) + len)) + +;; Assumes being called with c in 0..FF +(define-syntax put_byte + (syntax-rules () + [(_ c) + (begin (bytes-set! outbuf outcnt c) + (set! outcnt (add1 outcnt)) + (when (= outcnt OUTBUFSIZ) (flush_outbuf)))])) + +;; /* Output a 16 bit value, lsb first */ +;; Assumes being called with c in 0..FFFF +(define (put_short w) + (if (< outcnt (- OUTBUFSIZ 2)) + (begin (bytes-set! outbuf outcnt (bitwise-and #xFF w)) + (bytes-set! outbuf (add1 outcnt) (>> w 8)) + ;; this is not faster... + ;; (integer->integer-bytes w 2 #f #f outbuf outcnt) + (set! outcnt (+ outcnt 2))) + (begin (put_byte (bitwise-and #xFF w)) + (put_byte (>> w 8))))) + +;; /* Output a 32 bit value to the bit stream, lsb first */ +(define (put_long n) + (put_short (bitwise-and #xFFFF n)) + (put_short (bitwise-and #xFFFF (>> n 16)))) + +(define outcnt 0) +(define bytes_out 0) +(define outbuf (make-bytes OUTBUFSIZ)) + +;; /* =========================================================================== +;; * Write the output buffer outbuf[0..outcnt-1] and update bytes_out. +;; * (used for the compressed data only) +;; */ +(define (flush_outbuf) + (unless (= outcnt 0) + + (write-bytes outbuf ofd 0 outcnt) + + (set! bytes_out (+ bytes_out outcnt)) + (set! outcnt 0))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define ifd #f) +(define ofd #f) + +(define (deflate-inner in out) + (do-deflate)) + +(define (deflate in out) + + (set! bytes_in 0) + + (set! ifd in) + (set! ofd out) + (set! outcnt 0) + + (bi_init) + (ct_init) + (lm_init LEVEL) + + (deflate-inner in out) + + (flush_outbuf) + + (values bytes_in bytes_out (bitwise-xor crc #xffffffff))) + +(define (gzip-through-ports in out origname time_stamp) + + (define flags (if origname #x8 0)) ;; /* general purpose bit flags */ + + ;; make origname be a byte string + (set! origname (cond [(not origname) #f] + [(string? origname) (string->bytes/utf-8 origname)] + [(path? origname) (path->bytes origname)] + [else origname])) + + (set! bytes_in 0) + + (set! ifd in) + (set! ofd out) + (set! outcnt 0) + + ;; /* Write the header to the gzip file. See algorithm.doc for the format */ + (put_byte #o037) ;; /* magic header */ + (put_byte #o213) + (put_byte 8) ;; /* compression method */ + + (put_byte flags);; /* general flags */ + (put_long time_stamp); + + ;; /* Write deflated file to zip file */ + (updcrc #f 0) + + (bi_init) + (ct_init) + + (put_byte (lm_init LEVEL));; /* extra flags */ + (put_byte 3) ;; /* OS identifier */ + + (when origname + (for-each (lambda (b) (put_byte b)) (bytes->list origname)) + (put_byte 0)) + + (do-deflate) + + ;; /* Write the crc and uncompressed size */ + (put_long (bitwise-xor crc #xffffffff)) + (put_long bytes_in) + + (flush_outbuf)) + +(define (gzip infile outfile) + (let ([i (open-input-file infile)]) + (dynamic-wind + void + (lambda () + (let ([o (open-output-file outfile 'truncate/replace)]) + (dynamic-wind + void + (lambda () + (let ([name (with-handlers ([exn:fail? (lambda (x) #f)]) + (let-values ([(base name dir?) (split-path infile)]) + name))] + [timestamp (with-handlers ([exn:fail:filesystem? (lambda (x) 0)]) + (file-or-directory-modify-seconds infile))]) + (gzip-through-ports i o name timestamp))) + (lambda () (close-output-port o))))) + (lambda () (close-input-port i))))) + +(list gzip gzip-through-ports deflate))) + +(define gzip + (case-lambda + [(infile) (gzip infile (string-append infile ".gz"))] + [(infile outfile) ((car (invoke-unit code)) infile outfile)])) + +(define (gzip-through-ports in out origname time_stamp) + ((cadr (invoke-unit code)) in out origname time_stamp)) + +(define (deflate in out) + ((caddr (invoke-unit code)) in out)) + +) diff --git a/collects/mzlib/etc.rkt b/collects/mzlib/etc.rkt index 328ef6d575..aedc7095c1 100644 --- a/collects/mzlib/etc.rkt +++ b/collects/mzlib/etc.rkt @@ -3,7 +3,6 @@ racket/local racket/bool racket/block - racket/private/this-expression-source-directory (only racket/function identity) (only racket/base @@ -11,6 +10,7 @@ build-list build-vector compose) + "private/this-expression-source-directory.rkt" (rename racket/base base-else else)) (require-for-syntax syntax/name diff --git a/collects/mzlib/inflate.rkt b/collects/mzlib/inflate.rkt index 1823d67105..5fa4b7aea8 100644 --- a/collects/mzlib/inflate.rkt +++ b/collects/mzlib/inflate.rkt @@ -1,6 +1,931 @@ #lang racket/base +(require (for-syntax racket/base)) -;; deprecated library, see `file/gunzip` + (provide inflate + gunzip-through-ports + gunzip) + +#| + +/* inflate.c -- Not copyrighted 1992 by Mark Adler + version c10p1, 10 January 1993 */ +; Taken from the gzip source distribution +; Translated directly from C (obviously) by Matthew, April 1997 + +/* You can do whatever you like with this source file, though I would + prefer that if you modify it and redistribute it that you include + comments to that effect with your name and the date. Thank you. + [The history has been moved to the file ChangeLog.] + ; ChangeLog is distributed with the gzip source. + */ + +/* + Inflate deflated (PKZIP's method 8 compressed) data. The compression + method searches for as much of the current string of bytes (up to a + length of 258) in the previous 32K bytes. If it doesn't find any + matches (of at least length 3), it codes the next byte. Otherwise, it + codes the length of the matched string and its distance backwards from + the current position. There is a single Huffman code that codes both + single bytes (called "literals") and match lengths. A second Huffman + code codes the distance information, which follows a length code. Each + length or distance code actually represents a base value and a number + of "extra" (sometimes zero) bits to get to add to the base value. At + the end of each deflated block is a special end-of-block (EOB) literal/ + length code. The decoding process is basically: get a literal/length + code; if EOB then done; if a literal, emit the decoded byte; if a + length then get the distance and emit the referred-to bytes from the + sliding window of previously emitted data. + + There are (currently) three kinds of inflate blocks: stored, fixed, and + dynamic. The compressor deals with some chunk of data at a time, and + decides which method to use on a chunk-by-chunk basis. A chunk might + typically be 32K or 64K. If the chunk is uncompressible, then the + "stored" method is used. In this case, the bytes are simply stored as + is, eight bits per byte, with none of the above coding. The bytes are + preceded by a count, since there is no longer an EOB code. + + If the data is compressible, then either the fixed or dynamic methods + are used. In the dynamic method, the compressed data is preceded by + an encoding of the literal/length and distance Huffman codes that are + to be used to decode this block. The representation is itself Huffman + coded, and so is preceded by a description of that code. These code + descriptions take up a little space, and so for small blocks, there is + a predefined set of codes, called the fixed codes. The fixed method is + used if the block codes up smaller that way (usually for quite small + chunks), otherwise the dynamic method is used. In the latter case, the + codes are customized to the probabilities in the current block, and so + can code it much better than the pre-determined fixed codes. + + The Huffman codes themselves are decoded using a mutli-level table + lookup, in order to maximize the speed of decoding plus the speed of + building the decoding tables. See the comments below that precede the + lbits and dbits tuning parameters. + */ + + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarly, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + +|# + +#| +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). + Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 + means that v is a literal, 16 < e < 32 means that v is a pointer to + the next table, which codes e - 16 bits, and lastly e == 99 indicates + an unused code. If a code with e == 99 is looked up, this implies an + error in the data. */ +|# + + (define-struct huft (e b v) #:mutable) + + (define (huft-copy dest src) + (set-huft-e! dest (huft-e src)) + (set-huft-b! dest (huft-b src)) + (set-huft-v! dest (huft-v src))) + + (define (step start < end add1 f) + (let loop ([i start]) + (when (< i end) + (f i) + (loop (add1 i))))) + + (define (subvector v offset) + (let* ([len (- (vector-length v) offset)] + [new (make-vector len)]) + (step 0 < len add1 + (lambda (i) + (vector-set! new i (vector-ref v (+ i offset))))) + new)) + + (define (build-vector n p) + (let ([v (make-vector n)]) + (step 0 < n add1 (lambda (i) (vector-set! v i (p i)))) + v)) + + ;; We know that inflating will be a bottleneck, so we might as + ;; well help out the compiler... + (define-syntax define-const + (syntax-rules () + [(_ id v) (define-syntax id (make-const #'v))])) + (define-for-syntax (make-const val) + (make-set!-transformer + (lambda (stx) + (syntax-case stx (set!) + [(set! id . _) (raise-syntax-error (syntax-e #'id) + "cannot assign constant" + stx)] + [(id . rest) (quasisyntax/loc stx (#,val . rest))] + [id val])))) + +#| +/* The inflate algorithm uses a sliding 32K byte window on the uncompressed + stream to find repeated byte strings. This is implemented here as a + circular buffer. The index is updated simply by incrementing and then + and'ing with 0x7fff (32K-1). */ +|# + + (define-const WSIZE 32768) + + (define border + (vector + 16 17 18 0 8 7 9 6 10 5 11 4 12 3 13 2 14 1 15)) + + (define cplens + (vector + 3 4 5 6 7 8 9 10 11 13 15 17 19 23 27 31 + 35 43 51 59 67 83 99 115 131 163 195 227 258 0 0)) + ; /* note: see note #13 above about the 258 in this list. */ + (define cplext + (vector + 0 0 0 0 0 0 0 0 1 1 1 1 2 2 2 2 + 3 3 3 3 4 4 4 4 5 5 5 5 0 99 99)) ; /* 99==invalid */ + (define cpdist + (vector + 1 2 3 4 5 7 9 13 17 25 33 49 65 97 129 193 + 257 385 513 769 1025 1537 2049 3073 4097 6145 + 8193 12289 16385 24577)) + (define cpdext + (vector + 0 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6 + 7 7 8 8 9 9 10 10 11 11 + 12 12 13 13)) + + (define mask_bits + (vector + #x0000 + #x0001 #x0003 #x0007 #x000f #x001f #x003f #x007f #x00ff + #x01ff #x03ff #x07ff #x0fff #x1fff #x3fff #x7fff #xffff)) + + (define-const lbits 9) ; /* bits in base literal/length lookup table */ + (define-const dbits 6) ; /* bits in base distance lookup table */ + + + ; /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ + (define-const BMAX 16) ; /* maximum bit length of any code (16 for explode) */ + (define-const N_MAX 288) ; /* maximum number of codes in any set */ + +(define (inflate input-port output-port) + + (define slide (make-bytes WSIZE)) + (define wp 0) + + (define (flush-output len) + ; write out the data + (write-bytes slide output-port 0 len)) + + (define (check-flush) + (when (= wp WSIZE) + (flush-output WSIZE) + (set! wp 0))) + +#| +/* Macros for inflate() bit peeking and grabbing. + The usage is: + + NEEDBITS(j) + x = b & mask_bits[j]; + DUMPBITS(j) + + where NEEDBITS makes sure that b has at least j bits in it, and + DUMPBITS removes the bits from b. The macros use the variable k + for the number of bits in b. Normally, b and k are register + variables for speed, and are initialized at the beginning of a + routine that uses these macros from a global bit buffer and count. + + If we assume that EOB will be the longest code, then we will never + ask for bits with NEEDBITS that are beyond the end of the stream. + So, NEEDBITS should not read any more bytes than are needed to + meet the request. Then no bytes need to be "returned" to the buffer + at the end of the last block. + + However, this assumption is not true for fixed blocks--the EOB code + is 7 bits, but the other literal/length codes can be 8 or 9 bits. + (The EOB code is shorter than other codes because fixed blocks are + generally short. So, while a block always has an EOB, many other + literal/length codes have a significantly lower probability of + showing up at all.) However, by making the first table have a + lookup of seven bits, the EOB code will be found in that first + lookup, and so will not require that too many bits be pulled from + the stream. + */ +|# + + ;; We can't read the bytes outright, because we may + ;; look ahead. Assume that we need no more than 32 bytes + ;; look ahead, and peek in 4096-byte blocks. + (define MAX-LOOKAHEAD 32) + (define BUFFER-SIZE 4096) + (define buffer (make-bytes BUFFER-SIZE)) + (define buf-max 0) ; number of bytes in buffer + (define buf-pos 0) ; index into buffer = number of used peeked bytes + + (define bb 0) ; /* bit buffer */ + (define bk 0) ; /* bits in bit buffer */ + + (define (NEEDBITS n) + (when (< bk n) + (READBITS n))) + (define (READBITS n) + (if (= buf-pos buf-max) + (begin + (when (positive? buf-max) + (read-bytes! buffer input-port 0 (- buf-max MAX-LOOKAHEAD)) + ; (bytes-copy! buffer 0 buffer (- buf-max MAX-LOOKAHEAD) buf-max) + (set! buf-pos MAX-LOOKAHEAD)) + (let ([got (peek-bytes-avail! buffer buf-pos #f input-port buf-pos BUFFER-SIZE)]) + (if (eof-object? got) + (error 'inflate "unexpected end of file") + (set! buf-max (+ buf-pos got)))) + (READBITS n)) + (let ([v (bytes-ref buffer buf-pos)]) + (set! buf-pos (add1 buf-pos)) + (set! bb (+ bb (arithmetic-shift v bk))) + (set! bk (+ bk 8)) + (NEEDBITS n)))) + (define (DUMPBITS n) + (set! bb (arithmetic-shift bb (- n))) + (set! bk (- bk n))) + + (define (GETBITS n) + (NEEDBITS n) + (begin0 + bb + (DUMPBITS n))) + +#| +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ +|# + + (define (huft_build + b ; int vector /* code lengths in bits (all assumed <= BMAX) */ + n ; /* number of codes (assumed <= N_MAX) */ + s ; /* number of simple-valued codes (0..s-1) */ + d ; int vector /* list of base values for non-simple codes */ + e ; int vector /* list of extra bits for non-simple codes */ + m ; int /* maximum lookup bits, returns actual */ + incomp-ok?) + ; return: new-t new-m ok? + +#| +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return zero on success, one if + the given code set is incomplete (the tables are still built in this + case), two if the input is invalid (all zero length codes or an + oversubscribed set of lengths), and three if not enough memory. */ +|# + (define c (make-vector (add1 BMAX) 0)) + (define x (make-vector (add1 BMAX))) + (define v (make-vector N_MAX)) + + (define final-y 0) + (define t-result #f) + + ; (printf "n: ~s\n" n) + + (let/ec return + +#| +(if (= n 270) + (step 0 < n add1 + (lambda (i) (printf "b[~a] = ~a\n" i (vector-ref b i))))) +|# + + (step 0 < n add1 + (lambda (i) + (let ([pos (vector-ref b i)]) + (vector-set! c pos (add1 (vector-ref c pos)))))) + + (when (= n (vector-ref c 0)) + ; (printf "zero\n") + (return #f 0 #t)) + +#| +(when (= n 270) + (step 0 <= BMAX add1 + (lambda (i) + (printf "c[~s]: ~s\n" i (vector-ref c i))))) +|# + + ; /* Find minimum and maximum length, bound m-result by those */ + (let* ([j ; min-code-length + (let loop ([j 1]) + (cond + [(> j BMAX) j] + [(positive? (vector-ref c j)) j] + [else (loop (add1 j))]))] + [k j] + [i ; max-code-length + (let loop ([i BMAX]) + (cond + [(zero? i) 0] + [(positive? (vector-ref c i)) i] + [else (loop (sub1 i))]))] + [g i] + [l (min (max m j) i)] + [m-result l]) + ; (printf "min: ~s max: ~s\n" k g) + ; /* Adjust last length count to fill out codes, if needed */ + (let-values ([(y j) + (let loop ([y (arithmetic-shift 1 j)][j j]) + (if (>= j i) + (values y j) + (let ([new-y (- y (vector-ref c j))]) + (if (negative? new-y) + (begin + (error 'inflate + "bad input: more codes than bits") + (return null m-result #f)) + (loop (* new-y 2) (add1 j))))))]) + ; (printf "loop y: ~s\n" y) + (let ([y (- y (vector-ref c i))]) + (when (negative? y) + (error 'inflate "bad input: more codes than bits") + (return #f m-result #f)) + ; (printf "set c[~s] ~s + ~s\n" i (vector-ref c i) y) + (vector-set! c i (+ (vector-ref c i) y)) + (set! final-y y))) + ; /* Generate starting offsets into the value table for each length */ + (vector-set! x 1 0) + (let* ([j (let loop ([i (sub1 i)][x-pos 2][c-pos 1][j 0]) + (if (zero? i) + j + (let ([v (vector-ref c c-pos)]) + (vector-set! x x-pos (+ j v)) + (loop (sub1 i) (add1 x-pos) (add1 c-pos) (+ j v)))))]) + ; /* Make a table of values in order of bit lengths */ + (let loop ([i 0][b-pos 0]) + (let ([j (vector-ref b b-pos)]) + (unless (zero? j) + (let ([xj (vector-ref x j)]) + (vector-set! x j (add1 xj)) + (vector-set! v xj i))) + (let ([new-i (add1 i)]) + (when (< new-i n) + (loop new-i (add1 b-pos)))))) + + ; /* Generate the Huffman codes and for each, make the table entries */ + (vector-set! x 0 0) ; /* first Huffman code is zero */ + (let ([v-pos 0] ; /* grab values in bit order */ + [i 0] ; /* the Huffman code of length k bits for value *p */ + [h -1] ; /* no tables yet--level -1 */ + [w (- l)] ; /* bits decoded == (l * h) */ + [u (make-vector BMAX)] ; /* table stack */ + [q null] ; /* points to current table */ + [z 0] ; /* number of entries in current table */ + [r (make-huft 0 0 0)]) ; /* table entry for structure assignment */ + ; /* go through the bit lengths (k already is bits in shortest code) */ + (let k-loop ([k k]) + ; (printf "k: ~s\n" k) + (when (<= k g) + (let ([a (vector-ref c k)]) + (let a-loop ([a (sub1 a)]) + (unless (negative? a) + ; (printf "a: ~s\n" a) + ; /* here i is the Huffman code of length k bits for value *p */ + ; /* make tables up to required level */ + (let kwl-loop () + (when (> k (+ w l)) + (set! h (add1 h)) + (set! w (+ w l)) ; /* previous table always l bits */ + + ; /* compute minimum size table less than or equal to l bits */ + (set! z (min (- g w) l)) ; /* upper limit on table size */ + + ; (printf "z: ~s k: ~s w: ~s\n" z k w) + + (let* ([j (- k w)] + [f (arithmetic-shift 1 j)]) + (when (> f (add1 a)) ; /* try a k-w bit table */ + ; /* too few codes for k-w bit table */ + (set! f (- f a 1)) ; /* deduct codes from patterns left */ + ; /* try smaller tables up to z bits */ + (let loop ([c-pos k]) + (set! j (add1 j)) + (when (< j z) + (set! f (* f 2)) + (let* ([c-pos (add1 c-pos)] + [cv (vector-ref c c-pos)]) + (if (<= f cv) + (void) ; /* enough codes to use up j bits */ + (begin + (set! f (- f cv)) ; /* else deduct codes from patterns */ + (loop c-pos))))))) + (set! z (arithmetic-shift 1 j)) ; /* table entries for j-bit table */ + + ; /* allocate and link in new table */ + ; (printf "alloc: ~a\n" z) + (set! q (build-vector z (lambda (i) (make-huft 0 0 0)))) + + (when (not t-result) + (set! t-result q)) + + (vector-set! u h q) + + ; /* connect to last table, if there is one */ + (unless (zero? h) + (vector-set! x h i) ; /* save pattern for backing up */ + (set-huft-b! r l) ; /* bits to dump before this table */ + (set-huft-e! r (+ j 16)); /* bits in this table */ + (set-huft-v! r q) ; /* pointer to this table */ + (set! j (arithmetic-shift i (- l w))) + ; /* connect to last table: */ + (huft-copy (vector-ref (vector-ref u (sub1 h)) j) r))) + + (kwl-loop))) + + (set-huft-b! r (- k w)) ; cast uch (- k w) if needed + (if (>= v-pos n) + (set-huft-e! r 99) ; /* out of values--invalid code */ + (let ([vv (vector-ref v v-pos)]) + ; (printf "*p: ~s s: ~s\n" vv s) + (if (< vv s) + (begin + (set-huft-e! r (if (< vv 256) 16 15)) ; /* 256 is end-of-block code */ + (set-huft-v! r vv)) ; /* simple code is just the value */ + (begin + (set-huft-e! r (vector-ref e (- vv s))) ; /* non-simple--look up in lists */ + (set-huft-v! r (vector-ref d (- vv s))))) + (set! v-pos (add1 v-pos)))) + ; /* fill code-like entries with r */ + ; (printf "i: ~s w: ~s k: ~s\n" i w k) + (let ([f (arithmetic-shift 1 (- k w))]) ; /* i repeats in table every f entries */ + (let loop ([j (arithmetic-shift i (- w))]) + (when (< j z) + (huft-copy (vector-ref q j) r) + (loop (+ j f))))) + ; /* backwards increment the k-bit code i */ + (let loop ([j (arithmetic-shift 1 (sub1 k))]) + (if (positive? (bitwise-and i j)) + (begin + (set! i (bitwise-xor i j)) + (loop (arithmetic-shift j -1))) + (set! i (bitwise-xor i j)))) + ; /* backup over finished tables */ + (let loop () + (unless (= (vector-ref x h) (bitwise-and i (sub1 (arithmetic-shift 1 w)))) + (set! h (sub1 h)) ; /* don't need to update q */ + (set! w (- w l)) + (loop))) + + (a-loop (sub1 a)))) + (k-loop (add1 k))))) + + ; /* Return #f as third if we were given an incomplete table */ + ; (printf "done: ~s ~s\n" final-y g) + (let ([ok? (or incomp-ok? + (not (and (not (zero? final-y)) + (not (= g 1)))))]) + (unless ok? + (error 'inflate "incomplete table")) + (values t-result m-result ok?))))))) + + (define (inflate_codes + tl ; vector of hufts ; /* literal/length tables */ + td ; vector of hufts ; /* distance decoder tables */ + bl ; /* number of bits decoded by tl */ + bd) ; /* number of bits decoded by td[] */ + ; /* inflate (decompress) the codes in a deflated (compressed) block. + ; Return an error code or zero if it all goes ok. */ + + ; /* inflate the coded data */ + + ; /* precompute masks for speed */ + (define ml (vector-ref mask_bits bl)) + (define md (vector-ref mask_bits bd)) + (define t (void)) + (define e 0) + (define n 0) + (define d 0) + + (let/ec return + + (define (jump-to-next) + (let loop () + (when (= e 99) + (error 'inflate "bad inflate code") + (return #f)) + (DUMPBITS (huft-b t)) + (set! e (- e 16)) + (NEEDBITS e) + (set! t (vector-ref (huft-v t) (bitwise-and bb (vector-ref mask_bits e)))) + (set! e (huft-e t)) + (when (> e 16) + (loop)))) + + (let loop () ; /* do until end of block */ + (NEEDBITS bl) + (set! t (vector-ref tl (bitwise-and bb ml))) + ; (printf "t->e: ~s t->b: ~s\n" (huft-e t) (huft-b t)) + (set! e (huft-e t)) + (when (> e 16) + (jump-to-next)) + (DUMPBITS (huft-b t)) + ; (printf "e: ~s\n" e) + (if (= e 16) ; /* then it's a literal */ + (begin + (bytes-set! slide wp (huft-v t)) + (set! wp (add1 wp)) + (check-flush)) + (begin ; /* it's an EOB or a length */ + ; /* exit if end of block */ + (when (= e 15) + (return #t)) + + ; /* get length of block to copy */ + (NEEDBITS e) + (set! n (+ (huft-v t) (bitwise-and bb (vector-ref mask_bits e)))) + (DUMPBITS e) + ; (printf "n: ~s bb: ~s md: ~s\n" n bb md) + + ; /* decode distance of block to copy */ + (NEEDBITS bd) + (set! t (vector-ref td (bitwise-and bb md))) + ; (printf "t->e: ~s t->b: ~s\n" (huft-e t) (huft-b t)) + (set! e (huft-e t)) + ; (printf "e: ~s\n" e) + (when (> e 16) + (jump-to-next)) + (DUMPBITS (huft-b t)) + ; (printf "e: ~s\n" e) + + (NEEDBITS e) + (set! d (modulo (- wp (huft-v t) (bitwise-and bb (vector-ref mask_bits e))) WSIZE)) + (DUMPBITS e) + + ; (printf "wp: ~s t->v: ~s d: ~s\n" wp (huft-v t) d) + + ; /* do the copy */ + (let loop () + (set! d (bitwise-and d (sub1 WSIZE))) + (set! e (min n (- WSIZE (max d wp)))) + (set! n (- n e)) + (let loop () + (bytes-set! slide wp (bytes-ref slide d)) + (set! wp (add1 wp)) + (set! d (add1 d)) + (set! e (sub1 e)) + (unless (zero? e) + (loop))) + (check-flush) + (unless (zero? n) + (loop))))) + (loop)))) + + (define (inflate_stored) + ; /* "decompress" an inflated type 0 (stored) block. */ + + (let/ec return + + ; /* go to byte boundary */ + (DUMPBITS (bitwise-and bk 7)) + + ; /* get the length and its complement */ + (NEEDBITS 16) + (let ([n (bitwise-and bb #xffff)]) + (DUMPBITS 16) + (NEEDBITS 16) + (unless (= n (bitwise-and (bitwise-not bb) #xffff)) + (error 'inflate "error in compressed data") + (return #f)) ; /* error in compressed data */ + (DUMPBITS 16) + + ; /* read and output the compressed data */ + (let loop ([n n]) + (when (positive? n) + (NEEDBITS 8) + (bytes-set! slide wp (bitwise-and bb #xff)) + (set! wp (add1 wp)) + (check-flush) + (DUMPBITS 8) + (loop (sub1 n)))) + + #t))) + + (define (inflate_fixed) + ; /* decompress an inflated type 1 (fixed Huffman codes) block. We should + ; either replace this with a custom decoder, or at least precompute the + ; Huffman tables. */ + + (define l (make-vector 288)) + + (step 0 < 144 add1 (lambda (i) (vector-set! l i 8))) + (step 144 < 256 add1 (lambda (i) (vector-set! l i 9))) + (step 256 < 280 add1 (lambda (i) (vector-set! l i 7))) + (step 280 < 288 add1 (lambda (i) (vector-set! l i 8))) + + (let-values ([(tl bl ok?) + (huft_build l 288 257 cplens cplext 7 #f)]) + + (if (not ok?) + #f + (begin + (step 0 < 30 add1 (lambda (i) (vector-set! l i 5))) + (let-values ([(td bd ok?) + (huft_build l 30 0 cpdist cpdext 5 #t)]) + (if (not ok?) + #f + ; /* decompress until an end-of-block code */ + (inflate_codes tl td bl bd))))))) + + (define (inflate_dynamic) + ; /* decompress an inflated type 2 (dynamic Huffman codes) block. */ + + (begin ; let/ec return + + ; /* read in table lengths */ + ; (define junk1 (begin (NEEDBITS 5) (printf "~s ~s\n" bb bk))) + (define nl (+ 257 (bitwise-and (GETBITS 5) #x1f))) + ; (define junk2 (begin (NEEDBITS 5) (printf "~s ~s\n" bb bk))) + (define nd (+ 1 (bitwise-and (GETBITS 5) #x1f))) + ; (define junk3 (begin (NEEDBITS 4) (printf "~s ~s\n" bb bk))) + (define nb (+ 4 (bitwise-and (GETBITS 4) #xf))) + + ; (define junk8 (printf "~s ~s ~s\n" nl nd nb)) + + (define ll (make-vector (+ 286 30))) + (define i 0) + (define l 0) + + (if (or (> nl 286) (> nd 30)) + (begin + (error 'inflate "bad lengths") + #f) ; /* bad lengths */ + (begin + ; /* read in bit-length-code lengths */ + (step 0 < nb add1 + (lambda (j) + (vector-set! ll (vector-ref border j) (bitwise-and (GETBITS 3) 7)))) + (step nb < 19 add1 + (lambda (j) + (vector-set! ll (vector-ref border j) 0))) + + ; /* build decoding table for trees--single level, 7 bit lookup */ + (let-values ([(tl bl ok?) + (huft_build ll 19 19 null null 7 #f)]) + (if (not ok?) + #f + (begin + ; /* read in literal and distance code lengths */ + (let ([n (+ nl nd)] + [m (vector-ref mask_bits bl)]) + ; (printf "bl: ~s\n" bl) + (set! i 0) + (set! l 0) + (let loop () + (when (< i n) + (NEEDBITS bl) + (let* ([pos (bitwise-and bb m)] + [td (vector-ref tl pos)] + [dmp (huft-b td)] + [j (huft-v td)] + [set-lit + (lambda (j l) + (when (> (+ i j) n) + (error 'inflate "bad hop") + #;(return #f)) + (let loop ([j j]) + (unless (zero? j) + (vector-set! ll i l) + (set! i (add1 i)) + (loop (sub1 j)))))]) + (DUMPBITS dmp) + ; (printf "pos: ~s j: ~s l: ~s i: ~s\n" pos j l i) + (cond + [(< j 16) ; /* length of code in bits (0..15) */ + (vector-set! ll i j) + (set! l j) ; /* save last length in l */ + (set! i (add1 i))] + [(= j 16) ; /* repeat last length 3 to 6 times */ + (let ([j (+ 3 (bitwise-and (GETBITS 2) 3))]) + (set-lit j l))] + [(= j 17) ; /* 3 to 10 zero length codes */ + (let ([j (+ 3 (bitwise-and (GETBITS 3) 7))]) + (set-lit j 0) + (set! l 0))] + [else ; /* j == 18: 11 to 138 zero length codes */ + (let ([j (+ 11 (bitwise-and (GETBITS 7) #x7f))]) + (set-lit j 0) + (set! l 0))])) + (loop))) + + ; /* build the decoding tables for literal/length and distance codes */ + (let-values ([(tl bl ok?) + (huft_build ll nl 257 cplens cplext lbits #f)]) + (if (not ok?) + (begin + (error 'inflate "incomplete code set") + #f) ; /* incomplete code set */ + (let-values ([(td bd ok?) + (huft_build (subvector ll nl) nd 0 cpdist cpdext dbits #f)]) + (if (not ok?) + (begin + (error 'inflate "incomplete code set") + #f) ; /* incomplete code set */ + ; /* decompress until an end-of-block code */ + (inflate_codes tl td bl bd))))))))))))) + + (define (inflate_block) + ; return values: /* last block flag */ ok? + ; /* decompress an inflated block */ + + (define e-result (bitwise-and (GETBITS 1) 1)) + + ; /* read in block type */ + (define t (bitwise-and (GETBITS 2) 3)) + + (values e-result + (case t + [(2) (inflate_dynamic)] + [(0) (inflate_stored)] + [(1) (inflate_fixed)] + [else (error 'inflate "unknown inflate type") + #f]))) + + ;;;;;;;;;;;;;;;;;;;;;;;; + ; inflate starts here + ;;;;;;;;;;;;;;;;;;;;;;;; + + ; /* decompress an inflated entry */ + ; /* initialize window, bit buffer */ + (set! wp 0) + (set! bk 0) + (set! bb 0) + + + ; /* decompress until the last block */ + (let loop () + (let-values ([(e ok?) (inflate_block)]) + (if ok? + (if (zero? e) + (loop) + (begin + ; /* Undo too much lookahead. The next read will be byte aligned so we + ; * can discard unused bits in the last meaningful byte. + ; */ + (let loop () + (when (>= bk 8) + (set! bk (- bk 8)) + (set! buf-pos (sub1 buf-pos)) + (loop))) + (read-bytes! buffer input-port 0 buf-pos) + (flush-output wp) + #t = (void))) + #f)))) + + (define make-small-endian + (case-lambda + [(a b) (+ a (arithmetic-shift b 8))] + [(a b c d) (+ a + (arithmetic-shift b 8) + (arithmetic-shift c 16) + (arithmetic-shift d 24))])) + + (define (do-gunzip in out name-filter) + (let ([header1 (read-byte in)] + [header2 (read-byte in)]) + (unless (and (= header1 #o037) (= header2 #o213)) + (error 'gnu-unzip "bad header"))) + (let ([compression-type (read-byte in)]) + (unless (= compression-type #o010) + (error 'gnu-unzip "unknown compression type"))) + (let* ([flags (read-byte in)] + [ascii? (positive? (bitwise-and flags #b1))] + [continuation? (positive? (bitwise-and flags #b10))] + [has-extra-field? (positive? (bitwise-and flags #b100))] + [has-original-filename? (positive? (bitwise-and flags #b1000))] + [has-comment? (positive? (bitwise-and flags #b10000))] + [encrypted? (positive? (bitwise-and flags #b100000))]) + (when encrypted? + (error 'gnu-unzip "cannot unzip encrypted file")) + (when continuation? + (error 'gnu-unzip "cannot handle multi-part files")) + (let ([unix-mod-time (make-small-endian (read-byte in) (read-byte in) + (read-byte in) (read-byte in))] + [extra-flags (read-byte in)] + [source-os (read-byte in)]) + (when continuation? + (let ([part-number (make-small-endian (read-byte in) (read-byte in))]) + 'ok)) + (when has-extra-field? + (let ([len (make-small-endian (read-byte in) (read-byte in))]) + (let loop ([len len]) + (unless (zero? len) + (read-byte in) + (loop (sub1 len)))))) + (let* ([read-null-term-string + (lambda () + (let loop ([s null]) + (let ([r (read-byte in)]) + (if (zero? r) + (list->bytes (reverse s)) + (loop (cons r s))))))] + [original-filename (and has-original-filename? + (read-null-term-string))] + [comment (and has-comment? (read-null-term-string))]) + (when encrypted? + (let loop ([n 12]) + (unless (zero? n) + (read-byte in) + (loop (sub1 n))))) + + (let-values ([(out close?) (if out + (values out #f) + (let-values ([(fn orig?) + (if original-filename + (values (bytes->path original-filename) #t) + (values "unzipped" #f))]) + (values (open-output-file (name-filter fn orig?) #:exists 'truncate) + #t)))]) + (dynamic-wind + void + (lambda () (begin0 (inflate in out) + (read-bytes 8 in))) ; read CRC32 and ISIZE + (lambda () (when close? (close-output-port out))))))))) + + (define (gunzip-through-ports in out) + (do-gunzip in out void)) + + (define gunzip + (case-lambda + [(src) (gunzip src (lambda (name from-file?) name))] + [(src name-filter) + (let ([in (open-input-file src #:mode 'binary)]) + (dynamic-wind + void + (lambda () (do-gunzip in #f name-filter)) + (lambda () (close-input-port in))))])) -(require file/gunzip) -(provide (all-from-out file/gunzip)) diff --git a/collects/mzlib/port.rkt b/collects/mzlib/port.rkt index 73c8ee93fa..e331742109 100644 --- a/collects/mzlib/port.rkt +++ b/collects/mzlib/port.rkt @@ -1,11 +1,1796 @@ #lang racket/base -;; deprecated library, see `racket/port` +(require (for-syntax racket/base) + racket/contract/base + "private/port.rkt") -(require racket/port) -(provide ;; these are the functions that used to be defined in - ;; `mzlib/port` but are now defined in `racket/port` - open-output-nowhere +(define (input-port-with-progress-evts? ip) + (and (input-port? ip) + (port-provides-progress-evts? ip))) + +(define (mutable-bytes? b) + (and (bytes? b) (not (immutable? b)))) +(define (mutable-string? b) + (and (string? b) (not (immutable? b)))) + +(define (line-mode-symbol? s) + (memq s '(linefeed return return-linefeed any any-one))) + +(define (evt?/false v) + (or (eq? #f v) (evt? v))) + +;; ---------------------------------------- + +(define (strip-shell-command-start in) + (when (regexp-match-peek #rx#"^#![^\r\n]*" in) + (let loop ([s (read-line in)]) + (when (regexp-match #rx#"\\\\$" s) + (loop (read-line in)))))) + +;; ---------------------------------------- + +(define merge-input + (case-lambda + [(a b) (merge-input a b 4096)] + [(a b limit) + (or (input-port? a) + (raise-argument-error 'merge-input "input-port?" a)) + (or (input-port? b) + (raise-argument-error 'merge-input "input-port?" b)) + (or (not limit) + (and (number? limit) (positive? limit) (exact? limit) (integer? limit)) + (raise-argument-error 'merge-input "(or/c exact-positive-integer #f)" limit)) + (let-values ([(rd wt) (make-pipe-with-specials limit)] + [(other-done?) #f] + [(sema) (make-semaphore 1)]) + (let ([copy + (lambda (from) + (thread + (lambda () + (copy-port from wt) + (semaphore-wait sema) + (if other-done? + (close-output-port wt) + (set! other-done? #t)) + (semaphore-post sema))))]) + (copy a) + (copy b) + rd))])) + +;; `make-input-port/read-to-peek' sometimes needs to wrap a special-value +;; procedure so that it's only called once when the value is both +;; peeked and read. +(define-values (struct:memoized make-memoized memoized? memoized-ref memoized-set!) + (make-struct-type 'memoized #f 1 0 #f null (current-inspector) 0)) +(define (memoize p) + (define result #f) + (make-memoized + (if (procedure-arity-includes? p 0) + ;; original p accepts 0 or 4 arguments: + (case-lambda + [() (unless result (set! result (box (p)))) (unbox result)] + [(src line col pos) + (unless result (set! result (box (p src line col pos)))) + (unbox result)]) + ;; original p accepts only 4 arguments: + (lambda (src line col pos) + (unless result (set! result (box (p src line col pos)))) + (unbox result))))) + +;; Not kill-safe. +;; If the `read' proc returns an event, the event must produce +;; 0 always (which implies that the `read' proc must not return +;; a pipe input port). +(define make-input-port/read-to-peek + (lambda (name read fast-peek close + [location-proc #f] + [count-lines!-proc void] + [init-position 1] + [buffer-mode-proc #f] + [buffering? #f] + [on-consumed #f]) + (define lock-semaphore (make-semaphore 1)) + (define commit-semaphore (make-semaphore 1)) + (define-values (peeked-r peeked-w) (make-pipe)) + (define special-peeked null) + (define special-peeked-tail #f) + (define progress-requested? #f) + (define line-counting? #f) + (define use-manager? #f) + (define manager-th #f) + (define manager-ch (make-channel)) + (define resume-ch (make-channel)) + (define buf (make-bytes 4096)) + (define (try-again) + (wrap-evt + (semaphore-peek-evt lock-semaphore) + (lambda (x) 0))) + (define (suspend-manager) + (channel-put manager-ch 'suspend)) + (define (resume-manager) + (channel-put resume-ch 'resume)) + (define (with-manager-lock thunk) + (thread-resume manager-th (current-thread)) + (dynamic-wind suspend-manager thunk resume-manager)) + (define (make-progress) + ;; We dont worry about this byte getting picked up directly + ;; from peeked-r, because the pipe must have been empty when + ;; we grabed the lock, and since we've grabbed the lock, + ;; no other thread could have re-returned the pipe behind + ;; our back. + (write-byte 0 peeked-w) + (read-byte peeked-r)) + (define (consume-from-peeked s) + (let ([n (read-bytes-avail!* s peeked-r)]) + (when on-consumed (on-consumed n)) + n)) + (define (read-it-with-lock s) + (if use-manager? + (with-manager-lock (lambda () (do-read-it s))) + (do-read-it s))) + (define (read-it s) + (call-with-semaphore lock-semaphore read-it-with-lock try-again s)) + (define (do-read-it s) + (if (byte-ready? peeked-r) + (if on-consumed (consume-from-peeked s) peeked-r) + ;; If nothing is saved from a peeking read, dispatch to + ;; `read', otherwise return previously peeked data + (cond + [(null? special-peeked) + (when progress-requested? (make-progress)) + (if (and buffering? ((bytes-length s) . < . 10)) + ;; Buffering is enabled, so read more to move things + ;; along: + (let ([r (read buf)]) + (if (and (number? r) (positive? r)) + (begin (write-bytes buf peeked-w 0 r) + (if on-consumed (consume-from-peeked s) peeked-r)) + (begin (when on-consumed (on-consumed r)) + r))) + ;; Just read requested amount: + (let ([v (read s)]) + (when on-consumed (on-consumed v)) + v))] + [else (if (bytes? (mcar special-peeked)) + (let ([b (mcar special-peeked)]) + (write-bytes b peeked-w) + (set! special-peeked (mcdr special-peeked)) + (when (null? special-peeked) (set! special-peeked-tail #f)) + (consume-from-peeked s)) + (let ([v (mcar special-peeked)]) + (make-progress) + (set! special-peeked (mcdr special-peeked)) + (when on-consumed (on-consumed v)) + (when (null? special-peeked) (set! special-peeked-tail #f)) + v))]))) + (define (peek-it-with-lock s skip unless-evt) + (if use-manager? + (with-manager-lock (lambda () (do-peek-it s skip unless-evt))) + (do-peek-it s skip unless-evt))) + (define (peek-it s skip unless-evt) + (let ([v (peek-bytes-avail!* s skip unless-evt peeked-r)]) + (if (eq? v 0) + (call-with-semaphore lock-semaphore + peek-it-with-lock try-again s skip unless-evt) + v))) + (define (do-peek-it s skip unless-evt) + (let ([v (peek-bytes-avail!* s skip unless-evt peeked-r)]) + (if (eq? v 0) + ;; The peek may have failed because peeked-r is empty, + ;; because unless-evt is ready, or because the skip is + ;; far. Handle nicely the common case where there are no + ;; specials. + (cond + [(and unless-evt (sync/timeout 0 unless-evt)) + #f] + [(null? special-peeked) + ;; Empty special queue, so read through the original proc. + ;; We only only need + ;; (- (+ skip (bytes-length s)) (pipe-content-length peeked-w)) + ;; bytes, but if buffering is enabled, read more (up to size of + ;; buf) to help move things along. + (let* ([dest (if buffering? + buf + (make-bytes (- (+ skip (bytes-length s)) + (pipe-content-length peeked-w))))] + [r (read dest)]) + (cond + [(number? r) + ;; The nice case --- reading gave us more bytes + (write-bytes dest peeked-w 0 r) + ;; Now try again + (peek-bytes-avail!* s skip #f peeked-r)] + [(evt? r) + (if unless-evt + ;; Technically, there's a race condition here. + ;; We might choose r (and return 0) even when + ;; unless-evt becomes available first. However, + ;; this race is detectable only by the inside + ;; of `read'. + (choice-evt r (wrap-evt unless-evt (lambda (x) #f))) + r)] + [else + (set! special-peeked (mcons r null)) + (set! special-peeked-tail special-peeked) + ;; Now try again + (do-peek-it s skip unless-evt)]))] + [else + ;; Non-empty special queue, so try to use it + (let* ([avail (pipe-content-length peeked-r)] + [sk (- skip avail)]) + (let loop ([sk sk] [l special-peeked]) + (cond + [(null? l) + ;; Not enough even in the special queue. + ;; Read once and add it. + (let* ([t (make-bytes (min 4096 (+ sk (bytes-length s))))] + [r (read t)]) + (cond + [(evt? r) + (if unless-evt + ;; See note above + (choice-evt r (wrap-evt unless-evt (lambda (x) #f))) + r)] + [(eq? r 0) + ;; Original read thinks a spin is ok, + ;; so we return 0 to skin, too. + 0] + [else (let ([v (if (number? r) + (subbytes t 0 r) + r)]) + (let ([pr (mcons v null)]) + (set-mcdr! special-peeked-tail pr) + (set! special-peeked-tail pr)) + ;; Got something; now try again + (do-peek-it s skip unless-evt))]))] + [(eof-object? (mcar l)) + ;; No peeking past an EOF + eof] + [(procedure? (mcar l)) + (if (zero? sk) + ;; We should call the procedure only once. Change + ;; (mcar l) to a memoizing function, if it isn't already: + (let ([proc (mcar l)]) + (if (memoized? proc) + proc + (let ([proc (memoize proc)]) + (set-mcar! l proc) + proc))) + ;; Skipping over special... + (loop (sub1 sk) (mcdr l)))] + [(bytes? (mcar l)) + (let ([len (bytes-length (mcar l))]) + (if (sk . < . len) + (let ([n (min (bytes-length s) + (- len sk))]) + (bytes-copy! s 0 (mcar l) sk (+ sk n)) + n) + (loop (- sk len) (mcdr l))))])))]) + v))) + (define (commit-it-with-lock amt unless-evt done-evt) + (if use-manager? + (with-manager-lock (lambda () (do-commit-it amt unless-evt done-evt))) + (do-commit-it amt unless-evt done-evt))) + (define (commit-it amt unless-evt done-evt) + (call-with-semaphore lock-semaphore + commit-it-with-lock #f amt unless-evt done-evt)) + (define (do-commit-it amt unless-evt done-evt) + (if (sync/timeout 0 unless-evt) + #f + (let* ([avail (pipe-content-length peeked-r)] + [p-commit (min avail amt)]) + (let loop ([amt (- amt p-commit)] + [l special-peeked] + ;; result is either bytes (if needed for line ounting) + ;; or an integer count (for on-consumed) + [result (if line-counting? null 0)]) + (cond + [(amt . <= . 0) + ;; Enough has been peeked. Do commit... + (actual-commit p-commit l unless-evt done-evt result)] + [(null? l) + ;; Requested commit was larger than previous peeks + #f] + [(bytes? (mcar l)) + (let ([bl (bytes-length (mcar l))]) + (if (bl . > . amt) + ;; Split the string + (let ([next (mcons (subbytes (mcar l) amt) (mcdr l))]) + (set-mcar! l (subbytes (mcar l) 0 amt)) + (set-mcdr! l next) + (when (eq? l special-peeked-tail) + (set! special-peeked-tail next)) + (loop 0 (mcdr l) (if line-counting? + (cons (subbytes (mcar l) 0 amt) result) + (+ amt result)))) + ;; Consume this string... + (loop (- amt bl) (mcdr l) (if line-counting? + (cons (mcar l) result) + (+ bl result)))))] + [else + (loop (sub1 amt) (mcdr l) (if line-counting? + (cons #"." result) + (add1 result)))]))))) + (define (actual-commit p-commit l unless-evt done-evt result) + ;; The `finish' proc finally, actually, will commit... + (define (finish) + (let ([result (if line-counting? + (cons (peek-bytes p-commit 0 peeked-r) result) + (+ p-commit result))]) + (unless (zero? p-commit) + (peek-byte peeked-r (sub1 p-commit)) + (port-commit-peeked p-commit unless-evt always-evt peeked-r)) + (set! special-peeked l) + (when (null? special-peeked) (set! special-peeked-tail #f)) + (when (and progress-requested? (zero? p-commit)) (make-progress)) + (if line-counting? + ;; bytes representation of committed text allows line counting + ;; to be updated correctly (when line counting is implemented + ;; automatically) + (let ([bstr (apply bytes-append (reverse result))]) + (when on-consumed (on-consumed (bytes-length bstr))) + bstr) + (begin + (when on-consumed (on-consumed result)) + #t)))) + ;; If we can sync done-evt immediately, then finish. + (if (sync/timeout 0 (wrap-evt done-evt (lambda (x) #t))) + (finish) + ;; We need to wait, so we'll have to release the lock. + ;; Send the work to a manager thread. + (let ([result-ch (make-channel)] + [w/manager? use-manager?]) + (if w/manager? + ;; Resume manager if it was running: + (resume-manager) + ;; Start manager if it wasn't running: + (begin (set! manager-th (thread manage-commits)) + (set! use-manager? #t) + (thread-resume manager-th (current-thread)))) + ;; Sets use-manager? if the manager wasn't already running: + (channel-put manager-ch (list finish unless-evt done-evt result-ch)) + ;; Release locks: + (semaphore-post lock-semaphore) + (begin0 ;; Wait for manager to complete commit: + (sync result-ch) + ;; Grab locks again, so they're released + ;; properly on exit: + (semaphore-wait lock-semaphore) + (when w/manager? (suspend-manager)))))) + (define (manage-commits) + (let loop ([commits null]) + (apply + sync + (handle-evt manager-ch + (lambda (c) + (case c + [(suspend) + (channel-get resume-ch) + (loop commits)] + [else + ;; adding a commit + (loop (cons c commits))]))) + (map (lambda (c) + (define (send-result v) + ;; Create a new thread to send the result asynchronously: + (thread-resume + (thread (lambda () (channel-put (list-ref c 3) v))) + (current-thread)) + (when (null? (cdr commits)) + (set! use-manager? #f)) + (loop (remq c commits))) + ;; Choose between done and unless: + (if (sync/timeout 0 (list-ref c 1)) + (handle-evt always-evt (lambda (x) (send-result #f))) + (choice-evt + (handle-evt (list-ref c 1) + (lambda (x) + ;; unless ready, which means that the commit must fail + (send-result #f))) + (handle-evt (list-ref c 2) + (lambda (x) + ;; done-evt ready, which means that the commit + ;; must succeed. + ;; If we get here, then commits are not + ;; suspended, so we implicitly have the + ;; lock. + ((list-ref c 0)) + (send-result #t)))))) + commits)))) + (make-input-port + name + ;; Read + read-it + ;; Peek + (if fast-peek + (let ([fast-peek-k (lambda (s skip) (peek-it s skip #f))]) + (lambda (s skip unless-evt) + (if (or unless-evt + (byte-ready? peeked-r) + (mpair? special-peeked)) + (peek-it s skip unless-evt) + (fast-peek s skip fast-peek-k)))) + peek-it) + close + (lambda () + (set! progress-requested? #t) + (port-progress-evt peeked-r)) + commit-it + location-proc + (lambda () + (set! line-counting? #t) + (count-lines!-proc)) + init-position + (and buffer-mode-proc + (case-lambda + [() (buffer-mode-proc)] + [(mode) + (set! buffering? (eq? mode 'block)) + (buffer-mode-proc mode)]))))) + +(define (peeking-input-port orig-in + [name (object-name orig-in)] + [delta 0] + #:init-position [init-position 1]) + (make-input-port/read-to-peek + name + (lambda (s) + (let ([r (peek-bytes-avail!* s delta #f orig-in)]) + (set! delta (+ delta (if (number? r) r 1))) + (if (eq? r 0) (wrap-evt orig-in (lambda (v) 0)) r))) + (lambda (s skip default) + (peek-bytes-avail!* s (+ delta skip) #f orig-in)) + void + #f + void + init-position)) + +(define relocate-input-port + (lambda (p line col pos [close? #t]) + (transplant-to-relocate transplant-input-port p line col pos close?))) + +(define transplant-input-port + (lambda (p location-proc pos [close? #t] [count-lines!-proc void]) + (make-input-port + (object-name p) + (lambda (s) + (let ([v (read-bytes-avail!* s p)]) + (if (eq? v 0) (wrap-evt p (lambda (x) 0)) v))) + (lambda (s skip evt) + (let ([v (peek-bytes-avail!* s skip evt p)]) + (if (eq? v 0) + (choice-evt + (wrap-evt p (lambda (x) 0)) + (if evt (wrap-evt evt (lambda (x) #f)) never-evt)) + v))) + (lambda () + (when close? (close-input-port p))) + (and (port-provides-progress-evts? p) + (lambda () (port-progress-evt p))) + (and (port-provides-progress-evts? p) + (lambda (n evt target-evt) (port-commit-peeked n evt target-evt p))) + location-proc + count-lines!-proc + pos))) + +(define filter-read-input-port + (lambda (p wrap-read wrap-peek [close? #t]) + (make-input-port + (object-name p) + (lambda (s) + (let ([v (read-bytes-avail!* s p)]) + (wrap-read + s + (if (eq? v 0) (wrap-evt p (lambda (x) 0)) v)))) + (lambda (s skip evt) + (let ([v (peek-bytes-avail!* s skip evt p)]) + (wrap-peek + s skip evt + (if (eq? v 0) + (choice-evt + (wrap-evt p (lambda (x) 0)) + (if evt (wrap-evt evt (lambda (x) #f)) never-evt)) + v)))) + (lambda () + (when close? (close-input-port p))) + (and (port-provides-progress-evts? p) + (lambda () (port-progress-evt p))) + (and (port-provides-progress-evts? p) + (lambda (n evt target-evt) (port-commit-peeked n evt target-evt p))) + (lambda () (port-next-location p)) + (lambda () (port-count-lines! p)) + (add1 (file-position p))))) + +;; Not kill-safe. +(define make-pipe-with-specials + ;; This implementation of pipes is almost CML-style, with a manager thread + ;; to guard access to the pipe content. But we only enable the manager + ;; thread when write evts are active; otherwise, we use a lock semaphore. + ;; (Actually, the lock semaphore has to be used all the time, to guard + ;; the flag indicating whether the manager thread is running.) + (lambda ([limit (expt 2 64)] [in-name 'pipe] [out-name 'pipe]) + (let-values ([(r w) (make-pipe limit)] + [(more) null] + [(more-last) #f] + [(more-sema) #f] + [(close-w?) #f] + [(lock-semaphore) (make-semaphore 1)] + [(mgr-th) #f] + [(via-manager?) #f] + [(mgr-ch) (make-channel)]) + (define (flush-more) + (if (null? more) + (begin (set! more-last #f) + (when close-w? (close-output-port w))) + (when (bytes? (mcar more)) + (let ([amt (bytes-length (mcar more))]) + (let ([wrote (write-bytes-avail* (mcar more) w)]) + (if (= wrote amt) + (begin (set! more (mcdr more)) + (flush-more)) + (begin + ;; This means that we let too many bytes + ;; get written while a special was pending. + ;; (The limit is disabled when a special + ;; is in the pipe.) + (set-mcar! more (subbytes (mcar more) wrote)) + ;; By peeking, make room for more: + (peek-byte r (sub1 (min (pipe-content-length w) + (- amt wrote)))) + (flush-more)))))))) + (define (read-one s) + (let ([v (read-bytes-avail!* s r)]) + (if (eq? v 0) + (if more-last + ;; Return a special + (let ([a (mcar more)]) + (set! more (mcdr more)) + (flush-more) + (lambda (file line col ppos) a)) + ;; Nothing available, yet. + (begin (unless more-sema (set! more-sema (make-semaphore))) + (wrap-evt (semaphore-peek-evt more-sema) + (lambda (x) 0)))) + v))) + (define (close-it) + (set! close-w? #t) + (unless more-last (close-output-port w)) + (when more-sema (semaphore-post more-sema))) + (define (write-these-bytes str start end) + (begin0 (if more-last + (let ([p (mcons (subbytes str start end) null)]) + (set-mcdr! more-last p) + (set! more-last p) + (- end start)) + (let ([v (write-bytes-avail* str w start end)]) + (if (zero? v) (wrap-evt w (lambda (x) #f)) v))) + (when more-sema + (semaphore-post more-sema) + (set! more-sema #f)))) + (define (write-spec v) + (let ([p (mcons v null)]) + (if more-last (set-mcdr! more-last p) (set! more p)) + (set! more-last p) + (when more-sema + (semaphore-post more-sema) + (set! more-sema #f)))) + (define (serve) + ;; A request is + ;; (list sym result-ch nack-evt . v) + ;; where `v' varies for different `sym's + ;; The possible syms are: read, reply, close, + ;; write, write-spec, write-evt, write-spec-evt + (let loop ([reqs null]) + (apply + sync + ;; Listen for a request: + (handle-evt + mgr-ch + (lambda (req) + (let ([req + ;; Most requests we handle immediately and + ;; convert to a reply. The manager thread + ;; implicitly has the lock. + (let ([reply (lambda (v) + (list 'reply (cadr req) (caddr req) v))]) + (case (car req) + [(read) + (reply (read-one (cadddr req)))] + [(close) + (reply (close-it))] + [(write) + (reply (apply write-these-bytes (cdddr req)))] + [(write-spec) + (reply (write-spec (cadddr req)))] + [else req]))]) + (loop (cons req reqs))))) + (if (and (null? reqs) via-manager?) + ;; If we can get the lock before another request + ;; turn off manager mode: + (handle-evt lock-semaphore + (lambda (x) + (set! via-manager? #f) + (semaphore-post lock-semaphore) + (loop null))) + never-evt) + (append + (map (lambda (req) + (case (car req) + [(reply) + (handle-evt (channel-put-evt (cadr req) (cadddr req)) + (lambda (x) (loop (remq req reqs))))] + [(write-spec-evt) + (if close-w? + ;; Report close error: + (handle-evt (channel-put-evt (cadr req) 'closed) + (lambda (x) (loop (remq req reqs)))) + ;; Try to write special: + (handle-evt (channel-put-evt (cadr req) #t) + (lambda (x) + ;; We sync'd, so now we *must* write + (write-spec (cadddr req)) + (loop (remq req reqs)))))] + [(write-evt) + (if close-w? + ;; Report close error: + (handle-evt (channel-put-evt (cadr req) 'closed) + (lambda (x) (loop (remq req reqs)))) + ;; Try to write bytes: + (let* ([start (list-ref req 4)] + [end (list-ref req 5)] + [len (if more-last + (- end start) + (min (- end start) + (max 0 + (- limit (pipe-content-length w)))))]) + (if (and (zero? len) (null? more)) + (handle-evt w (lambda (x) (loop reqs))) + (handle-evt + (channel-put-evt (cadr req) len) + (lambda (x) + ;; We sync'd, so now we *must* write + (write-these-bytes (cadddr req) start (+ start len)) + (loop (remq req reqs)))))))])) + reqs) + ;; nack => remove request (could be anything) + (map (lambda (req) + (handle-evt (caddr req) + (lambda (x) (loop (remq req reqs))))) + reqs))))) + (define (via-manager what req-sfx) + (thread-resume mgr-th (current-thread)) + (let ([ch (make-channel)]) + (sync (nack-guard-evt + (lambda (nack) + (channel-put mgr-ch (list* what ch nack req-sfx)) + ch))))) + (define (start-mgr) + (unless mgr-th (set! mgr-th (thread serve))) + (set! via-manager? #t)) + (define (evt what req-sfx) + (nack-guard-evt + (lambda (nack) + (resume-mgr) + (let ([ch (make-channel)]) + (call-with-semaphore + lock-semaphore + (lambda () + (unless mgr-th (set! mgr-th (thread serve))) + (set! via-manager? #t) + (thread-resume mgr-th (current-thread)) + (channel-put mgr-ch (list* what ch nack req-sfx)) + (wrap-evt ch (lambda (x) + (if (eq? x 'close) + (raise-mismatch-error 'write-evt "port is closed: " out) + x))))))))) + (define (resume-mgr) + (when mgr-th (thread-resume mgr-th (current-thread)))) + (define in + ;; ----- Input ------ + (make-input-port/read-to-peek + in-name + (lambda (s) + (let ([v (read-bytes-avail!* s r)]) + (if (eq? v 0) + (begin (resume-mgr) + (call-with-semaphore + lock-semaphore + (lambda () + (if via-manager? + (via-manager 'read (list s)) + (read-one s))))) + v))) + #f + void)) + (define out + ;; ----- Output ------ + (make-output-port + out-name + w + ;; write + (lambda (str start end buffer? w/break?) + (if (= start end) + 0 + (begin + (resume-mgr) + (call-with-semaphore + lock-semaphore + (lambda () + (if via-manager? + (via-manager 'write (list str start end)) + (write-these-bytes str start end))))))) + ;; close + (lambda () + (resume-mgr) + (call-with-semaphore + lock-semaphore + (lambda () + (if via-manager? (via-manager 'close null) (close-it))))) + ;; write-special + (lambda (v buffer? w/break?) + (resume-mgr) + (call-with-semaphore + lock-semaphore + (lambda () + (if via-manager? + (via-manager 'write-spec (list v)) + (write-spec v))))) + ;; write-evt + (lambda (str start end) + (if (= start end) + (wrap-evt always-evt (lambda (x) 0)) + (evt 'write-evt (list str start end)))) + ;; write-special-evt + (lambda (v) + (evt 'write-spec-evt (list v))))) + (values in out)))) + +(define input-port-append + (lambda (close-orig? . ports) + (make-input-port + (map object-name ports) + (lambda (str) + ;; Reading is easy -- read from the first port, + ;; and get rid of it if the result is eof + (if (null? ports) + eof + (let ([n (read-bytes-avail!* str (car ports))]) + (cond + [(eq? n 0) (wrap-evt (car ports) (lambda (x) 0))] + [(eof-object? n) + (when close-orig? (close-input-port (car ports))) + (set! ports (cdr ports)) + 0] + [else n])))) + (lambda (str skip unless-evt) + ;; Peeking is more difficult, due to skips. + (let loop ([ports ports][skip skip]) + (if (null? ports) + eof + (let ([n (peek-bytes-avail!* str skip unless-evt (car ports))]) + (cond + [(eq? n 0) + ;; Not ready, yet. + (peek-bytes-avail!-evt str skip unless-evt (car ports))] + [(eof-object? n) + ;; Port is exhausted, or we skipped past its input. + ;; If skip is not zero, we need to figure out + ;; how many chars were skipped. + (loop (cdr ports) + (- skip (compute-avail-to-skip skip (car ports))))] + [else n]))))) + (lambda () + (when close-orig? + (map close-input-port ports)))))) + +(define (convert-stream from from-port to to-port) + (let ([c (bytes-open-converter from to)] + [in (make-bytes 4096)] + [out (make-bytes 4096)]) + (unless c + (error 'convert-stream "could not create converter from ~e to ~e" + from to)) + (dynamic-wind + void + (lambda () + (let loop ([got 0]) + (let ([n (read-bytes-avail! in from-port got)]) + (let ([got (+ got (if (number? n) n 0))]) + (let-values ([(wrote used status) (bytes-convert c in 0 got out)]) + (when (eq? status 'error) + (error 'convert-stream "conversion error")) + (unless (zero? wrote) + (write-bytes out to-port 0 wrote)) + (bytes-copy! in 0 in used got) + (if (not (number? n)) + (begin + (unless (= got used) + (error 'convert-stream + "input stream ~a with a partial conversion" + (if (eof-object? n) "ended" "hit a special value"))) + (let-values ([(wrote status) (bytes-convert-end c out)]) + (when (eq? status 'error) + (error 'convert-stream "conversion-end error")) + (unless (zero? wrote) + (write-bytes out to-port 0 wrote)) + (if (eof-object? n) + ;; Success + (void) + (begin (write-special n to-port) + (loop 0))))) + (loop (- got used)))))))) + (lambda () (bytes-close-converter c))))) + +;; Helper for input-port-append; given a skip count +;; and an input port, determine how many characters +;; (up to upto) are left in the port. We figure this +;; out using binary search. +(define (compute-avail-to-skip upto p) + (let ([str (make-bytes 1)]) + (let loop ([upto upto][skip 0]) + (if (zero? upto) + skip + (let* ([half (quotient upto 2)] + [n (peek-bytes-avail!* str (+ skip half) #f p)]) + (if (eq? n 1) + (loop (- upto half 1) (+ skip half 1)) + (loop half skip))))))) + +(define make-limited-input-port + (lambda (port limit [close-orig? #t]) + (let ([got 0] + [lock-semaphore (make-semaphore 1)]) + (define (do-read str) + (let ([count (min (- limit got) (bytes-length str))]) + (if (zero? count) + eof + (let ([n (read-bytes-avail!* str port 0 count)]) + (cond [(eq? n 0) (wrap-evt port (lambda (x) 0))] + [(number? n) (set! got (+ got n)) n] + [(procedure? n) (set! got (add1 got)) n] + [else n]))))) + (define (do-peek str skip progress-evt) + (let ([count (max 0 (min (- limit got skip) (bytes-length str)))]) + (if (zero? count) + eof + (let ([n (peek-bytes-avail!* str skip progress-evt port 0 count)]) + (if (eq? n 0) + (wrap-evt port (lambda (x) 0)) + n))))) + (define (try-again) + (wrap-evt + (semaphore-peek-evt lock-semaphore) + (lambda (x) 0))) + (make-input-port + (object-name port) + (lambda (str) + (call-with-semaphore + lock-semaphore + do-read + try-again + str)) + (lambda (str skip progress-evt) + (call-with-semaphore + lock-semaphore + do-peek + try-again + str skip progress-evt)) + (lambda () + (when close-orig? + (close-input-port port))) + (and (port-provides-progress-evts? port) + (lambda () (port-progress-evt port))) + (and (port-provides-progress-evts? port) + (lambda (n evt target-evt) + (let loop () + (if (semaphore-try-wait? lock-semaphore) + (let ([ok? (port-commit-peeked n evt target-evt port)]) + (when ok? (set! got (+ got n))) + (semaphore-post lock-semaphore) + ok?) + (sync (handle-evt evt (lambda (v) #f)) + (handle-evt (semaphore-peek-evt lock-semaphore) + (lambda (v) (loop)))))))) + (lambda () (port-next-location port)) + (lambda () (port-count-lines! port)) + (add1 (file-position port)))))) + +(define special-filter-input-port + (lambda (p filter [close? #t]) + (unless (input-port? p) + (raise-argument-error 'special-filter-input-port "input-port?" p)) + (unless (and (procedure? filter) + (procedure-arity-includes? filter 2)) + (raise-argument-error 'special-filter-input-port "(any/c bytes? . -> . any/c)" filter)) + (make-input-port + (object-name p) + (lambda (s) + (let ([v (read-bytes-avail!* s p)]) + (cond + [(eq? v 0) (wrap-evt p (lambda (x) 0))] + [(procedure? v) (filter v s)] + [else v]))) + (lambda (s skip evt) + (let ([v (peek-bytes-avail!* s skip evt p)]) + (cond + [(eq? v 0) + (choice-evt + (wrap-evt p (lambda (x) 0)) + (if evt (wrap-evt evt (lambda (x) #f)) never-evt))] + [(procedure? v) (filter v s)] + [else v]))) + (lambda () + (when close? (close-input-port p))) + (and (port-provides-progress-evts? p) + (lambda () (port-progress-evt p))) + (and (port-provides-progress-evts? p) + (lambda (n evt target-evt) (port-commit-peeked n evt target-evt p))) + (lambda () (port-next-location p)) + (lambda () (port-count-lines! p)) + (add1 (file-position p))))) + +;; ---------------------------------------- + +(define (poll-or-spawn go) + (poll-guard-evt + (lambda (poll?) + (if poll? + ;; In poll mode, call `go' directly: + (let ([v (go never-evt #f #t)]) + (if v (wrap-evt always-evt (lambda (x) v)) never-evt)) + ;; In non-poll mode, start a thread to call go + (nack-guard-evt + (lambda (nack) + (define ch (make-channel)) + (define ready (make-semaphore)) + (let ([t (thread (lambda () + (parameterize-break #t + (with-handlers ([exn:break? void]) + (semaphore-post ready) + (go nack ch #f)))))]) + (thread (lambda () + (sync nack) + (semaphore-wait ready) + (break-thread t)))) + ch)))))) + +(define (read-at-least-bytes!-evt orig-bstr input-port need-more? shrink combo + peek-offset prog-evt) + ;; go is the main reading function, either called directly for + ;; a poll, or called in a thread for a non-poll read + (define (go nack ch poll?) + (let try-again ([pos 0] [bstr orig-bstr] [progress-evt #f]) + (let* ([progress-evt + ;; if no progress event is given, get one to ensure that + ;; consecutive bytes are read and can be committed: + (or progress-evt prog-evt (port-progress-evt input-port))] + [v (and + ;; to implement weak support for reusing the buffer in `read-bytes!-evt', + ;; need to check nack after getting progress-evt: + (not (sync/timeout 0 nack)) + ;; try to get bytes: + ((if poll? peek-bytes-avail!* peek-bytes-avail!) + bstr (+ pos (or peek-offset 0)) progress-evt input-port pos))]) + (cond + ;; the first two cases below are shortcuts, and not + ;; strictly necessary + [(sync/timeout 0 nack) + (void)] + [(sync/timeout 0 progress-evt) + (cond [poll? #f] + [prog-evt (void)] + [else (try-again 0 bstr #f)])] + [(and poll? (equal? v 0)) #f] + [(and (number? v) (need-more? bstr (+ pos v))) + => (lambda (bstr) (try-again (+ v pos) bstr progress-evt))] + [else + (let* ([v2 (cond [(number? v) (shrink bstr (+ v pos))] + [(positive? pos) pos] + [else v])] + [result (combo bstr v2)]) + (cond + [peek-offset + (if poll? + result + (sync (or prog-evt never-evt) + (channel-put-evt ch result)))] + [(port-commit-peeked (if (number? v2) v2 1) + progress-evt + (if poll? + always-evt + (channel-put-evt ch result)) + input-port) + result] + [(and (eof-object? eof) + (zero? pos) + (not (sync/timeout 0 progress-evt))) + ;; Must be a true end-of-file + (let ([result (combo bstr eof)]) + (if poll? result (channel-put ch result)))] + [poll? #f] + [else (try-again 0 orig-bstr #f)]))])))) + (if (zero? (bytes-length orig-bstr)) + (wrap-evt always-evt (lambda (x) 0)) + (poll-or-spawn go))) + +(define (-read-bytes-avail!-evt bstr input-port peek-offset prog-evt) + (read-at-least-bytes!-evt bstr input-port + (lambda (bstr v) (if (zero? v) bstr #f)) + (lambda (bstr v) v) + (lambda (bstr v) v) + peek-offset prog-evt)) + +(define (read-bytes-avail!-evt bstr input-port) + (-read-bytes-avail!-evt bstr input-port #f #f)) + +(define (peek-bytes-avail!-evt bstr peek-offset prog-evt input-port) + (-read-bytes-avail!-evt bstr input-port peek-offset prog-evt)) + +(define (-read-bytes!-evt bstr input-port peek-offset prog-evt) + (read-at-least-bytes!-evt bstr input-port + (lambda (bstr v) + (if (v . < . (bytes-length bstr)) bstr #f)) + (lambda (bstr v) v) + (lambda (bstr v) v) + peek-offset prog-evt)) + +(define (read-bytes!-evt bstr input-port [progress-evt #f]) + (-read-bytes!-evt bstr input-port #f progress-evt)) + +(define (peek-bytes!-evt bstr peek-offset prog-evt input-port) + (-read-bytes!-evt bstr input-port peek-offset prog-evt)) + +(define (-read-bytes-evt len input-port peek-offset prog-evt) + (guard-evt + (lambda () + (let ([bstr (make-bytes len)]) + (wrap-evt + (-read-bytes!-evt bstr input-port peek-offset prog-evt) + (lambda (v) + (if (number? v) + (if (= v len) bstr (subbytes bstr 0 v)) + v))))))) + +(define (read-bytes-evt len input-port) + (-read-bytes-evt len input-port #f #f)) + +(define (peek-bytes-evt len peek-offset prog-evt input-port) + (-read-bytes-evt len input-port peek-offset prog-evt)) + +(define (-read-string-evt goal input-port peek-offset prog-evt) + (if (zero? goal) + (wrap-evt always-evt (lambda (x) "")) + (guard-evt + (lambda () + (let ([bstr (make-bytes goal)] + [c (bytes-open-converter "UTF-8-permissive" "UTF-8")]) + (wrap-evt + (read-at-least-bytes!-evt + bstr input-port + (lambda (bstr v) + (if (= v (bytes-length bstr)) + ;; We can't easily use bytes-utf-8-length here, + ;; because we may need more bytes to figure out + ;; the true role of the last byte. The + ;; `bytes-convert' function lets us deal with + ;; the last byte properly. + (let-values ([(bstr2 used status) + (bytes-convert c bstr 0 v)]) + (let ([got (bytes-utf-8-length bstr2)]) + (if (= got goal) + ;; Done: + #f + ;; Need more bytes: + (let ([bstr2 (make-bytes (+ v (- goal got)))]) + (bytes-copy! bstr2 0 bstr) + bstr2)))) + ;; Need more bytes in bstr: + bstr)) + (lambda (bstr v) + ;; We may need one less than v, + ;; because we may have had to peek + ;; an extra byte to discover an + ;; error in the stream. + (if ((bytes-utf-8-length bstr #\? 0 v) . > . goal) (sub1 v) v)) + cons + peek-offset prog-evt) + (lambda (bstr+v) + (let ([bstr (car bstr+v)] + [v (cdr bstr+v)]) + (if (number? v) + (bytes->string/utf-8 bstr #\? 0 v) + v))))))))) + +(define (read-string-evt goal input-port) + (-read-string-evt goal input-port #f #f)) + +(define (peek-string-evt goal peek-offset prog-evt input-port) + (-read-string-evt goal input-port peek-offset prog-evt)) + +(define (-read-string!-evt str input-port peek-offset prog-evt) + (wrap-evt + (-read-string-evt (string-length str) input-port peek-offset prog-evt) + (lambda (s) + (if (string? s) + (begin (string-copy! str 0 s) + (string-length s)) + s)))) + +(define (read-string!-evt str input-port) + (-read-string!-evt str input-port #f #f)) + +(define (peek-string!-evt str peek-offset prog-evt input-port) + (-read-string!-evt str input-port peek-offset prog-evt)) + +(define (regexp-match-evt pattern input-port) + (define (go nack ch poll?) + (let try-again () + (if (port-closed? input-port) + #f + (let* ([progress-evt (port-progress-evt input-port)] + [m ((if poll? + regexp-match-peek-positions-immediate + regexp-match-peek-positions) + pattern input-port 0 #f progress-evt)]) + (cond + [(sync/timeout 0 nack) (void)] + [(sync/timeout 0 progress-evt) (try-again)] + [(not m) + (if poll? + #f + (sync nack + (handle-evt progress-evt + (lambda (x) (try-again)))))] + [else + (let ([m2 (map (lambda (p) + (and p + (let ([bstr (make-bytes (- (cdr p) (car p)))]) + (unless (= (car p) (cdr p)) + (let loop ([offset 0]) + (let ([v (peek-bytes-avail! bstr (car p) progress-evt input-port offset)]) + (unless (zero? v) + (when ((+ offset v) . < . (bytes-length bstr)) + (loop (+ offset v))))))) + bstr))) + m)]) + (cond + [(and (zero? (cdar m)) (or poll? (channel-put ch m2))) + m2] + [(port-commit-peeked + (cdar m) + progress-evt + (if poll? always-evt (channel-put-evt ch m2)) + input-port) + m2] + [poll? #f] + [else (try-again)]))]))))) + (poll-or-spawn go)) + +(define-syntax (newline-rx stx) + (syntax-case stx () + [(_ str) + (datum->syntax + #'here + (byte-regexp (string->bytes/latin-1 + (format "^(?:(.*?)~a)|(.*?$)" (syntax-e #'str)))))])) + +(define read-bytes-line-evt + (lambda (input-port [mode 'linefeed]) + (wrap-evt + (regexp-match-evt (case mode + [(linefeed) (newline-rx "\n")] + [(return) (newline-rx "\r")] + [(return-linefeed) (newline-rx "\r\n")] + [(any) (newline-rx "(?:\r\n|\r|\n)")] + [(any-one) (newline-rx "[\r\n]")]) + input-port) + (lambda (m) + (or (cadr m) + (let ([l (caddr m)]) + (if (and l (zero? (bytes-length l))) eof l))))))) + +(define read-line-evt + (lambda (input-port [mode 'linefeed]) + (wrap-evt + (read-bytes-line-evt input-port mode) + (lambda (s) + (if (eof-object? s) s (bytes->string/utf-8 s #\?)))))) + +(define (eof-evt input-port) + (wrap-evt (regexp-match-evt #rx#"^$" input-port) + (lambda (x) eof))) + +;; -------------------------------------------------- + +;; Helper for reencode-input-port: simulate the composition +;; of a CRLF/CRNEL/NEL/LS -> LF decoding and some other +;; decoding. +;; The "converter" `c' is (mcons converter saved), where +;; saved is #f if no byte is saved, otherwise it's a saved +;; byte. It would be nicer and closer to the `bytes-convert' +;; interface to not consume a trailing CR, but we don't +;; know the inner encoding, and so we can't rewind it. +(define (bytes-convert/post-nl c buf buf-start buf-end dest) + (cond + [(and (mcdr c) (= buf-start buf-end)) + ;; No more bytes to convert; provide single + ;; saved byte if it's not #\return, otherwise report 'aborts + (if (eq? (mcdr c) (char->integer #\return)) + (values 0 0 'aborts) + (begin (bytes-set! dest 0 (mcdr c)) + (set-mcdr! c #f) + (values 1 0 'complete)))] + [(and (mcdr c) (= 1 (bytes-length dest))) + ;; We have a saved byte, but the destination is only 1 byte. + ;; If the saved byte is a return, we need to try decoding more, + ;; which means we may end up saving a non-#\return byte: + (if (eq? (mcdr c) (char->integer #\return)) + (let-values ([(got-c used-c status) + (bytes-convert (mcar c) buf buf-start buf-end dest)]) + (if (positive? got-c) + (cond + [(eq? (bytes-ref dest 0) (char->integer #\newline)) + ;; Found CRLF, so just produce LF (and nothing to save) + (set-mcdr! c #f) + (values 1 used-c status)] + [else + ;; Next char fits in a byte, so it isn't NEL, etc. + ;; Save it, and for now return the #\return. + (set-mcdr! c (bytes-ref dest 0)) + (bytes-set! dest 0 (char->integer #\newline)) + (values 1 used-c 'continues)]) + ;; Didn't decode any more; ask for bigger input, etc. + (values 0 0 status))) + ;; Saved a non-#\return, so use that up now. + (begin (bytes-set! dest 0 (mcdr c)) + (set-mcdr! c #f) + (values 1 0 'continues)))] + [else + ;; Normal convert, maybe prefixed: + (let-values ([(got-c used-c status) + (bytes-convert (mcar c) buf buf-start buf-end dest + (if (mcdr c) 1 0))]) + (let* ([got-c (if (mcdr c) + ;; Insert saved character: + (begin (bytes-set! dest 0 (char->integer #\return)) + (set-mcdr! c #f) + (add1 got-c)) + got-c)] + [got-c (if (and (positive? got-c) + (eq? (bytes-ref dest (sub1 got-c)) + (char->integer #\return)) + (not (eq? status 'error))) + ;; Save trailing carriage return: + (begin (set-mcdr! c (char->integer #\return)) + (sub1 got-c)) + got-c)]) + ;; Iterate through the converted bytes to apply the newline + ;; conversions: + (let loop ([i 0] [j 0]) + (cond + [(= i got-c) + (values (- got-c (- i j)) + used-c + (if (and (eq? 'complete status) (mcdr c)) + 'aborts + status))] + [(eq? (bytes-ref dest i) (char->integer #\return)) + (cond [(= (add1 i) got-c) + ;; Found lone CR: + (bytes-set! dest j (char->integer #\newline)) + (loop (add1 i) (add1 j))] + [(eq? (bytes-ref dest (add1 i)) (char->integer #\newline)) + ;; Found CRLF: + (bytes-set! dest j (char->integer #\newline)) + (loop (+ i 2) (add1 j))] + [(and (eq? (bytes-ref dest (add1 i)) #o302) + (eq? (bytes-ref dest (+ i 2)) #o205)) + ;; Found CRNEL: + (bytes-set! dest j (char->integer #\newline)) + (loop (+ i 3) (add1 j))] + [else + ;; Found lone CR: + (bytes-set! dest j (char->integer #\newline)) + (loop (add1 i) (add1 j))])] + [(and (eq? (bytes-ref dest i) #o302) + (eq? (bytes-ref dest (+ i 1)) #o205)) + ;; Found NEL: + (bytes-set! dest j (char->integer #\newline)) + (loop (+ i 2) (add1 j))] + [(and (eq? (bytes-ref dest i) #o342) + (eq? (bytes-ref dest (+ i 1)) #o200) + (eq? (bytes-ref dest (+ i 2)) #o250)) + ;; Found LS: + (bytes-set! dest j (char->integer #\newline)) + (loop (+ i 3) (add1 j))] + [else + ;; Anything else: + (unless (= i j) + (bytes-set! dest j (bytes-ref dest i))) + (loop (add1 i) (add1 j))]))))])) + +(define reencode-input-port + (lambda (port encoding [error-bytes #f] [close? #f] + [name (object-name port)] + [newline-convert? #f] + [decode-error (lambda (msg port) + (error 'reencode-input-port + (format "~a: ~~e" msg) + port))]) + (let ([c (let ([c (bytes-open-converter encoding "UTF-8")]) + (if newline-convert? (mcons c #f) c))] + [ready-bytes (make-bytes 1024)] + [ready-start 0] + [ready-end 0] + [buf (make-bytes 1024)] + [buf-start 0] + [buf-end 0] + [buf-eof? #f] + [buf-eof-result #f] + [buffer-mode (or (file-stream-buffer-mode port) 'none)]) + ;; Main reader entry: + (define (read-it s) + (cond + [(> ready-end ready-start) + ;; We have leftover converted bytes: + (let ([cnt (min (bytes-length s) (- ready-end ready-start))]) + (bytes-copy! s 0 ready-bytes ready-start (+ ready-start cnt)) + (set! ready-start (+ ready-start cnt)) + cnt)] + [else + ;; Try converting already-read bytes: + (let-values ([(got-c used-c status) + (if (= buf-start buf-end) + (values 0 0 'aborts) + ((if newline-convert? + bytes-convert/post-nl + bytes-convert) + c buf buf-start buf-end s))]) + (when (positive? used-c) (set! buf-start (+ used-c buf-start))) + (cond + [(positive? got-c) + ;; We converted some bytes into s. + got-c] + [(eq? status 'aborts) + (if buf-eof? + ;; Had an EOF or special in the stream. + (if (= buf-start buf-end) + (if (and newline-convert? (mcdr c)) ; should be bytes-convert-end + ;; Have leftover CR: + (begin + (bytes-set! s 0 + (if (eq? (mcdr c) (char->integer #\return)) + (char->integer #\newline) + (mcdr c))) + (set-mcdr! c #f) + 1) + ;; Return EOF: + (begin0 buf-eof-result + (set! buf-eof? #f) + (set! buf-eof-result #f))) + (handle-error s)) + ;; Need more bytes. + (begin + (when (positive? buf-start) + (bytes-copy! buf 0 buf buf-start buf-end) + (set! buf-end (- buf-end buf-start)) + (set! buf-start 0)) + (let* ([amt (bytes-length s)] + [c (read-bytes-avail!* + buf port buf-end + (if (eq? buffer-mode 'block) + (bytes-length buf) + (min (bytes-length buf) (+ buf-end amt))))]) + (cond + [(or (eof-object? c) (procedure? c)) + ;; Got EOF/procedure + (set! buf-eof? #t) + (set! buf-eof-result c) + (read-it s)] + [(zero? c) + ;; No bytes ready --- try again later. + (wrap-evt port (lambda (v) 0))] + [else + ;; Got some bytes; loop to decode. + (set! buf-end (+ buf-end c)) + (read-it s)]))))] + [(eq? status 'error) + (handle-error s)] + [(eq? status 'continues) + ;; Need more room to make progress at all. + ;; Decode into ready-bytes. + (let-values ([(got-c used-c status) ((if newline-convert? + bytes-convert/post-nl + bytes-convert) + c buf buf-start buf-end ready-bytes)]) + (unless (memq status '(continues complete)) + (decode-error "unable to make decoding progress" + port)) + (set! ready-start 0) + (set! ready-end got-c) + (set! buf-start (+ used-c buf-start)) + (read-it s))]))])) + + ;; Raise exception or discard first buffered byte. + ;; We assume that read-bytes is empty + (define (handle-error s) + (if error-bytes + (begin + (set! buf-start (add1 buf-start)) + (let ([cnt (min (bytes-length s) + (bytes-length error-bytes))]) + (bytes-copy! s 0 error-bytes 0 cnt) + (bytes-copy! ready-bytes 0 error-bytes cnt) + (set! ready-start 0) + (set! ready-end (- (bytes-length error-bytes) cnt)) + cnt)) + (decode-error "decoding error in input stream" port))) + + (unless c + (error 'reencode-input-port + "could not create converter from ~e to UTF-8" + encoding)) + + (make-input-port/read-to-peek + name + read-it + #f + (lambda () + (when close? (close-input-port port)) + (bytes-close-converter (if newline-convert? (mcar c) c))) + #f void 1 + (case-lambda + [() buffer-mode] + [(mode) (set! buffer-mode mode)]) + (eq? buffer-mode 'block))))) + +;; -------------------------------------------------- + +(define reencode-output-port + (lambda (port encoding [error-bytes #f] [close? #f] + [name (object-name port)] + [convert-newlines-to #f] + [decode-error (lambda (msg port) + (error 'reencode-output-port + (format "~a: ~~e" msg) + port))]) + (let ([c (bytes-open-converter "UTF-8" encoding)] + [ready-bytes (make-bytes 1024)] + [ready-start 0] + [ready-end 0] + [out-bytes (make-bytes 1024)] + [out-start 0] + [out-end 0] + [buffer-mode (or (file-stream-buffer-mode port) 'block)] + [debuffer-buf #f] + [newline-buffer #f]) + (define-values (buffered-r buffered-w) (make-pipe 4096)) + + ;; The main writing entry point: + (define (write-it s start end no-buffer&block? enable-break?) + (cond + [(= start end) + ;; This is a flush request; no-buffer&block? must be #f + ;; Note: we could get stuck because only half an encoding + ;; is available in out-bytes. + (flush-buffer-pipe #f enable-break?) + (flush-some #f enable-break?) + (if (buffer-flushed?) + 0 + (write-it s start end no-buffer&block? enable-break?))] + [no-buffer&block? + (case (flush-all #t enable-break?) + [(not-done) + ;; We couldn't flush right away, so give up. + #f] + [(done) + (non-blocking-write s start end)] + [(stuck) + ;; We need more bytes to make progress. + ;; Add out-bytes and s into one string for non-blocking-write. + (let ([s2 (bytes-append (subbytes out-bytes out-start out-end) + (subbytes s start end))] + [out-len (- out-end out-start)]) + (let ([c (non-blocking-write s2 0 (bytes-length s2))]) + (and c (begin (set! out-start 0) + (set! out-end 0) + (- c out-len)))))])] + [(and (eq? buffer-mode 'block) + (zero? (pipe-content-length buffered-r))) + ;; The port system can buffer to a pipe faster, so give it a pipe. + buffered-w] + [else + ;; Flush/buffer from pipe, first: + (flush-buffer-pipe #f enable-break?) + ;; Flush as needed to make room in the buffer: + (make-buffer-room #f enable-break?) + ;; Buffer some bytes: + (let-values ([(s2 start2 cnt2 used) + (convert-newlines s start + (- end start) + (- (bytes-length out-bytes) out-end))]) + (if (zero? used) + ;; No room --- try flushing again: + (write-it s start end #f enable-break?) + ;; Buffer and report success: + (begin + (bytes-copy! out-bytes out-end s2 start2 (+ start2 cnt2)) + (set! out-end (+ cnt2 out-end)) + (case buffer-mode + [(none) (flush-all-now enable-break?)] + [(line) (when (regexp-match-positions #rx#"[\r\n]" s start + (+ start used)) + (flush-all-now enable-break?))]) + used)))])) + + (define (convert-newlines s start cnt avail) + ;; If newline converting is on, try convert up to cnt + ;; bytes to produce a result that fits in avail bytes. + (if convert-newlines-to + ;; Conversion: + (let ([end (+ start cnt)] + [avail (min avail 1024)]) + (unless newline-buffer + (set! newline-buffer (make-bytes 1024))) + (let loop ([i start][j 0]) + (cond + [(or (= j avail) (= i end)) (values newline-buffer 0 j i)] + [(eq? (char->integer #\newline) (bytes-ref s i)) + ;; Newline conversion + (let ([len (bytes-length convert-newlines-to)]) + (if ((+ j len) . > . avail) + ;; No room + (values newline-buffer 0 j i) + ;; Room + (begin (bytes-copy! newline-buffer j convert-newlines-to) + (loop (add1 i) (+ j len)))))] + [else + (bytes-set! newline-buffer j (bytes-ref s i)) + (loop (add1 i) (add1 j))]))) + ;; No conversion: + (let ([cnt (min cnt avail)]) + (values s start cnt cnt)))) + + (define (make-buffer-room non-block? enable-break?) + (when (or (> ready-end ready-start) + (< (- (bytes-length out-bytes) out-end) 100)) + ;; Make room for conversion. + (flush-some non-block? enable-break?) ;; convert some + (flush-some non-block? enable-break?)) ;; write converted + ;; Make room in buffer + (when (positive? out-start) + (bytes-copy! out-bytes 0 out-bytes out-start out-end) + (set! out-end (- out-end out-start)) + (set! out-start 0))) + + (define (flush-buffer-pipe non-block? enable-break?) + (let loop () + (if (zero? (pipe-content-length buffered-r)) + 'done + (begin + (unless debuffer-buf (set! debuffer-buf (make-bytes 4096))) + (make-buffer-room non-block? enable-break?) + (let ([amt (- (bytes-length out-bytes) out-end)]) + (if (zero? amt) + 'stuck + (if convert-newlines-to + ;; Peek, convert newlines, write, then read converted amount: + (let ([cnt (peek-bytes-avail! debuffer-buf 0 #f buffered-r + 0 amt)]) + (let-values ([(s2 start2 cnt2 used) + (convert-newlines debuffer-buf 0 cnt amt)]) + (bytes-copy! out-bytes out-end s2 start2 cnt2) + (set! out-end (+ cnt2 out-end)) + (read-bytes-avail! debuffer-buf buffered-r 0 used) + (loop))) + ;; Skip an indirection: read directly and write: + (let ([cnt (read-bytes-avail! debuffer-buf buffered-r + 0 amt)]) + (bytes-copy! out-bytes out-end debuffer-buf 0 cnt) + (set! out-end (+ cnt out-end)) + (loop))))))))) + + (define (non-blocking-write s start end) + ;; For now, everything that we can flushed is flushed. + ;; Try to write the minimal number of bytes, and hope for the + ;; best. If none of all of the minimal bytes get written, + ;; everyone is happy enough. If some of the bytes get written, + ;; the we will have buffered bytes when we shouldn't have. + ;; That probably won't happen, but we can't guarantee it. + (if (sync/timeout 0.0 port) + ;; We should be able to write one byte... + (let loop ([len 1]) + (let*-values ([(s2 start2 len2 used) + (convert-newlines s start (- end start) len)] + [(got-c used-c status) + (bytes-convert c s2 start2 (+ start2 len2) + ready-bytes)]) + (cond + [(positive? got-c) + (try-flush-ready got-c used-c) + ;; If used-c < len2, then we converted only partially + ;; --- which is strange, because we kept adding + ;; bytes one at a time. we will just guess is that + ;; the unused bytes were not converted bytes, and + ;; generally hope that this sort of encoding doesn't + ;; show up. + (- used (- len2 used-c))] + [(eq? status 'aborts) + (if (< len (- end start)) + ;; Try converting a bigger chunk + (loop (add1 len)) + ;; We can't flush half an encoding, so just buffer it. + (begin (when (> len2 (bytes-length out-bytes)) + (raise-insane-decoding-length)) + (bytes-copy! out-bytes 0 s2 start2 (+ start2 len2)) + (set! out-start 0) + (set! out-end len2) + used))] + [(eq? status 'continues) + ;; Not enough room in ready-bytes!? We give up. + (raise-insane-decoding-length)] + [else + ;; Encoding error. Try to flush error bytes. + (let ([cnt (bytes-length error-bytes)]) + (bytes-copy! ready-bytes 0 error-bytes) + (try-flush-ready cnt 1) + used)]))) + ;; Port is not ready for writing: + #f)) + + (define (write-special-it v no-buffer&block? enable-break?) + (cond + [(buffer-flushed?) + ((if no-buffer&block? + write-special-avail* + (if enable-break? + (lambda (v p) (parameterize-break #t (write-special v p))) + write-special)) + v port)] + [else + ;; Note: we could get stuck because only half an encoding + ;; is available in out-bytes. + (flush-buffer-pipe no-buffer&block? enable-break?) + (flush-some no-buffer&block? enable-break?) + (if (or (buffer-flushed?) (not no-buffer&block?)) + (write-special-it v no-buffer&block? enable-break?) + #f)])) + + ;; flush-all : -> 'done, 'not-done, or 'stuck + (define (flush-all non-block? enable-break?) + (if (eq? (flush-buffer-pipe non-block? enable-break?) 'done) + (let ([orig-none-ready? (= ready-start ready-end)] + [orig-out-start out-start] + [orig-out-end out-end]) + (flush-some non-block? enable-break?) + (if (buffer-flushed?) + 'done + ;; Couldn't flush everything. One possibility is that we need + ;; more bytes to convert before a flush. + (if (and orig-none-ready? + (= ready-start ready-end) + (= orig-out-start out-start) + (= orig-out-end out-end)) + 'stuck + 'not-done))) + 'stuck)) + + (define (flush-all-now enable-break?) + (case (flush-all #f enable-break?) + [(not-done) (flush-all-now enable-break?)])) + + (define (buffer-flushed?) + (and (= ready-start ready-end) + (= out-start out-end) + (zero? (pipe-content-length buffered-r)))) + + ;; Try to flush immediately a certain number of bytes. + ;; we've already converted them, so we have to keep + ;; the bytes in any case. + (define (try-flush-ready got-c used-c) + (let ([c (write-bytes-avail* ready-bytes port 0 got-c)]) + (unless (= c got-c) + (set! ready-start c) + (set! ready-end got-c)))) + + ;; Try to make progress flushing buffered bytes + (define (flush-some non-block? enable-break?) + (unless (= ready-start ready-end) + ;; Flush converted bytes: + (let ([cnt ((cond [non-block? write-bytes-avail*] + [enable-break? write-bytes-avail/enable-break] + [else write-bytes-avail]) + ready-bytes port ready-start ready-end)]) + (set! ready-start (+ ready-start cnt)))) + (when (= ready-start ready-end) + ;; Convert more, if available: + (set! ready-start 0) + (set! ready-end 0) + (when (> out-end out-start) + (let-values ([(got-c used-c status) + (bytes-convert c out-bytes out-start out-end + ready-bytes)]) + (set! ready-end got-c) + (set! out-start (+ out-start used-c)) + (when (and (eq? status 'continues) (zero? used-c)) + ;; Yikes! Size of ready-bytes isn't enough room for progress!? + (raise-insane-decoding-length)) + (when (and (eq? status 'error) (zero? used-c)) + ;; No progress before an encoding error. + (if error-bytes + ;; Write error bytes and drop an output byte: + (begin (set! out-start (add1 out-start)) + (bytes-copy! ready-bytes 0 error-bytes) + (set! ready-end (bytes-length error-bytes))) + ;; Raise an exception: + (begin + (set! out-start out-end) ;; flush buffer so close can work + (decode-error + "error decoding output to stream" + port)))))))) + + ;; This error is used when decoding wants more bytes to make + ;; progress even though we've supplied hundreds of bytes + (define (raise-insane-decoding-length) + (decode-error "unable to make decoding progress" port)) + + ;; Check that a decoder is available: + (unless c + (error 'reencode-output-port + "could not create converter from ~e to UTF-8" + encoding)) + + (make-output-port + name + port + write-it + (lambda () + ;; Flush output + (write-it #"" 0 0 #f #f) + (when close? + (close-output-port port)) + (bytes-close-converter c)) + write-special-it + #f #f + #f void + 1 + (case-lambda + [() buffer-mode] + [(mode) (let ([old buffer-mode]) + (set! buffer-mode mode) + (when (or (and (eq? old 'block) (memq mode '(none line))) + (and (eq? old 'line) (memq mode '(none)))) + ;; Flush output + (write-it #"" 0 0 #f #f)))]))))) + +;; ---------------------------------------- + +(define dup-output-port + (lambda (p [close? #f]) + (let ([new (transplant-output-port + p + (lambda () (port-next-location p)) + (add1 (file-position p)) + close? + (lambda () (port-count-lines! p)))]) + (port-display-handler new (port-display-handler p)) + (port-write-handler new (port-write-handler p)) + new))) + +(define dup-input-port + (lambda (p [close? #f]) + (let ([new (transplant-input-port + p + (lambda () (port-next-location p)) + (add1 (file-position p)) + close? + (lambda () (port-count-lines! p)))]) + (port-read-handler new (port-read-handler p)) + new))) + +;; ---------------------------------------- + +(provide open-output-nowhere make-pipe-with-specials make-input-port/read-to-peek peeking-input-port @@ -24,29 +1809,41 @@ reencode-output-port dup-input-port dup-output-port - - read-bytes-avail!-evt - peek-bytes-avail!-evt - read-bytes!-evt - peek-bytes!-evt - read-bytes-evt - peek-bytes-evt - read-string!-evt - peek-string!-evt - read-string-evt - peek-string-evt - regexp-match-evt - read-bytes-line-evt - read-line-evt - eof-evt - - ;; defined here and not in racket/port strip-shell-command-start) -;; ---------------------------------------- +(provide/contract + (read-bytes-avail!-evt (mutable-bytes? input-port-with-progress-evts? + . -> . evt?)) + (peek-bytes-avail!-evt (mutable-bytes? exact-nonnegative-integer? evt?/false + input-port-with-progress-evts? + . -> . evt?)) + (read-bytes!-evt (mutable-bytes? input-port-with-progress-evts? . -> . evt?)) + (peek-bytes!-evt (mutable-bytes? exact-nonnegative-integer? evt?/false + input-port-with-progress-evts? + . -> . evt?)) + (read-bytes-evt (exact-nonnegative-integer? input-port-with-progress-evts? + . -> . evt?)) + (peek-bytes-evt (exact-nonnegative-integer? exact-nonnegative-integer? + evt?/false input-port-with-progress-evts? + . -> . evt?)) + (read-string!-evt (mutable-string? input-port-with-progress-evts? + . -> . evt?)) + (peek-string!-evt (mutable-string? exact-nonnegative-integer? evt?/false + input-port-with-progress-evts? + . -> . evt?)) + (read-string-evt (exact-nonnegative-integer? input-port-with-progress-evts? + . -> . evt?)) + (peek-string-evt (exact-nonnegative-integer? exact-nonnegative-integer? + evt?/false input-port-with-progress-evts? + . -> . evt?)) + (regexp-match-evt ((or/c regexp? byte-regexp? string? bytes?) + input-port-with-progress-evts? + . -> . evt?)) -(define (strip-shell-command-start in) - (when (regexp-match-peek #rx#"^#![^\r\n]*" in) - (let loop ([s (read-line in)]) - (when (regexp-match #rx#"\\\\$" s) - (loop (read-line in)))))) + (read-bytes-line-evt (case-> (input-port-with-progress-evts? . -> . evt?) + (input-port-with-progress-evts? line-mode-symbol? + . -> . evt?))) + (read-line-evt (case-> (input-port-with-progress-evts? . -> . evt?) + (input-port-with-progress-evts? line-mode-symbol? + . -> . evt?))) + (eof-evt (input-port-with-progress-evts? . -> . evt?))) diff --git a/collects/racket/private/info.rkt b/collects/mzlib/private/info.rkt similarity index 100% rename from collects/racket/private/info.rkt rename to collects/mzlib/private/info.rkt diff --git a/collects/racket/private/port.rkt b/collects/mzlib/private/port.rkt similarity index 98% rename from collects/racket/private/port.rkt rename to collects/mzlib/private/port.rkt index b5990fd058..de7546e822 100644 --- a/collects/racket/private/port.rkt +++ b/collects/mzlib/private/port.rkt @@ -3,7 +3,7 @@ ;; used by contract.rkt, which is used by port.rkt --- so we ;; break the cycle with this module. ;; -;; copy-port is used by racket/private/streams.rkt, which is used by +;; copy-port is used by mzlib/private/streams.rkt, which is used by ;; racket/place.rkt, which we want to load without loading contracts ;; --- so copy port is place in this module. diff --git a/collects/racket/private/runtime-path-table.rkt b/collects/mzlib/private/runtime-path-table.rkt similarity index 100% rename from collects/racket/private/runtime-path-table.rkt rename to collects/mzlib/private/runtime-path-table.rkt diff --git a/collects/racket/private/shared-body.rkt b/collects/mzlib/private/shared-body.rkt similarity index 100% rename from collects/racket/private/shared-body.rkt rename to collects/mzlib/private/shared-body.rkt diff --git a/collects/racket/private/streams.rkt b/collects/mzlib/private/streams.rkt similarity index 98% rename from collects/racket/private/streams.rkt rename to collects/mzlib/private/streams.rkt index 5f655e9926..694cc6473d 100644 --- a/collects/racket/private/streams.rkt +++ b/collects/mzlib/private/streams.rkt @@ -1,6 +1,6 @@ #lang racket/base -(require racket/private/port) +(require "port.rkt") (provide if-stream-out if-stream-in diff --git a/collects/racket/private/this-expression-source-directory.rkt b/collects/mzlib/private/this-expression-source-directory.rkt similarity index 100% rename from collects/racket/private/this-expression-source-directory.rkt rename to collects/mzlib/private/this-expression-source-directory.rkt diff --git a/collects/racket/private/unit-compiletime.rkt b/collects/mzlib/private/unit-compiletime.rkt similarity index 100% rename from collects/racket/private/unit-compiletime.rkt rename to collects/mzlib/private/unit-compiletime.rkt diff --git a/collects/racket/private/unit-contract-syntax.rkt b/collects/mzlib/private/unit-contract-syntax.rkt similarity index 100% rename from collects/racket/private/unit-contract-syntax.rkt rename to collects/mzlib/private/unit-contract-syntax.rkt diff --git a/collects/racket/private/unit-contract.rkt b/collects/mzlib/private/unit-contract.rkt similarity index 100% rename from collects/racket/private/unit-contract.rkt rename to collects/mzlib/private/unit-contract.rkt diff --git a/collects/racket/private/unit-keywords.rkt b/collects/mzlib/private/unit-keywords.rkt similarity index 100% rename from collects/racket/private/unit-keywords.rkt rename to collects/mzlib/private/unit-keywords.rkt diff --git a/collects/racket/private/unit-runtime.rkt b/collects/mzlib/private/unit-runtime.rkt similarity index 100% rename from collects/racket/private/unit-runtime.rkt rename to collects/mzlib/private/unit-runtime.rkt diff --git a/collects/racket/private/unit-syntax.rkt b/collects/mzlib/private/unit-syntax.rkt similarity index 100% rename from collects/racket/private/unit-syntax.rkt rename to collects/mzlib/private/unit-syntax.rkt diff --git a/collects/racket/private/unit-utils.rkt b/collects/mzlib/private/unit-utils.rkt similarity index 100% rename from collects/racket/private/unit-utils.rkt rename to collects/mzlib/private/unit-utils.rkt diff --git a/collects/mzlib/process.rkt b/collects/mzlib/process.rkt index ed07ddc196..49f556232e 100644 --- a/collects/mzlib/process.rkt +++ b/collects/mzlib/process.rkt @@ -1,6 +1,207 @@ #lang racket/base +(provide process + process* + process/ports + process*/ports + system + system* + system/exit-code + system*/exit-code) -;; deprecated library, see `racket/system` +(require "private/streams.rkt") -(require racket/system) -(provide (all-from-out racket/system)) \ No newline at end of file +;; Helpers: ---------------------------------------- + +(define (shell-path/args who argstr) + (case (system-type) + [(unix macosx) (append '("/bin/sh" "-c") (list argstr))] + [(windows) (let ([cmd + (let ([d (find-system-path 'sys-dir)]) + (let ([cmd (build-path d "cmd.exe")]) + (if (file-exists? cmd) + cmd + (let ([cmd (build-path d "command.com")]) + (if (file-exists? cmd) + cmd + ;; One last try: up a dir + (build-path d 'up "command.com"))))))]) + (list cmd + 'exact + (format "~a /c \"~a\"" (path->string cmd) argstr)))] + [else (raise-mismatch-error + who + (format "~a: don't know what shell to use for platform: " who) + (system-type))])) + +(define (check-exe who exe) + (unless (path-string? exe) + (raise-argument-error who "path-string?" exe)) + exe) + +(define (path-or-ok-string? s) + ;; use `path-string?' t check for nul characters in a string, + ;; but allow the empty string (which is not an ok path), too: + (or (path-string? s) + (equal? "" s))) + +(define (string-no-nuls? s) + (and (string? s) (path-or-ok-string? s))) + +(define (bytes-no-nuls? s) + (and (bytes? s) + (not (regexp-match? #rx#"\0" s)))) + +(define (check-args who args) + (cond + [(null? args) (void)] + [(eq? (car args) 'exact) + (when (null? (cdr args)) + (raise-mismatch-error + who + "expected a single string argument after: " + (car args))) + (unless (and (>= 2 (length args)) + (string? (cadr args)) + (path-or-ok-string? (cadr args))) + (raise-mismatch-error who + "expected a single string argument after 'exact, given: " + (cadr args))) + (when (pair? (cddr args)) + (raise-mismatch-error + who + "expected a single string argument after 'exact, given additional argument: " + (caddr args)))] + [else + (for ([s (in-list args)]) + (unless (or (path-or-ok-string? s) + (bytes-no-nuls? s)) + (raise-argument-error + who + (string-append "(or/c path-string?\n" + " (and/c bytes? (lambda (bs) (not (memv 0 (bytes->list bs))))))") + s)))]) + args) + +(define (check-command who str) + (unless (or (string-no-nuls? str) + (bytes-no-nuls? str)) + (raise-argument-error + who + (string-append "(or/c (and/c string? (lambda (s) (not (memv #\\nul (string->list s)))))\n" + " (and/c bytes? (lambda (bs) (not (memv 0 (bytes->list bs))))))") + str))) + +;; Old-style functions: ---------------------------------------- + +(define (do-process*/ports who cout cin cerr exe . args) + (let-values ([(subp out in err) (apply subprocess + (if-stream-out who cout) + (if-stream-in who cin) + (if-stream-out who cerr #t) + (check-exe who exe) + (check-args who args))] + [(it-ready) (make-semaphore)]) + (let ([so (streamify-out cout out)] + [si (streamify-in cin in (lambda (ok?) + (if ok? + (semaphore-post it-ready) + (semaphore-wait it-ready))))] + [se (streamify-out cerr err)] + [aport (lambda (x) (and (port? x) x))]) + (when (thread? si) + ;; Wait for process to end, then stop copying input: + (thread (lambda () + (sync subp si) + (semaphore-wait it-ready) + (break-thread si)))) + (let ([threads-still-going? + (lambda () + (ormap (lambda (s) (and (thread? s) (thread-running? s))) + (list so si se)))]) + (define (control m) + (case m + [(status) + (let ([s (subprocess-status subp)]) + (cond [(or (not (integer? s)) (threads-still-going?)) + 'running] + [(zero? s) 'done-ok] + [else 'done-error]))] + [(exit-code) + (if (threads-still-going?) + #f + (let ([s (subprocess-status subp)]) (and (integer? s) s)))] + [(wait) + (subprocess-wait subp) + (let ([twait (lambda (t) (when (thread? t) (thread-wait t)))]) + (twait so) + (twait si) + (twait se))] + [(interrupt) (subprocess-kill subp #f)] + [(kill) (subprocess-kill subp #t)] + [else (raise-argument-error + 'control-process + "(or/c 'status 'exit-code 'wait 'interrupt 'kill)" m)])) + (list (aport so) + (aport si) + (subprocess-pid subp) + (aport se) + control))))) + +(define (process*/ports cout cin cerr exe . args) + (apply do-process*/ports 'process*/ports cout cin cerr exe args)) + +(define (process/ports out in err str) + (apply do-process*/ports 'process/ports out in err (shell-path/args 'process/ports str))) + +(define (process* exe . args) + (apply do-process*/ports 'process* #f #f #f exe args)) + +(define (process str) + (check-command 'process str) + (apply do-process*/ports 'process #f #f #f (shell-path/args 'process str))) + +;; Note: these always use current ports +(define (do-system*/exit-code who exe . args) + (let ([cout (current-output-port)] + [cin (current-input-port)] + [cerr (current-error-port)] + [it-ready (make-semaphore)]) + (let-values ([(subp out in err) + (apply subprocess + (if-stream-out who cout) + (if-stream-in who cin) + (if-stream-out who cerr #t) + (check-exe who exe) + (check-args who args))]) + (let ([ot (streamify-out cout out)] + [it (streamify-in cin in (lambda (ok?) + (if ok? + (semaphore-post it-ready) + (semaphore-wait it-ready))))] + [et (streamify-out cerr err)]) + (subprocess-wait subp) + (when it + ;; stop piping output to subprocess + (semaphore-wait it-ready) + (break-thread it)) + ;; wait for other pipes to run dry: + (when (thread? ot) (thread-wait ot)) + (when (thread? et) (thread-wait et)) + (when err (close-input-port err)) + (when out (close-input-port out)) + (when in (close-output-port in))) + (subprocess-status subp)))) + +(define (system*/exit-code exe . args) + (apply do-system*/exit-code 'system*/exit-code exe args)) + +(define (system* exe . args) + (zero? (apply do-system*/exit-code 'system* exe args))) + +(define (system str) + (check-command 'system str) + (zero? (apply do-system*/exit-code 'system (shell-path/args 'system str)))) + +(define (system/exit-code str) + (check-command 'system/exit-code str) + (apply do-system*/exit-code 'system/exit-code (shell-path/args 'system/exit-code str))) diff --git a/collects/mzlib/runtime-path.rkt b/collects/mzlib/runtime-path.rkt index dc070f5e18..735b46c4f4 100644 --- a/collects/mzlib/runtime-path.rkt +++ b/collects/mzlib/runtime-path.rkt @@ -1,10 +1,172 @@ -#lang racket/base +(module runtime-path racket/base + (require "private/this-expression-source-directory.rkt" + racket/list + setup/dirs + (only-in "private/runtime-path-table.rkt" table) + (for-syntax racket/base)) -;; deprecated library, see `racket/runtime-path` + (provide define-runtime-path + define-runtime-paths + define-runtime-path-list + define-runtime-module-path-index + runtime-paths) + + (define-for-syntax ext-file-table (make-hasheq)) -(require racket/runtime-path) -(provide define-runtime-path - define-runtime-paths - define-runtime-path-list - define-runtime-module-path-index - runtime-paths) + (define (lookup-in-table var-ref p) + ;; This function is designed to cooperate with a table embedded + ;; in an executable by create-embedding-executable. + (let ([modname (variable-reference->resolved-module-path var-ref)]) + (let ([p (hash-ref + table + (cons (resolved-module-path-name modname) + (if (path? p) + (path->bytes p) + (if (and (pair? p) (eq? 'module (car p))) + (list 'module (cadr p)) + p))) + #f)]) + (and p + (car p) + (let* ([p (car p)] + [p (if (bytes? p) + (bytes->path p) + p)]) + (if (symbol? p) + (module-path-index-join (list 'quote p) #f) ; make it a module path index + (if (absolute-path? p) + p + (parameterize ([current-directory (find-system-path 'orig-dir)]) + (or (find-executable-path (find-system-path 'exec-file) p #t) + (build-path (current-directory) p)))))))))) + + (define (resolve-paths tag-stx get-base paths) + (let ([base #f]) + (map (lambda (p) + (or + ;; Check table potentially substituted by + ;; mzc --exe: + (and table + (lookup-in-table tag-stx p)) + ;; Normal resolution + (cond + [(and (or (string? p) (path? p)) + (not (complete-path? p))) + (unless base + (set! base (get-base))) + (path->complete-path p base)] + [(string? p) (string->path p)] + [(path? p) p] + [(and (list? p) + (= 2 (length p)) + (eq? 'so (car p)) + (string? (cadr p))) + (let ([f (path-replace-suffix (cadr p) (system-type 'so-suffix))]) + (or (ormap (lambda (p) + (let ([p (build-path p f)]) + (and (file-exists? p) + p))) + (get-lib-search-dirs)) + (cadr p)))] + [(and (list? p) + ((length p) . > . 1) + (eq? 'lib (car p)) + (andmap string? (cdr p))) + (let* ([strs (regexp-split #rx"/" + (let ([s (cadr p)]) + (if (regexp-match? #rx"[./]" s) + s + (string-append s "/main.rkt"))))]) + (apply collection-file-path + (last strs) + (if (and (null? (cddr p)) + (null? (cdr strs))) + (list "mzlib") + (append (cddr p) (drop-right strs 1)))))] + [(and (list? p) + ((length p) . = . 3) + (eq? 'module (car p)) + (or (not (caddr p)) + (variable-reference? (caddr p)))) + (let ([p (cadr p)] + [vr (caddr p)]) + (unless (module-path? p) + (error 'runtime-path "not a module path: ~.s" p)) + (let ([base (and vr + (variable-reference->resolved-module-path vr))]) + (if (and (pair? p) + (eq? (car p) 'submod) + (path? (cadr p))) + (module-path-index-join `(submod "." ,@(cddr p)) + (module-path-index-join (cadr p) base)) + (module-path-index-join p base))))] + [else (error 'runtime-path "unknown form: ~.s" p)]))) + paths))) + + (define-for-syntax (register-ext-files var-ref paths) + (let ([modname (variable-reference->resolved-module-path var-ref)]) + (let ([files (hash-ref ext-file-table modname null)]) + (hash-set! ext-file-table modname (append paths files))))) + + (define-syntax (-define-runtime-path stx) + (syntax-case stx () + [(_ orig-stx (id ...) expr to-list to-values) + (let ([ids (syntax->list #'(id ...))]) + (unless (memq (syntax-local-context) '(module module-begin top-level)) + (raise-syntax-error #f "allowed only at the top level" #'orig-stx)) + (for-each (lambda (id) + (unless (identifier? id) + (raise-syntax-error + #f + #'orig-stx + id))) + ids) + #`(begin + (define-values (id ...) + (let-values ([(id ...) expr]) + (let ([get-dir (lambda () + #,(datum->syntax + #'orig-stx + `(,#'this-expression-source-directory) + #'orig-stx))]) + (apply to-values (resolve-paths (#%variable-reference) + get-dir + (to-list id ...)))))) + (begin-for-syntax + (register-ext-files + (#%variable-reference) + (let-values ([(id ...) expr]) + (to-list id ...))))))])) + + (define-syntax (define-runtime-path stx) + (syntax-case stx () + [(_ id expr) #`(-define-runtime-path #,stx (id) expr list values)])) + + (define-syntax (define-runtime-paths stx) + (syntax-case stx () + [(_ (id ...) expr) #`(-define-runtime-path #,stx (id ...) expr list values)])) + + (define-syntax (define-runtime-path-list stx) + (syntax-case stx () + [(_ id expr) #`(-define-runtime-path #,stx (id) expr values list)])) + + (define-syntax (define-runtime-module-path-index stx) + (syntax-case stx () + [(_ id expr) #`(-define-runtime-path #,stx (id) `(module ,expr ,(#%variable-reference)) list values)])) + + (define-syntax (runtime-paths stx) + (syntax-case stx () + [(_ mp) + #`(quote + #,(hash-ref + ext-file-table + (module-path-index-resolve + (let ([p (syntax->datum #'mp)] + [base (syntax-source-module stx)]) + (if (and (pair? p) (eq? (car p) 'submod) (path? (cadr p))) + (module-path-index-join `(submod "." ,@(cddr p)) + (module-path-index-join (cadr p) base)) + (module-path-index-join p base)))) + null))])) + + ) diff --git a/collects/mzlib/shared.rkt b/collects/mzlib/shared.rkt index 04ffee5e80..f6af9d4aae 100644 --- a/collects/mzlib/shared.rkt +++ b/collects/mzlib/shared.rkt @@ -1,6 +1,21 @@ #lang racket/base +(require (for-syntax racket/base + syntax/kerncase + syntax/struct + racket/struct-info + racket/include)) -;; deprecated library, see `racket/shared` - -(require racket/shared) (provide shared) + +(define-for-syntax code-insp (variable-reference->module-declaration-inspector + (#%variable-reference))) + +(define undefined (letrec ([x x]) x)) +(require (only-in racket/base [cons the-cons])) + +(define-syntax shared + (lambda (stx) + (define make-check-cdr #f) + ;; Include the implementation. + ;; See private/shared-body.rkt. + (include "private/shared-body.rkt"))) diff --git a/collects/mzlib/unit-exptime.rkt b/collects/mzlib/unit-exptime.rkt index 088d79bf99..df22354598 100644 --- a/collects/mzlib/unit-exptime.rkt +++ b/collects/mzlib/unit-exptime.rkt @@ -1,6 +1,27 @@ #lang racket/base -;; deprecated library, see `racket/unit-exptime` +(require "private/unit-syntax.rkt" + "private/unit-compiletime.rkt") -(require racket/unit-exptime) -(provide (all-from-out racket/unit-exptime)) +(provide unit-static-signatures + signature-members) + +(define (unit-static-signatures name err-stx) + (parameterize ((error-syntax err-stx)) + (let ((ui (lookup-def-unit name))) + (values (apply list (unit-info-import-sig-ids ui)) + (apply list (unit-info-export-sig-ids ui)))))) + +(define (signature-members name err-stx) + (parameterize ((error-syntax err-stx)) + (let ([s (lookup-signature name)]) + (values + ;; extends: + (and (pair? (cdr (siginfo-names (signature-siginfo s)))) + (cadr (siginfo-names (signature-siginfo s)))) + ;; vars + (apply list (signature-vars s)) + ;; defined vars + (apply list (apply append (map car (signature-val-defs s)))) + ;; defined stxs + (apply list (apply append (map car (signature-stx-defs s)))))))) diff --git a/collects/mzlib/unit.rkt b/collects/mzlib/unit.rkt index e5efa5b8e1..7561aa30d1 100644 --- a/collects/mzlib/unit.rkt +++ b/collects/mzlib/unit.rkt @@ -1,8 +1,2324 @@ #lang racket/base -;; deprecated library, see `racket/unit` +(require (for-syntax racket/base + syntax/boundmap + syntax/context + syntax/kerncase + syntax/name + syntax/parse + syntax/struct + racket/struct-info + syntax/stx + syntax/location + "private/unit-contract-syntax.rkt" + "private/unit-compiletime.rkt" + "private/unit-syntax.rkt")) -(require racket/unit - (submod racket/unit compat)) -(provide (except-out (all-from-out racket/unit) struct/ctc) - (all-from-out (submod racket/unit compat))) +(require racket/block + racket/contract/base + racket/contract/region + racket/stxparam + syntax/location + "private/unit-contract.rkt" + "private/unit-keywords.rkt" + "private/unit-runtime.rkt" + "private/unit-utils.rkt" + (rename-in racket/private/struct [struct struct~])) + +(provide define-signature-form struct struct/ctc open + define-signature provide-signature-elements + only except rename import export prefix link tag init-depend extends contracted + define-values-for-export + unit? + (rename-out [:unit unit]) define-unit + compound-unit define-compound-unit compound-unit/infer define-compound-unit/infer + invoke-unit define-values/invoke-unit + invoke-unit/infer define-values/invoke-unit/infer + unit-from-context define-unit-from-context + define-unit-binding + unit/new-import-export define-unit/new-import-export + unit/s define-unit/s + unit/c define-unit/contract + struct~s struct~s/ctc + struct~r struct~r/ctc) + +(define-syntax/err-param (define-signature-form stx) + (syntax-case stx () + ((_ (name arg) . val) + (begin + (check-id #'name) + (check-id #'arg) + #'(define-syntax name + (make-set!-transformer + (make-signature-form (λ (arg) . val)))))) + ((_ . l) + (let ((l (checked-syntax->list stx))) + (unless (>= 3 (length l)) + (raise-stx-err + (format "expected syntax matching (~a (id id) expr ...)" + (syntax-e (stx-car stx))))) + (unless (= 2 (length (checked-syntax->list (car l)))) + (raise-stx-err + "expected syntax matching (identifier identifier)" + (car l))))))) + +(define-signature-form (struct stx) + (parameterize ((error-syntax stx)) + (syntax-case stx () + ((_ name (field ...) . omissions) + (let ([omit-selectors #f] + [omit-setters #f] + [omit-constructor #f] + [omit-type #f]) + (define (remove-ctor&type-name l) + (cond + ((and omit-constructor omit-type) + (cddr l)) + (omit-type + (cdr l)) + (omit-constructor + (cons (car l) (cddr l))) + (else + l))) + (define (remove-ctor&type-info l) + (define new-type + (if omit-type + #f + (cadr l))) + (define new-ctor + (if omit-constructor + #f + (caddr l))) + (cons (car l) + (cons new-type + (cons new-ctor + (cdddr l))))) + (check-id #'name) + (for-each check-id (syntax->list #'(field ...))) + (for-each + (lambda (omission) + (cond + ((and (identifier? omission) + (free-identifier=? omission #'-selectors)) + (set! omit-selectors #t)) + ((and (identifier? omission) + (free-identifier=? omission #'-setters)) + (set! omit-setters #t)) + ((and (identifier? omission) + (free-identifier=? omission #'-constructor)) + (set! omit-constructor #t)) + ((and (identifier? omission) + (free-identifier=? omission #'-type)) + (set! omit-type #t)) + (else + (raise-stx-err + "expected \"-selectors\" or \"-setters\" or \"-constructor\" or \"-type\"" + omission)))) + (checked-syntax->list #'omissions)) + (cons + #`(define-syntaxes (name) + #,(remove-ctor&type-info + (build-struct-expand-info + #'name (syntax->list #'(field ...)) + omit-selectors omit-setters + #f '(#f) '(#f)))) + (remove-ctor&type-name + (build-struct-names #'name (syntax->list #'(field ...)) + omit-selectors omit-setters #f))))) + ((_ name (x . y) . omissions) + ;; Will fail + (checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))) + ((_ name fields . omissions) + (raise-stx-err "expected syntax matching (identifier ...)" #'fields)) + ((_ name) + (raise-stx-err "missing fields")) + ((_) + (raise-stx-err "missing name and fields"))))) + +(begin-for-syntax + (define-struct self-name-struct-info (id) + #:super struct:struct-info + #:property prop:procedure (lambda (me stx) + (syntax-case stx () + [(_ arg ...) (datum->syntax + stx + (cons ((self-name-struct-info-id me)) + #'(arg ...)) + stx + stx)] + [_ (let ([id ((self-name-struct-info-id me))]) + (datum->syntax id + (syntax-e id) + stx + stx))])) + #:omit-define-syntaxes)) + +(define-for-syntax option-keywords + "#:mutable, #:constructor-name, #:extra-constructor-name, #:omit-constructor, #:omit-define-syntaxes, or #:omit-define-values") + +;; Replacement `struct' signature form for `scheme/unit': +(define-for-syntax (do-struct~ stx extra-make?) + (syntax-case stx () + ((_ name (field ...) opt ...) + (begin + (unless (identifier? #'name) + (raise-syntax-error #f + "expected an identifier to name the structure type" + stx + #'name)) + (for-each (lambda (field) + (unless (identifier? field) + (syntax-case field () + [(id #:mutable) + (identifier? #'id) + 'ok] + [_ + (raise-syntax-error #f + "bad field specification" + stx + field)]))) + (syntax->list #'(field ...))) + (let*-values ([(no-ctr? mutable? no-stx? no-rt? opt-cname) + (let loop ([opts (syntax->list #'(opt ...))] + [no-ctr? #f] + [mutable? #f] + [no-stx? #f] + [no-rt? #f] + [cname #f]) + (if (null? opts) + (values no-ctr? mutable? no-stx? no-rt? cname) + (let ([opt (car opts)]) + (case (syntax-e opt) + [(#:constructor-name #:extra-constructor-name) + (if cname + (raise-syntax-error #f + "redundant option" + stx + opt) + (if (null? (cdr opts)) + (raise-syntax-error #f + "missing identifier after option" + stx + opt) + (if (identifier? (cadr opts)) + (loop (cddr opts) #f mutable? no-stx? no-rt? + (if (eq? (syntax-e opt) '#:extra-constructor-name) + (list (cadr opts)) + (cadr opts))) + (raise-syntax-error #f + "not an identifier for a constructor name" + stx + (cadr opts)))))] + [(#:omit-constructor) + (if no-ctr? + (raise-syntax-error #f + "redundant option" + stx + opt) + (loop (cdr opts) #t mutable? no-stx? no-rt? cname))] + [(#:mutable) + (if mutable? + (raise-syntax-error #f + "redundant option" + stx + opt) + (loop (cdr opts) no-ctr? #t no-stx? no-rt? cname))] + [(#:omit-define-syntaxes) + (if no-stx? + (raise-syntax-error #f + "redundant option" + stx + opt) + (loop (cdr opts) no-ctr? mutable? #t no-rt? cname))] + [(#:omit-define-values) + (if no-rt? + (raise-syntax-error #f + "redundant option" + stx + opt) + (loop (cdr opts) no-ctr? mutable? no-stx? #t cname))] + [else + (raise-syntax-error #f + (string-append + "expected a keyword to specify option: " + option-keywords) + stx + opt)]))))] + [(def-cname) (cond + [opt-cname (if (pair? opt-cname) + (car opt-cname) + opt-cname)] + [extra-make? #f] + [else (car (generate-temporaries #'(name)))])] + [(cname) (cond + [opt-cname (if (pair? opt-cname) + (cons def-cname #'name) + (cons opt-cname opt-cname))] + [extra-make? #f] + [else (cons def-cname #'name)])] + [(self-ctr?) (and cname (bound-identifier=? #'name (cdr cname)))]) + (cons + #`(define-syntaxes (name) + #,(let ([e (build-struct-expand-info + #'name (syntax->list #'(field ...)) + #f (not mutable?) + #f '(#f) '(#f) + #:omit-constructor? no-ctr? + #:constructor-name def-cname)]) + (if self-ctr? + #`(make-self-name-struct-info + (lambda () #,e) + (lambda () (quote-syntax #,def-cname))) + e))) + (let ([names (build-struct-names #'name (syntax->list #'(field ...)) + #f (not mutable?) + #:constructor-name def-cname)]) + (cond + [no-ctr? (cons (car names) (cddr names))] + [self-ctr? (cons #`(define-values-for-export (#,def-cname) name) + names)] + [else names])))))) + ((_ name fields opt ...) + (raise-syntax-error #f + "bad syntax; expected a parenthesized sequence of fields" + stx + #'fields)) + ((_ name) + (raise-syntax-error #f + "bad syntax; missing fields" + stx)) + ((_) + (raise-syntax-error #f + "missing name and fields" + stx)))) + +(define-signature-form (struct~s stx) + (do-struct~ stx #t)) +(define-signature-form (struct~r stx) + (do-struct~ stx #f)) + +(define-signature-form (struct/ctc stx) + (parameterize ((error-syntax stx)) + (syntax-case stx () + ((_ name ([field ctc] ...) . omissions) + (let ([omit-selectors #f] + [omit-setters #f] + [omit-constructor #f] + [omit-type #f]) + (define (remove-ctor&type-info l) + (define new-type + (if omit-type + #f + (cadr l))) + (define new-ctor + (if omit-constructor + #f + (caddr l))) + (cons (car l) + (cons new-type + (cons new-ctor + (cdddr l))))) + (define (add-contracts l) + (let* ([pred (caddr l)] + [ctor-ctc #`(-> ctc ... #,pred)] + [pred-ctc #`(-> any/c boolean?)] + [field-ctcs (apply append + (map (λ (c) + (append (if omit-selectors + null + (list #`(-> #,pred #,c))) + (if omit-setters + null + (list #`(-> #,pred #,c void?))))) + (syntax->list #'(ctc ...))))]) + (list* (car l) + (list (cadr l) ctor-ctc) + (list pred pred-ctc) + (map list (cdddr l) field-ctcs)))) + (check-id #'name) + (for-each check-id (syntax->list #'(field ...))) + (for-each + (lambda (omission) + (cond + ((and (identifier? omission) + (free-identifier=? omission #'-selectors)) + (set! omit-selectors #t)) + ((and (identifier? omission) + (free-identifier=? omission #'-setters)) + (set! omit-setters #t)) + ((and (identifier? omission) + (free-identifier=? omission #'-constructor)) + (set! omit-constructor #t)) + ((and (identifier? omission) + (free-identifier=? omission #'-type)) + (set! omit-type #t)) + (else + (raise-stx-err + "expected \"-selectors\" or \"-setters\" or \"-constructor\" or \"-type\"" + omission)))) + (checked-syntax->list #'omissions)) + (cons + #`(define-syntaxes (name) + #,(remove-ctor&type-info + (build-struct-expand-info + #'name (syntax->list #'(field ...)) + omit-selectors omit-setters + #f '(#f) '(#f)))) + (let* ([res (add-contracts + (build-struct-names #'name (syntax->list #'(field ...)) + omit-selectors omit-setters #f))] + [cpairs (cons 'contracted (if omit-constructor (cddr res) (cdr res)))]) + (if omit-type + (list cpairs) + (list (car res) cpairs)))))) + ((_ name (x . y) . omissions) + ;; Will fail + (checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))) + ((_ name fields . omissions) + (raise-stx-err "expected syntax matching (identifier ...)" #'fields)) + ((_ name) + (raise-stx-err "missing fields")) + ((_) + (raise-stx-err "missing name and fields"))))) + +;; Replacement struct/ctc form for `scheme/unit': +(define-for-syntax (do-struct~/ctc stx extra-make?) + (syntax-case stx () + ((_ name ([field ctc] ...) opt ...) + (begin + (unless (identifier? #'name) + (raise-syntax-error #f + "expected an identifier to name the structure type" + stx + #'name)) + (for-each (lambda (field) + (unless (identifier? field) + (syntax-case field () + [(id #:mutable) + (identifier? #'id) + 'ok] + [_ + (raise-syntax-error #f + "bad field specification" + stx + field)]))) + (syntax->list #'(field ...))) + (let*-values ([(no-ctr? mutable? no-stx? no-rt? opt-cname) + (let loop ([opts (syntax->list #'(opt ...))] + [no-ctr? #f] + [mutable? #f] + [no-stx? #f] + [no-rt? #f] + [cname #f]) + (if (null? opts) + (values no-ctr? mutable? no-stx? no-rt? cname) + (let ([opt (car opts)]) + (case (syntax-e opt) + [(#:constructor-name #:extra-constructor-name) + (if cname + (raise-syntax-error #f + "redundant option" + stx + opt) + (if (null? (cdr opts)) + (raise-syntax-error #f + "missing identifier after option" + stx + opt) + (if (identifier? (cadr opts)) + (loop (cddr opts) #f mutable? no-stx? no-rt? + (if (eq? (syntax-e opt) '#:extra-constructor-name) + (list (cadr opts)) + (cadr opts))) + (raise-syntax-error #f + "not an identifier for a constructor name" + stx + (cadr opts)))))] + [(#:omit-constructor) + (if no-ctr? + (raise-syntax-error #f + "redundant option" + stx + opt) + (loop (cdr opts) #t mutable? no-stx? no-rt? cname))] + [(#:mutable) + (if mutable? + (raise-syntax-error #f + "redundant option" + stx + opt) + (loop (cdr opts) no-ctr? #t no-stx? no-rt? cname))] + [(#:omit-define-syntaxes) + (if no-stx? + (raise-syntax-error #f + "redundant option" + stx + opt) + (loop (cdr opts) no-ctr? mutable? #t no-rt? cname))] + [(#:omit-define-values) + (if no-rt? + (raise-syntax-error #f + "redundant option" + stx + opt) + (loop (cdr opts) no-ctr? mutable? no-stx? #t cname))] + [else + (raise-syntax-error #f + (string-append + "expected a keyword to specify option: " + option-keywords) + stx + opt)]))))] + [(def-cname) (cond + [opt-cname (if (pair? opt-cname) + (car opt-cname) + opt-cname)] + [extra-make? #f] + [else (car (generate-temporaries #'(name)))])] + [(cname) (cond + [opt-cname (if (pair? opt-cname) + (cons def-cname #'name) + (cons def-cname def-cname))] + [extra-make? #f] + [else (cons def-cname #'name)])] + [(self-ctr?) (and cname (bound-identifier=? #'name (cdr cname)))]) + (define (add-contracts l) + (let* ([pred (caddr l)] + [ctor-ctc #`(-> ctc ... #,pred)] + [pred-ctc #'(-> any/c boolean?)] + [field-ctcs + (apply append + (map (λ (f c) + (cons #`(-> #,pred #,c) + (if (and (not mutable?) + (not (pair? (syntax-e f)))) + null + #`(-> #,pred #,c void?)))) + (syntax->list #'(field ...)) + (syntax->list #'(ctc ...))))]) + (list* (car l) + (list (cadr l) ctor-ctc) + (list pred pred-ctc) + (map list (cdddr l) field-ctcs)))) + (cons + #`(define-syntaxes (name) + #,(let ([e (build-struct-expand-info + #'name (syntax->list #'(field ...)) + #f (not mutable?) + #f '(#f) '(#f) + #:omit-constructor? no-ctr? + #:constructor-name def-cname)]) + (if self-ctr? + #`(make-self-name-struct-info + (lambda () #,e) + (lambda () (quote-syntax #,def-cname))) + e))) + (let* ([names (add-contracts + (build-struct-names #'name (syntax->list #'(field ...)) + #f (not mutable?) + #:constructor-name def-cname))] + [cpairs (cons 'contracted + (cond + [no-ctr? (cddr names)] + [else (cdr names)]))] + [l (list (car names) cpairs)]) + (if self-ctr? + (cons #`(define-values-for-export (#,def-cname) name) l) + l)))))) + ((_ name fields opt ...) + (raise-syntax-error #f + "bad syntax; expected a parenthesized sequence of fields" + stx + #'fields)) + ((_ name) + (raise-syntax-error #f + "bad syntax; missing fields" + stx)) + ((_) + (raise-syntax-error #f + "missing name and fields" + stx)))) + +(define-signature-form (struct~s/ctc stx) + (do-struct~/ctc stx #t)) +(define-signature-form (struct~r/ctc stx) + (do-struct~/ctc stx #f)) + +;; build-val+macro-defs : sig -> (list syntax-object^3) +(define-for-syntax (build-val+macro-defs sig) + (if (and (null? (cadr sig)) + (null? (caddr sig))) + ;; No renames needed; this shortcut avoids + ;; an explosion of renamings, especially with chains + ;; of `open': + (list #'(() (values)) #'() #'()) + ;; Renames and macros needes: + (with-syntax ([(((int-ivar . ext-ivar) ...) + ((((int-vid . ext-vid) ...) . vbody) ...) + ((((int-sid . ext-sid) ...) . sbody) ...) + _ + _) + (map-sig (lambda (x) x) + (make-syntax-introducer) + sig)]) + (list + #'((ext-ivar ... ext-vid ... ... ext-sid ... ...) + (make-rename-transformers + (quote-syntax + (int-ivar ... + int-vid ... ... + int-sid ... ...)))) + #'(((int-sid ...) sbody) ...) + #'(((int-vid ...) vbody) ...))))) + +;; build-post-val-defs : sig -> (list syntax-object) +(define-for-syntax (build-post-val-defs sig) + (with-syntax ([(((int-ivar . ext-ivar) ...) + ((((int-vid . ext-vid) ...) . _) ...) + ((((int-sid . ext-sid) ...) . _) ...) + _ + (((post-id ...) . post-rhs) ...)) + (map-sig (lambda (x) x) + (make-syntax-introducer) + sig)]) + (list + #'((ext-ivar ... ext-vid ... ... ext-sid ... ...) + (make-rename-transformers + (quote-syntax + (int-ivar ... + int-vid ... ... + int-sid ... ...)))) + #'(post-rhs ...)))) + +;; Using `make-rename-transformers' helps improve sharing in +;; a syntax-quoted list of identifiers, although it risks +;; losting certificates as the list is broken apart; since the +;; identifiers are bound at the same point that the rename +;; transformer is introduced, certificate loss should be ok. +(define-for-syntax (make-rename-transformers ids) + (apply values + (map + make-rename-transformer + (syntax->list ids)))) + +(define-signature-form (open stx) + (define (build-sig-elems sig) + (map (λ (p c) + (if c #`(contracted [#,(car p) #,c]) (car p))) + (car sig) + (cadddr sig))) + (parameterize ([error-syntax stx]) + (syntax-case stx () + ((_ export-spec) + (let ([sig (process-spec #'export-spec)]) + (with-syntax (((sig-elem ...) + (build-sig-elems sig)) + ((renames + (((mac-name ...) mac-body) ...) + (((val-name ...) val-body) ...)) + (build-val+macro-defs sig))) + (syntax->list + #'(sig-elem ... + (define-syntaxes . renames) + (define-syntaxes (mac-name ...) mac-body) ... + (define-values (val-name ...) val-body) ...))))) + (_ + (raise-stx-err (format "must match (~a export-spec)" + (syntax-e (stx-car stx)))))))) + +(define-signature-form (define-values-for-export stx) + (raise-syntax-error #f "internal error" stx)) + +(define-for-syntax (introduce-def d) + (cons (map syntax-local-introduce (car d)) + (syntax-local-introduce (cdr d)))) + +;; build-define-syntax : identifier (or/c identifier #f) syntax-object -> syntax-object +(define-for-syntax (build-define-signature sigid super-sigid sig-exprs) + (unless (or (stx-null? sig-exprs) (stx-pair? sig-exprs)) + (raise-stx-err "expected syntax matching (sig-expr ...)" sig-exprs)) + (let ([ses (checked-syntax->list sig-exprs)]) + (define-values (super-names super-ctimes super-rtimes super-bindings + super-val-defs super-stx-defs super-post-val-defs + super-ctcs) + (if super-sigid + (let* ([super-sig (lookup-signature super-sigid)] + [super-siginfo (signature-siginfo super-sig)]) + (values (siginfo-names super-siginfo) + (siginfo-ctime-ids super-siginfo) + (map syntax-local-introduce + (siginfo-rtime-ids super-siginfo)) + (map syntax-local-introduce (signature-vars super-sig)) + (map introduce-def (signature-val-defs super-sig)) + (map introduce-def (signature-stx-defs super-sig)) + (map introduce-def (signature-post-val-defs super-sig)) + (map (lambda (ctc) + (if ctc + (syntax-local-introduce ctc) + ctc)) + (signature-ctcs super-sig)))) + (values '() '() '() '() '() '() '() '()))) + (let loop ((sig-exprs ses) + (bindings null) + (val-defs null) + (stx-defs null) + (post-val-defs null) + (ctcs null)) + (cond + ((null? sig-exprs) + (let* ([all-bindings (append super-bindings (reverse bindings))] + [all-val-defs (append super-val-defs (reverse val-defs))] + [all-stx-defs (append super-stx-defs (reverse stx-defs))] + [all-post-val-defs (append super-post-val-defs (reverse post-val-defs))] + [all-ctcs (append super-ctcs (reverse ctcs))] + [dup + (check-duplicate-identifier + (append all-bindings + (apply append (map car all-val-defs)) + (apply append (map car all-stx-defs))))]) + (when dup + (raise-stx-err "duplicate identifier" dup)) + (with-syntax (((super-rtime ...) super-rtimes) + ((super-name ...) super-names) + ((var ...) all-bindings) + ((ctc ...) all-ctcs) + ((((vid ...) . vbody) ...) all-val-defs) + ((((sid ...) . sbody) ...) all-stx-defs) + ((((pvid ...) . pvbody) ...) all-post-val-defs)) + #`(begin + (define signature-tag (gensym)) + (define-syntax #,sigid + (make-set!-transformer + (make-signature + (make-siginfo (list #'#,sigid #'super-name ...) + (list (quote-syntax signature-tag) + #'super-rtime + ...)) + (list (quote-syntax var) ...) + (list (cons (list (quote-syntax vid) ...) + (quote-syntax vbody)) + ...) + (list (cons (list (quote-syntax sid) ...) + (quote-syntax sbody)) + ...) + (list (cons (list (quote-syntax pvid) ...) + (quote-syntax pvbody)) + ...) + (list #,@(map (lambda (c) + (if c + #`(quote-syntax #,c) + #'#f)) + all-ctcs)) + (quote-syntax #,sigid)))) + (define-values () + (begin + (λ (var ...) + (letrec-syntaxes+values + ([(sid ...) sbody] ...) ([(vid ...) vbody] ...) + ctc ... + (void))) + (values))))))) + (else + (syntax-case (car sig-exprs) (define-values define-syntaxes contracted) + (x + (identifier? #'x) + (loop (cdr sig-exprs) (cons #'x bindings) val-defs stx-defs post-val-defs (cons #f ctcs))) + ((x (y z) ...) + (and (identifier? #'x) + (free-identifier=? #'x #'contracted) + (andmap identifier? (syntax->list #'(y ...)))) + (loop (cdr sig-exprs) + (append (syntax->list #'(y ...)) bindings) + val-defs + stx-defs + post-val-defs + (append (syntax->list #'(z ...)) ctcs))) + ((x . z) + (and (identifier? #'x) + (free-identifier=? #'x #'contracted)) + (raise-syntax-error + 'define-signature + "expected a list of [id contract] pairs after the contracted keyword" + (car sig-exprs))) + ((x . y) + (and (identifier? #'x) + (or (free-identifier=? #'x #'define-values) + (free-identifier=? #'x #'define-syntaxes) + (free-identifier=? #'x #'define-values-for-export))) + (begin + (check-def-syntax (car sig-exprs)) + (syntax-case #'y () + (((name ...) body) + (begin + (for-each (lambda (id) (check-id id)) + (syntax->list #'(name ...))) + (let ((b #'body)) + (loop (cdr sig-exprs) + bindings + (if (free-identifier=? #'x #'define-values) + (cons (cons (syntax->list #'(name ...)) b) + val-defs) + val-defs) + (if (free-identifier=? #'x #'define-syntaxes) + (cons (cons (syntax->list #'(name ...)) b) + stx-defs) + stx-defs) + (if (free-identifier=? #'x #'define-values-for-export) + (cons (cons (syntax->list #'(name ...)) b) + post-val-defs) + post-val-defs) + ctcs))))))) + ((x . y) + (let ((trans + (set!-trans-extract + (syntax-local-value + ;; redirect struct~ to struct~r + (if (free-identifier=? #'x #'struct~) + #'struct~r + (syntax-local-introduce #'x)) + (lambda () + (raise-stx-err "unknown signature form" #'x)))))) + (unless (signature-form? trans) + (raise-stx-err "not a signature form" #'x)) + (let ((results ((signature-form-f trans) (car sig-exprs)))) + (unless (list? results) + (raise-stx-err + (format "expected list of results from signature form, got ~e" results) + (car sig-exprs))) + (loop (append results (cdr sig-exprs)) + bindings + val-defs + stx-defs + post-val-defs + ctcs)))) + (x (raise-stx-err + "expected either an identifier or signature form" + #'x)))))))) + + +(define-syntax/err-param (define-signature stx) + (syntax-case stx (extends) + ((_ sig-name sig-exprs) + (begin + (check-id #'sig-name) + (build-define-signature #'sig-name #f #'sig-exprs))) + ((_ sig-name extends super-name sig-exprs) + (begin + (check-id #'sig-name) + (check-id #'super-name) + (build-define-signature #'sig-name #'super-name #'sig-exprs))) + (_ + (begin + (checked-syntax->list stx) + (raise-stx-err + (format "expected syntax matching (~a identifier (sig-expr ...)) or (~a identifier extends identifier (sig-expr ...))" + (syntax-e (stx-car stx)) (syntax-e (stx-car stx)))))))) + +(define-for-syntax (signature->identifiers sigids) + (define provide-tagged-sigs (map process-tagged-import sigids)) + (define provide-sigs (map caddr provide-tagged-sigs)) + (map sig-int-names provide-sigs)) + +(define-syntax/err-param (provide-signature-elements stx) + (syntax-case stx () + ((_ . p) + (let* ((sigs (checked-syntax->list #'p)) + (nameses (signature->identifiers sigs)) + ;; Export only the names that would be visible to uses + ;; with the same lexical context as p. Otherwise, we + ;; can end up with collisions with renamings that are + ;; symbolically the same, such as those introduced by + ;; `open'. + (nameses (map (lambda (sig names) + (filter (lambda (name) + (bound-identifier=? + name + (datum->syntax sig (syntax-e name)))) + names)) + sigs nameses)) + (names (apply append nameses)) + (dup (check-duplicate-identifier names))) + (when dup + (raise-stx-err (format "duplicate binding for ~.s" (syntax-e dup)))) + (quasisyntax/loc stx + (provide #,@names)))))) + +;; A unit is +;; - (unit (import import-spec ...) (export export-spec ...) unit-body-expr ...) + +(define-for-syntax (localify exp def-ctx) + (cadr (syntax->list + (local-expand #`(stop #,exp) + 'expression + (list #'stop) + def-ctx)))) + +(define-for-syntax (tagged-sigid->tagged-siginfo x) + (cons (car x) + (signature-siginfo (lookup-signature (cdr x))))) + +(define-for-syntax (make-import-unboxing var renamings loc ctc) + (if ctc + (with-syntax ([ctc-stx (syntax-property ctc 'inferred-name var)]) + (quasisyntax/loc (error-syntax) + (quote-syntax (let ([v/c (#,loc)]) + (if (pair? v/c) + (contract (let-syntax #,renamings ctc-stx) (car v/c) (cdr v/c) + (current-contract-region) + (quote #,var) (quote-srcloc #,var)) + (error 'unit "contracted import ~a used before definition" + (quote #,(syntax->datum var)))))))) + (quasisyntax/loc (error-syntax) + (quote-syntax (#,loc))))) + +;; build-unit : syntax-object -> +;; (values syntax-object (listof identifier) (listof identifier)) +;; constructs the code for a unit expression. stx must be +;; such that it passes check-unit-syntax. +;; The two additional values are the identifiers of the unit's import and export +;; signatures +(define-for-syntax (build-unit stx) + (syntax-case stx (import export init-depend) + (((import i ...) + (export e ...) + (init-depend id ...) + . body) + + (let* ([d (syntax->list #'(id ...))] + [dep-tagged-sigids (map check-tagged-id d)] + [dep-tagged-siginfos + (map tagged-sigid->tagged-siginfo dep-tagged-sigids)]) + + (define-values (isig tagged-import-sigs import-tagged-infos + import-tagged-sigids import-sigs) + (process-unit-import #'(i ...))) + + (define-values (esig tagged-export-sigs export-tagged-infos + export-tagged-sigids export-sigs) + (process-unit-export #'(e ...))) + + (check-duplicate-sigs import-tagged-infos isig dep-tagged-siginfos d) + + (check-duplicate-subs export-tagged-infos esig) + + (check-unit-ie-sigs import-sigs export-sigs) + + (with-syntax ((((dept . depr) ...) + (map + (lambda (tinfo) + (cons (car tinfo) + (syntax-local-introduce (car (siginfo-rtime-ids (cdr tinfo)))))) + dep-tagged-siginfos)) + [((renames (mac ...) (val ...)) ...) + (map build-val+macro-defs import-sigs)] + [(((int-ivar . ext-ivar) ...) ...) (map car import-sigs)] + [(((int-evar . ext-evar) ...) ...) (map car export-sigs)] + [((((e-post-id ...) . _) ...) ...) (map (lambda (s) (list-ref s 4)) export-sigs)] + [((post-renames (e-post-rhs ...)) ...) (map build-post-val-defs export-sigs)] + [((iloc ...) ...) + (map (lambda (x) (generate-temporaries (car x))) import-sigs)] + [((eloc ...) ...) + (map (lambda (x) (generate-temporaries (car x))) export-sigs)] + [((ectc ...) ...) + (map (λ (sig) + (map (λ (ctc) + (if ctc + (cons 'contract ctc) + #f)) + (cadddr sig))) export-sigs)] + [((import-key import-super-keys ...) ...) + (map tagged-info->keys import-tagged-infos)] + [((export-key ...) ...) + (map tagged-info->keys export-tagged-infos)] + [(import-name ...) + (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) + import-tagged-infos)] + [(export-name ...) + (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) + export-tagged-infos)] + [name (syntax-local-infer-name (error-syntax))] + [(icount ...) (map + (lambda (import) (length (car import))) + import-sigs)]) + (values + (quasisyntax/loc (error-syntax) + (make-unit + 'name + (vector-immutable (cons 'import-name + (vector-immutable import-key import-super-keys ...)) ...) + (vector-immutable (cons 'export-name + (vector-immutable export-key ...)) ...) + (list (cons 'dept depr) ...) + (syntax-parameterize ([current-contract-region (lambda (stx) #'(quote (unit name)))]) + (lambda () + (let ([eloc (box undefined)] ... ...) + (values + (lambda (import-table) + (let-values ([(iloc ...) + (vector->values (hash-ref import-table import-key) 0 icount)] + ...) + (letrec-syntaxes (#,@(map (lambda (ivs e-ivs ils ics) + (with-syntax ([renamings + (map (λ (ev iv) + #`(#,ev + (make-rename-transformer + (quote-syntax #,iv)))) + (syntax->list e-ivs) + (syntax->list ivs))]) + (quasisyntax/loc (error-syntax) + [#,ivs + (make-id-mappers + #,@(map (lambda (iv l c) + (make-import-unboxing iv #'renamings l c)) + (syntax->list ivs) + (syntax->list ils) + ics))]))) + (syntax->list #'((int-ivar ...) ...)) + (syntax->list #'((ext-ivar ...) ...)) + (syntax->list #'((iloc ...) ...)) + (map cadddr import-sigs))) + (letrec-syntaxes+values (renames ... + mac ... ...) + (val ... ...) + (unit-body #,(error-syntax) + (int-ivar ... ...) + (int-evar ... ...) + (eloc ... ...) + (ectc ... ...) + (begin . body) + (define-values (e-post-id ...) + (letrec-syntaxes+values (post-renames ...) () + e-post-rhs)) ... ...))))) + (unit-export ((export-key ...) (vector-immutable (λ () (unbox eloc)) ...)) ...))))))) + import-tagged-sigids + export-tagged-sigids + dep-tagged-sigids)))))) + +(define-syntax/err-param (:unit stx) + (syntax-case stx () + ((_ . x) + (begin + (let-values (((u x y z) (build-unit (check-unit-syntax #'x)))) + u))))) + +(define-syntax (unit-body stx) + (syntax-case stx () + ((_ err-stx ivars evars elocs ectcs body ...) + (parameterize ((error-syntax #'err-stx)) + (let* ([expand-context (generate-expand-context)] + [def-ctx (syntax-local-make-definition-context)] + [stop-list + (append + (kernel-form-identifier-list) + (syntax->list #'ivars))] + [definition? + (lambda (id) + (and (identifier? id) + (or (free-identifier=? id (quote-syntax define-values)) + (free-identifier=? id (quote-syntax define-syntaxes)))))] + [expanded-body + (let expand-all ((defns&exprs (syntax->list #'(body ...)))) + ;; Also lifted from Matthew, to expand the body enough + (apply + append + (map + (lambda (defn-or-expr) + (let ([defn-or-expr + (local-expand + defn-or-expr + expand-context + stop-list + def-ctx)]) + (syntax-case defn-or-expr (begin define-values define-syntaxes) + [(begin . l) + (let ([l (parameterize ((error-syntax defn-or-expr)) + (checked-syntax->list #'l))]) + (expand-all (map (lambda (s) + (syntax-track-origin s defn-or-expr #'begin)) + l)))] + [(define-syntaxes (id ...) rhs) + (andmap identifier? (syntax->list #'(id ...))) + (with-syntax ([rhs (local-transformer-expand + #'rhs + 'expression + null)]) + (syntax-local-bind-syntaxes (syntax->list #'(id ...)) #'rhs def-ctx) + (list #'(define-syntaxes (id ...) rhs)))] + [(define-values (id ...) rhs) + (andmap identifier? (syntax->list #'(id ...))) + (begin + (syntax-local-bind-syntaxes (syntax->list #'(id ...)) #f def-ctx) + (list defn-or-expr))] + [else (list defn-or-expr)]))) + defns&exprs)))] + ;; Get all the defined names, sorting out variable definitions + ;; from syntax definitions. + [defined-names-table + (let ((table (make-bound-identifier-mapping))) + (for-each + (lambda (defn-or-expr) + (syntax-case defn-or-expr () + ((dv . rest) + (definition? #'dv) + (begin + (check-def-syntax defn-or-expr) + (syntax-case #'rest () + [((id ...) expr) + (for-each + (lambda (id) + (when (bound-identifier-mapping-get table id (lambda () #f)) + (raise-stx-err "variable defined twice" id)) + (bound-identifier-mapping-put! + table id + (make-var-info (free-identifier=? #'dv (quote-syntax define-syntaxes)) + #f + id + #f))) + (syntax->list #'(id ...)))] + [_ (void)]))) + [_ (void)])) + expanded-body) + table)]) + (internal-definition-context-seal def-ctx) + + ;; Mark exported names and + ;; check that all exported names are defined (as var): + (for-each + (lambda (name loc ctc) + (let ([v (bound-identifier-mapping-get defined-names-table + name + (lambda () #f))]) + (unless v + (raise-stx-err (format "undefined export ~a" (syntax-e name)))) + (when (var-info-syntax? v) + (raise-stx-err "cannot export syntax from a unit" name)) + (set-var-info-exported?! v loc) + (when (pair? (syntax-e ctc)) + (set-var-info-ctc! v (localify (cdr (syntax-e ctc)) def-ctx))))) + (syntax->list (localify #'evars def-ctx)) + (syntax->list #'elocs) + (syntax->list #'ectcs)) + + ;; Check that none of the imports are defined + (for-each + (lambda (i) + (let ((defid (bound-identifier-mapping-get defined-names-table + i + (lambda () #f)))) + (when defid + (raise-stx-err + "definition for imported identifier" + (var-info-id defid))))) + (syntax->list (localify #'ivars def-ctx))) + + (let ([marker (lambda (id) ((make-syntax-introducer) (datum->syntax #f (syntax-e id))))]) + (with-syntax ([(defn-or-expr ...) + (apply append + (map (λ (defn-or-expr) + (syntax-case defn-or-expr (define-values) + [(define-values (id ...) body) + (let* ([ids (syntax->list #'(id ...))] + [tmps (map marker ids)] + [do-one + (λ (id tmp) + (let ([var-info (bound-identifier-mapping-get + defined-names-table + id)]) + (cond + [(var-info-exported? var-info) + => + (λ (export-loc) + (let ([ctc (var-info-ctc var-info)]) + (list (if ctc + (quasisyntax/loc defn-or-expr + (begin + (contract #,ctc #,tmp + (current-contract-region) + 'cant-happen + (quote #,id) + (quote-srcloc #,id)) + (set-box! #,export-loc + (cons #,tmp (current-contract-region))))) + (quasisyntax/loc defn-or-expr + (set-box! #,export-loc #,tmp))) + (quasisyntax/loc defn-or-expr + (define-syntax #,id + (make-id-mapper (quote-syntax #,tmp)))))))] + [else (list (quasisyntax/loc defn-or-expr + (define-syntax #,id + (make-rename-transformer (quote-syntax #,tmp)))))])))]) + (cons (quasisyntax/loc defn-or-expr + (define-values #,tmps body)) + (apply append (map do-one ids tmps))))] + [else (list defn-or-expr)])) + expanded-body))]) + #'(block defn-or-expr ...)))))))) + +(define-for-syntax (redirect-imports/exports import?) + (lambda (table-stx + import-tagged-infos + import-sigs + target-import-tagged-infos + target-import-sigs) + (define def-table (make-bound-identifier-mapping)) + (define ctc-table (make-bound-identifier-mapping)) + (define sig-table (make-bound-identifier-mapping)) + (for-each + (lambda (tagged-info sig) + (define v + #`(hash-ref #,table-stx #,(car (tagged-info->keys tagged-info)))) + (for-each + (lambda (int/ext-name index ctc) + (bound-identifier-mapping-put! def-table + (car int/ext-name) + #`(vector-ref #,v #,index)) + (bound-identifier-mapping-put! ctc-table + (car int/ext-name) + ctc) + (bound-identifier-mapping-put! sig-table + (car int/ext-name) + sig)) + (car sig) + (iota (length (car sig))) + (cadddr sig))) + import-tagged-infos + import-sigs) + (with-syntax ((((eloc ...) ...) + (map + (lambda (target-sig) + (map + (lambda (target-int/ext-name target-ctc) + (let* ([var (car target-int/ext-name)] + [vref + (bound-identifier-mapping-get + def-table + var + (lambda () + (raise-stx-err + (format (if import? + "identifier ~a is not present in new imports" + "identifier ~a is not present in old exports") + (syntax-e (car target-int/ext-name))))))] + [ctc (bound-identifier-mapping-get ctc-table var)] + [rename-bindings (get-member-bindings def-table + (bound-identifier-mapping-get sig-table var) + #'(current-contract-region))]) + (with-syntax ([ctc-stx (if ctc (syntax-property + #`(letrec-syntax #,rename-bindings #,ctc) + 'inferred-name var) + ctc)]) + (if target-ctc + #`(λ () + (cons #,(if ctc + #`(let ([old-v/c (#,vref)]) + (contract ctc-stx (car old-v/c) + (cdr old-v/c) (current-contract-region) + (quote #,var) (quote-srcloc #,var))) + #`(#,vref)) + (current-contract-region))) + (if ctc + #`(λ () + (let ([old-v/c (#,vref)]) + (contract ctc-stx (car old-v/c) + (cdr old-v/c) (current-contract-region) + (quote #,var) (quote-srcloc #,var)))) + vref))))) + (car target-sig) + (cadddr target-sig))) + target-import-sigs)) + (((export-keys ...) ...) + (map tagged-info->keys target-import-tagged-infos))) + #`(unit-export ((export-keys ...) + (vector-immutable eloc ...)) ...)))) + +(define-for-syntax redirect-imports (redirect-imports/exports #t)) +(define-for-syntax redirect-exports (redirect-imports/exports #f)) + + +;; build-unit/new-import-export : syntax-object -> +;; (values syntax-object (listof identifier) (listof identifier)) +;; constructs the code for a unit expression that changes the import and export signatures +;; of another. stx must be such that it passes check-unit-syntax. +;; The two additional values are the identifiers of the unit's import and export +;; signatures +(define-for-syntax (build-unit/new-import-export stx) + (syntax-case stx (import export init-depend) + (((import i ...) + (export e ...) + (init-depend id ...) + . body) + + (let* ([d (syntax->list #'(id ...))] + [dep-tagged-sigids (map check-tagged-id d)] + [dep-tagged-siginfos + (map tagged-sigid->tagged-siginfo dep-tagged-sigids)]) + (define-values (isig tagged-import-sigs import-tagged-infos + import-tagged-sigids import-sigs) + (process-unit-import #'(i ...))) + + (define-values (esig tagged-export-sigs export-tagged-infos + export-tagged-sigids export-sigs) + (process-unit-export #'(e ...))) + + (check-duplicate-sigs import-tagged-infos isig dep-tagged-siginfos d) + + (check-duplicate-subs export-tagged-infos esig) + + (check-unit-ie-sigs import-sigs export-sigs) + + (syntax-case #'body () + ((b) (check-link-line-syntax #'b)) + (() (raise-stx-err "missing unit specification")) + (_ (raise-stx-err "expects a single unit specification"))) + + (with-syntax (((((orig-e ...) unit-exp orig-i ...)) #'body)) + (define-values (orig-isig orig-tagged-import-sigs orig-import-tagged-infos + orig-import-tagged-sigids orig-import-sigs) + (process-unit-export #'(orig-i ...))) + + (define-values (orig-esig orig-tagged-export-sigs orig-export-tagged-infos + orig-export-tagged-sigids orig-export-sigs) + (process-unit-import #'(orig-e ...))) + (with-syntax ((((dept . depr) ...) + (map + (lambda (tinfo) + (cons (car tinfo) + (syntax-local-introduce (car (siginfo-rtime-ids (cdr tinfo)))))) + dep-tagged-siginfos)) + [((import-key ...) ...) + (map tagged-info->keys import-tagged-infos)] + [((export-key ...) ...) + (map tagged-info->keys export-tagged-infos)] + [((orig-import-key ...) ...) + (map tagged-info->keys orig-import-tagged-infos)] + [((orig-export-key ...) ...) + (map tagged-info->keys orig-export-tagged-infos)] + [(import-name ...) + (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) + import-tagged-infos)] + [(export-name ...) + (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) + export-tagged-infos)] + [(orig-import-name ...) + (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) + orig-import-tagged-infos)] + [(orig-export-name ...) + (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) + orig-export-tagged-infos)] + [name (syntax-local-infer-name (error-syntax))] + [form (syntax-e (stx-car (error-syntax)))]) + (values + (quasisyntax/loc (error-syntax) + (let ([unit-tmp unit-exp]) + (check-unit unit-tmp 'form) + (check-sigs unit-tmp + (vector-immutable + (cons 'orig-import-name + (vector-immutable orig-import-key ...)) ...) + (vector-immutable + (cons 'orig-export-name + (vector-immutable orig-export-key ...)) ...) + 'form) + (make-unit + 'name + (vector-immutable (cons 'import-name + (vector-immutable import-key ...)) ...) + (vector-immutable (cons 'export-name + (vector-immutable export-key ...)) ...) + (list (cons 'dept depr) ...) + (syntax-parameterize ([current-contract-region (lambda (stx) #'(quote (unit name)))]) + (lambda () + (let-values ([(unit-fn export-table) ((unit-go unit-tmp))]) + (values (lambda (import-table) + (unit-fn #,(redirect-imports #'import-table + import-tagged-infos + import-sigs + orig-import-tagged-infos + orig-import-sigs))) + #,(redirect-exports #'export-table + orig-export-tagged-infos + orig-export-sigs + export-tagged-infos + export-sigs)))))))) + import-tagged-sigids + export-tagged-sigids + dep-tagged-sigids))))))) + + +(define-syntax/err-param (unit/new-import-export stx) + (syntax-case stx () + ((_ . x) + (begin + (let-values (((u x y z) (build-unit/new-import-export (check-unit-syntax #'x)))) + u))))) + +;; build-compound-unit : syntax-object -> +;; (values syntax-object (listof identifier) (listof identifier)) +;; constructs the code for a compound-unit expression. stx match the return of +;; check-compound-syntax +;; The two additional values are the identifiers of the compound-unit's import and export +;; signatures +(define-for-syntax (build-compound-unit stx) + (define-struct lnkid-record (access-code names ctime-ids rtime-ids source-idx sigid siginfo)) + (define (lnkid-rec->keys t rec) + (map (lambda (rid) (build-key t rid)) + (lnkid-record-rtime-ids rec))) + (syntax-case stx () + (((import ...) + (export-lnktag ...) + (((sub-out ...) sub-exp sub-in-lnktag ...) ...)) + (with-syntax ((((import-tag import-lnkid . import-sigid) ...) + (map check-tagged-:-clause (syntax->list #'(import ...)))) + (((export-tag . export-lnkid) ...) + (map check-tagged-id + (syntax->list #'(export-lnktag ...)))) + ((((sub-out-tag sub-out-lnkid . sub-out-sigid) ...) ...) + (map (lambda (e) (map check-tagged-:-clause (syntax->list e))) + (syntax->list #'((sub-out ...) ...)))) + ((((sub-in-tag . sub-in-lnkid) ...) ...) + (map (lambda (t) (map check-tagged-id (syntax->list t))) + (syntax->list #'((sub-in-lnktag ...) ...))))) + + (let ([dup (check-duplicate-identifier + (syntax->list #'(import-lnkid ... sub-out-lnkid ... ...)))]) + (when dup + (raise-stx-err "duplicate linking identifier definition" dup))) + + + (let ([bt (make-bound-identifier-mapping)]) + (for-each + (lambda (lnkid) + (bound-identifier-mapping-put! bt lnkid #t)) + (syntax->list #'(import-lnkid ...))) + (for-each + (lambda (lnkid) + (when (bound-identifier-mapping-get bt lnkid (lambda () #f)) + (raise-stx-err "cannot directly export an import" lnkid))) + (syntax->list #'(export-lnkid ...)))) + + + (let* ([idxs (iota (add1 (length (syntax->list #'(sub-exp ...)))))] + [sub-export-table-tmps (generate-temporaries #'(sub-exp ...))] + [link-map + (let ((bt (make-bound-identifier-mapping))) + (for-each + (lambda (tags lnkids sigids tableid i) + (for-each + (lambda (tag lnkid sigid) + (define siginfo (signature-siginfo (lookup-signature sigid))) + (define rtime-ids (map syntax-local-introduce + (siginfo-rtime-ids siginfo))) + (bound-identifier-mapping-put! + bt + lnkid + (make-lnkid-record + #`(hash-ref + #,tableid + #,(build-key (syntax-e tag) (car rtime-ids))) + (siginfo-names siginfo) + (siginfo-ctime-ids siginfo) + rtime-ids + i + sigid + siginfo))) + (syntax->list tags) + (syntax->list lnkids) + (syntax->list sigids))) + (syntax->list #'((import-tag ...) (sub-out-tag ...) ...)) + (syntax->list #'((import-lnkid ...) (sub-out-lnkid ...) ...)) + (syntax->list #'((import-sigid ...) (sub-out-sigid ...) ...)) + (cons #'import-table-id sub-export-table-tmps) + idxs) + (lambda (id) + (bound-identifier-mapping-get + bt + id + (lambda () + (raise-stx-err "unknown linking identifier" id)))))] + [link-deps + (map + (lambda (tags lnkids i) + (define ht (make-hash)) + (for-each + (lambda (t l) + (define et (syntax-e t)) + (define el (syntax-e l)) + (define rec (link-map l)) + (define forward-dep (>= (lnkid-record-source-idx rec) i)) + (define import-dep (= 0 (lnkid-record-source-idx rec))) + (for-each + (lambda (ctime-id rtime-id name) + (hash-set! ht + (build-key et ctime-id) + (list forward-dep import-dep et rtime-id name el))) + (lnkid-record-ctime-ids rec) + (lnkid-record-rtime-ids rec) + (lnkid-record-names rec))) + (syntax->list tags) + (syntax->list lnkids)) + (hash-map ht (lambda (x y) y))) + (syntax->list #'((sub-in-tag ...) ...)) + (syntax->list #'((sub-in-lnkid ...) ...)) + (cdr idxs))]) + + (check-duplicate-subs + (map (lambda (t lid) (cons (syntax-e t) + (lnkid-record-siginfo (link-map lid)))) + (syntax->list #'(export-tag ...)) + (syntax->list #'(export-lnkid ...))) + (syntax->list #'(export-lnktag ...))) + + (with-syntax (((sub-tmp ...) (generate-temporaries #'(sub-exp ...))) + ((sub-export-table-tmp ...) sub-export-table-tmps) + (name (syntax-local-infer-name (error-syntax))) + (((import-key ...) ...) + (map + (lambda (t l) + (lnkid-rec->keys (syntax-e t) (link-map l))) + (syntax->list #'(import-tag ...)) + (syntax->list #'(import-lnkid ...)))) + (((export-key ...) ...) + (map + (lambda (t l) + (lnkid-rec->keys (syntax-e t) (link-map l))) + (syntax->list #'(export-tag ...)) + (syntax->list #'(export-lnkid ...)))) + ((import-name ...) + (map (lambda (l) (car (lnkid-record-names (link-map l)))) + (syntax->list #'(import-lnkid ...)))) + ((export-name ...) + (map (lambda (l) (car (lnkid-record-names (link-map l)))) + (syntax->list #'(export-lnkid ...)))) + (((((sub-in-key sub-in-code) ...) ...) ...) + (map + (lambda (stxed-tags lnkids) + (define lnkid-recs (map link-map (syntax->list lnkids))) + (define tags (map syntax-e (syntax->list stxed-tags))) + (define tagged-siginfos + (map + (lambda (t l) (cons t (lnkid-record-siginfo l))) + tags + lnkid-recs)) + (check-duplicate-subs tagged-siginfos (syntax->list lnkids)) + (map + (lambda (t lr) + (with-syntax (((key ...) + (lnkid-rec->keys t lr))) + #`((key #,(lnkid-record-access-code lr)) ...))) + tags + lnkid-recs)) + (syntax->list #'((sub-in-tag ...) ...)) + (syntax->list #'((sub-in-lnkid ...) ...)))) + ((((sub-out-key ...) ...) ...) + (map + (lambda (lnkids tags) + (map + (lambda (l t) + (lnkid-rec->keys (syntax-e t) (link-map l))) + (syntax->list lnkids) + (syntax->list tags))) + (syntax->list #'((sub-out-lnkid ...) ...)) + (syntax->list #'((sub-out-tag ...) ...)))) + (((export-sigid . export-code) ...) + (map (lambda (lnkid) + (define s (link-map lnkid)) + (cons (lnkid-record-sigid s) + (lnkid-record-access-code s))) + (syntax->list #'(export-lnkid ...)))) + (form (syntax-e (stx-car (error-syntax)))) + ) + + (with-syntax (((check-sub-exp ...) + (map + (lambda (stx link-deps) + (with-syntax (((sub-exp + sub-tmp + ((sub-in-key ...) ...) + ((sub-out-key ...) ...) + sub-in-lnkid + sub-out-lnkid) + stx)) + (with-syntax (((sub-in-signame ...) + (map (lambda (l) (car (lnkid-record-names (link-map l)))) + (syntax->list #'sub-in-lnkid))) + ((sub-out-signame ...) + (map (lambda (l) (car (lnkid-record-names (link-map l)))) + (syntax->list #'sub-out-lnkid))) + (((fdep-tag fdep-rtime fsig-name flnk-name) ...) + (map cddr (filter car link-deps))) + (((rdep-tag rdep-rtime . _) ...) + (map cddr (filter cadr link-deps)))) + #`(begin + #,(syntax/loc #'sub-exp + (check-unit sub-tmp 'form)) + #,(syntax/loc #'sub-exp + (check-sigs sub-tmp + (vector-immutable + (cons 'sub-in-signame + (vector-immutable sub-in-key ...)) + ...) + (vector-immutable + (cons 'sub-out-signame + (vector-immutable sub-out-key ...)) + ...) + 'form)) + (let ([fht (equal-hash-table + ((cons 'fdep-tag fdep-rtime) + (cons 'fsig-name 'flnk-name)) + ...)] + [rht (equal-hash-table + ((cons 'rdep-tag rdep-rtime) + #t) + ...)]) + #,(syntax/loc #'sub-exp (check-deps fht sub-tmp 'form)) + (for-each + (lambda (dep) + (when (hash-ref rht dep #f) + (set! deps (cons dep deps)))) + (unit-deps sub-tmp))))))) + (syntax->list #'((sub-exp + sub-tmp + ((sub-in-key ...) ...) + ((sub-out-key ...) ...) + (sub-in-lnkid ...) + (sub-out-lnkid ...)) + ...)) + link-deps)) + (((sub-in-key-code-workaround ...) ...) + (map + (lambda (x) + (with-syntax ((((a ...) ...) x)) + #'(a ... ...))) + (syntax->list #'((((sub-in-key sub-in-code) ...) ...) ...)))) + ) + (values + (quasisyntax/loc (error-syntax) + (let ([deps '()] + [sub-tmp sub-exp] ...) + check-sub-exp ... + (make-unit + 'name + (vector-immutable + (cons 'import-name + (vector-immutable import-key ...)) + ...) + (vector-immutable + (cons 'export-name + (vector-immutable export-key ...)) + ...) + deps + (lambda () + (let-values ([(sub-tmp sub-export-table-tmp) ((unit-go sub-tmp))] + ...) + (values (lambda (import-table-id) + (void) + (sub-tmp (equal-hash-table sub-in-key-code-workaround ...)) + ...) + (unit-export ((export-key ...) export-code) ...))))))) + (map syntax-e (syntax->list #'((import-tag . import-sigid) ...))) + (map syntax-e (syntax->list #'((export-tag . export-sigid) ...))) + '())))))) + (((i ...) (e ...) (l ...)) + (for-each check-link-line-syntax (syntax->list #'(l ...)))))) + + +(define-syntax/err-param (compound-unit stx) + (let-values (((u x y z) + (build-compound-unit + (check-compound-syntax (syntax-case stx () ((_ . x) #'x)))))) + u)) + + +(define (invoke-unit/core unit) + (check-unit unit 'invoke-unit) + (check-no-imports unit 'invoke-unit) + (let-values ([(f exports) ((unit-go unit))]) + (f #f))) + +(define-syntax/err-param (define-values/invoke-unit/core stx) + (syntax-case stx () + ((_ unit-expr . unit-out) + (let* ((unit-out (checked-syntax->list #'unit-out)) + (tagged-out (map process-tagged-import unit-out)) + (out-tags (map car tagged-out)) + (out-sigs (map caddr tagged-out)) + (dup (check-duplicate-identifier (apply append (map sig-int-names out-sigs)))) + (out-vec (generate-temporaries out-sigs)) + (tmarker (make-syntax-introducer)) + (tmp-bindings (map (λ (s) (map tmarker (map car (car s)))) out-sigs)) + (def-table (make-bound-identifier-mapping))) + (when dup + (raise-stx-err (format "duplicate binding for ~.s" (syntax-e dup)))) + (for-each + (λ (sig new-xs) + (for-each + (λ (old new) + (bound-identifier-mapping-put! def-table old new)) + (map car (car sig)) + new-xs)) + out-sigs + tmp-bindings) + (with-syntax ((((key1 key ...) ...) (map tagged-info->keys out-tags)) + ((((int-binding . ext-binding) ...) ...) (map car out-sigs)) + ((out-vec ...) out-vec) + (((renames + (((mac-name ...) mac-body) ...) + (((val-name ...) val-body) ...)) + ...) + (map build-val+macro-defs out-sigs)) + ((out-names ...) + (map (lambda (info) (car (siginfo-names (cdr info)))) + out-tags)) + (((tmp-binding ...) ...) tmp-bindings) + (((out-code ...) ...) + (map + (lambda (os ov) + (map + (lambda (i) + #`(vector-ref #,ov #,i)) + (iota (length (car os))))) + out-sigs + out-vec)) + (((wrap-code ...) ...) + (map (λ (os ov tbs) + (define rename-bindings + (get-member-bindings def-table os #'(quote-module-name))) + (map (λ (tb i v c) + (if c + (with-syntax ([ctc-stx + (syntax-property + #`(letrec-syntax #,rename-bindings #,c) + 'inferred-name v)]) + #`(let ([v/c (#,tb)]) + (contract ctc-stx (car v/c) (cdr v/c) + (current-contract-region) + (quote #,v) (quote-srcloc #,v)))) + #`(#,tb))) + tbs + (iota (length (car os))) + (map car (car os)) + (cadddr os))) + out-sigs + out-vec + tmp-bindings))) + (quasisyntax/loc stx + (begin + (define-values (tmp-binding ... ...) + #,(syntax/loc #'unit-expr + (let ((unit-tmp unit-expr)) + (check-unit unit-tmp 'define-values/invoke-unit) + (check-sigs unit-tmp + (vector-immutable) + (vector-immutable (cons 'out-names + (vector-immutable key1 key ...)) ...) + 'define-values/invoke-unit) + (let-values (((unit-fn export-table) + ((unit-go unit-tmp)))) + (let ([out-vec (hash-ref export-table key1)] ...) + (unit-fn #f) + (values out-code ... ...)))))) + (define-values (int-binding ... ...) + (values wrap-code ... ...)) + (define-syntaxes . renames) ... + (define-syntaxes (mac-name ...) mac-body) ... ... + (define-values (val-name ...) val-body) ... ...))))) + ((_) + (raise-stx-err "missing unit expression")))) + +;; build-unit-from-context : syntax-object -> +;; (values syntax-object (listof identifier) (listof identifier)) +;; constructs the code for a unit-from-context expression. stx must be +;; such that it passes check-ufc-syntax. +;; The two additional values are the identifiers of the unit's import and export +;; signatures +(define-for-syntax (build-unit-from-context stx) + (syntax-case stx () + ((export-spec) + (let* ((tagged-export-sig (process-tagged-export #'export-spec)) + (export-sig (caddr tagged-export-sig))) + (with-syntax ((((int-id . ext-id) ...) (car export-sig)) + ((def-name ...) (generate-temporaries (map car (car export-sig))))) + (values + #'(:unit (import) (export (rename export-spec (def-name int-id) ...)) + (define def-name int-id) + ...) + null + (list (cadr tagged-export-sig)) + '())))))) + +(define-for-syntax (check-ufc-syntax stx) + (syntax-case stx () + ((export-spec) (void)) + (() + (raise-stx-err "missing export-spec")) + (_ + (raise-stx-err "nothing is permitted after export-spec")))) + +(define-syntax/err-param (unit-from-context stx) + (syntax-case stx () + ((_ . x) + (begin + (check-ufc-syntax #'x) + (let-values (((u x y z) (build-unit-from-context #'x))) + u))))) + + + +(define-for-syntax (build-define-unit-helper contracted?) + (lambda (stx build err-msg) + (syntax-case stx () + ((_ name . rest) + (begin + (check-id #'name) + (let-values (((exp i e d) (parameterize ([error-syntax (syntax-property (error-syntax) 'inferred-name (syntax-e #'name))]) + (build #'rest )))) + (with-syntax ((((itag . isig) ...) i) + (((etag . esig) ...) e) + (((deptag . depsig) ...) d) + (contracted? contracted?)) + (quasisyntax/loc (error-syntax) + (begin + (define u #,exp) + (define-syntax name + (make-set!-transformer + (make-unit-info (quote-syntax u) + (list (cons 'itag (quote-syntax isig)) ...) + (list (cons 'etag (quote-syntax esig)) ...) + (list (cons 'deptag (quote-syntax deptag)) ...) + (quote-syntax name) + contracted?))))))))) + ((_) + (raise-stx-err err-msg))))) + +;; build-define-unit : syntax-object +;; (syntax-object -> (values syntax-object (listof identifier) (listof identifier)) +;; string -> +;; syntax-object +(define-for-syntax build-define-unit (build-define-unit-helper #f)) +(define-for-syntax build-define-unit/contracted (build-define-unit-helper #t)) + +(define-for-syntax (build-define-unit-binding stx) + + (define (check-helper tagged-info) + (cons (car (siginfo-names (cdr tagged-info))) + (tagged-info->keys tagged-info))) + + (syntax-case stx (import export init-depend) + ((unit-exp (import i ...) (export e ...) (init-depend idep ...)) + (let* ([ti (syntax->list #'(i ...))] + [te (syntax->list #'(e ...))] + [tidep (syntax->list #'(idep ...))] + [tagged-import-sigids (map check-tagged-id ti)] + [tagged-export-sigids (map check-tagged-id te)] + [tagged-dep-sigids (map check-tagged-id tidep)] + [tagged-import-infos (map tagged-sigid->tagged-siginfo tagged-import-sigids)] + [tagged-export-infos (map tagged-sigid->tagged-siginfo tagged-export-sigids)] + [tagged-dep-siginfos (map tagged-sigid->tagged-siginfo tagged-dep-sigids)]) + (check-duplicate-sigs tagged-import-infos ti tagged-dep-siginfos tidep) + (check-duplicate-subs tagged-export-infos te) + (with-syntax ((((import-name . (import-keys ...)) ...) + (map check-helper tagged-import-infos)) + (((export-name . (export-keys ...)) ...) + (map check-helper tagged-export-infos)) + (form (stx-car (error-syntax)))) + (values + #`(let ([unit-tmp unit-exp]) + #,(syntax/loc #'unit-exp + (check-unit unit-tmp 'form)) + #,(syntax/loc #'unit-exp + (check-sigs unit-tmp + (vector-immutable + (cons 'import-name + (vector-immutable import-keys ...)) + ...) + (vector-immutable + (cons 'export-name + (vector-immutable export-keys ...)) + ...) + 'form)) + unit-tmp) + tagged-import-sigids + tagged-export-sigids + tagged-dep-sigids)))))) + +(define-syntax/err-param (define-unit-binding stx) + (build-define-unit stx (lambda (unit) + (build-define-unit-binding (check-unit-body-syntax unit))) + "missing unit name, unit expression, import clause, and export clause")) + +(define-syntax/err-param (define-unit stx) + (build-define-unit stx (lambda (unit) + (build-unit (check-unit-syntax unit))) + "missing unit name, import clause, and export clause")) + +(define-syntax/err-param (define-unit/new-import-export stx) + (build-define-unit stx (lambda (unit) + (build-unit/new-import-export (check-unit-syntax unit))) + "missing unit name, import clause, and export clause")) + +(define-syntax/err-param (define-compound-unit stx) + (build-define-unit stx (lambda (clauses) + (build-compound-unit (check-compound-syntax clauses))) + "missing unit name")) + +(define-syntax/err-param (define-unit-from-context stx) + (build-define-unit stx (lambda (sig) + (check-ufc-syntax sig) + (build-unit-from-context sig)) + "missing unit name and signature")) + +(define-for-syntax (build-unit/contract stx) + (syntax-parse stx + [(:import-clause/contract :export-clause/contract dep:dep-clause . body) + (let-values ([(exp isigs esigs deps) + (build-unit + (check-unit-syntax + (syntax/loc stx + ((import i.s ...) (export e.s ...) dep . body))))]) + (with-syntax ([name (syntax-local-infer-name (error-syntax))] + [(import-tagged-sig-id ...) + (map (λ (i s) + (if (identifier? i) #`(tag #,i #,s) s)) + (syntax->list #'(i.s.i ...)) + (syntax->list #'(i.s.s.name ...)))] + [(export-tagged-sig-id ...) + (map (λ (i s) + (if (identifier? i) #`(tag #,i #,s) s)) + (syntax->list #'(e.s.i ...)) + (syntax->list #'(e.s.s.name ...)))]) + (with-syntax ([new-unit exp] + [unit-contract + (unit/c/core + #'name + (syntax/loc stx + ((import (import-tagged-sig-id [i.x i.c] ...) ...) + (export (export-tagged-sig-id [e.x e.c] ...) ...))))]) + (values + (syntax/loc stx + (contract unit-contract new-unit '(unit name) (current-contract-region) (quote name) (quote-srcloc name))) + isigs esigs deps))))] + [(ic:import-clause/contract ec:export-clause/contract . body) + (build-unit/contract + (syntax/loc stx + (ic ec (init-depend) . body)))])) + +(define-syntax/err-param (define-unit/contract stx) + (build-define-unit/contracted stx (λ (stx) + (build-unit/contract stx)) + "missing unit name")) + +(define-for-syntax (unprocess-tagged-id ti) + (if (car ti) + #`(tag #,(car ti) #,(cdr ti)) + (cdr ti))) + +(define-for-syntax (temp-id-with-tags id i) + (syntax-case i (tag) + [(tag t sig) + (list id #`(tag t #,id) #'sig)] + [_else + (list id id i)])) + +(define-syntax/err-param (define-values/invoke-unit stx) + (syntax-case stx (import export) + ((_ u (import) (export e ...)) + (quasisyntax/loc stx + (define-values/invoke-unit/core u e ...))) + ((_ u (import i ...) (export e ...)) + (with-syntax (((EU ...) (generate-temporaries #'(e ...))) + (((IU IUl i) ...) (map temp-id-with-tags + (generate-temporaries #'(i ...)) + (syntax->list #'(i ...)))) + ((iu ...) (generate-temporaries #'(i ...))) + ((i-id ...) (map cdadr + (map process-tagged-import + (syntax->list #'(i ...))))) + ((e-id ...) (map cdadr + (map process-tagged-export + (syntax->list #'(e ...)))))) + (quasisyntax/loc stx + (begin + (define-unit-from-context iu i) + ... + (define-compound-unit u2 (import) + (export EU ...) + (link [((IU : i-id)) iu] ... [((EU : e-id) ...) u IUl ...])) + (define-values/invoke-unit/core u2 e ...))))) + ((_) + (raise-stx-err "missing unit" stx)) + ((_ . b) + (raise-stx-err + (format "expected syntax matching (~a (import ...) (export ...))" + (syntax-e (stx-car stx))))))) + +;; build-compound-unit/infer : syntax-object -> +;; (values syntax-object (listof identifier) (listof identifier)) +;; constructs the code for a compound-unit/infer expression. stx match the return of +;; check-compound-syntax +;; The two additional values are the identifiers of the compound-unit's import and export +;; signatures +(define-for-syntax (build-compound-unit/infer stx) + + (define (lookup-tagged tid) + (cons (car tid) (lookup-signature (cdr tid)))) + + (define (process-signature s) + (define l + ((check-tagged + (lambda (b) + (syntax-case* b (:) (lambda (x y) (eq? (syntax-e x) (syntax-e y))) + ((x : y) + (and (identifier? #'x) (identifier? #'y)) + (list #'x #'y (signature-siginfo (lookup-signature #'y)))) + (x + (identifier? #'x) + (list (car (generate-temporaries (list #'x))) + #'x + (signature-siginfo (lookup-signature #'x)))) + (_ + (raise-stx-err "expected syntax matching or ( : )" + b))))) + s)) + (apply make-link-record l)) + + (define ((process-tagged-sigid introducer) sid) + (make-link-record (car sid) #f (introducer (cdr sid)) (signature-siginfo (lookup-signature (cdr sid))))) + + (syntax-case stx () + (((import ...) + (export ...) + (((out ...) u l ...) ...)) + (let* ([us (syntax->list #'(u ...))] + [units (map lookup-def-unit us)] + [import-sigs (map process-signature + (syntax->list #'(import ...)))] + [sig-introducers (map (lambda (unit u) + (make-syntax-delta-introducer u (unit-info-orig-binder unit))) + units us)] + [sub-outs + (map + (lambda (outs unit sig-introducer) + (define o + (map + (lambda (clause) + (define c (check-tagged-:-clause clause)) + (make-link-record (car c) (cadr c) (cddr c) + (signature-siginfo (lookup-signature (cddr c))))) + (syntax->list outs))) + (complete-exports (map (process-tagged-sigid sig-introducer) (unit-info-export-sig-ids unit)) + o)) + (syntax->list #'((out ...) ...)) + units + sig-introducers)] + [link-defs (append import-sigs (apply append sub-outs))]) + + (define lnk-table (make-bound-identifier-mapping)) + (define sig-table (make-hasheq)) + + (let ([dup (check-duplicate-identifier (map link-record-linkid link-defs))]) + (when dup + (raise-stx-err "duplicate identifier" dup))) + + (for-each + (lambda (b) + (bound-identifier-mapping-put! lnk-table (link-record-linkid b) b)) + link-defs) + + (for-each + (lambda (b) + (for-each + (lambda (cid) + (define there? (hash-ref sig-table cid #f)) + (hash-set! sig-table cid (if there? 'duplicate (link-record-linkid b)))) + (siginfo-ctime-ids (link-record-siginfo b)))) + link-defs) + + (let ([sub-ins + (map + (lambda (ins unit sig-introducer unit-stx) + (define is (syntax->list ins)) + (define lrs + (map + (lambda (i) + (define tagged-lnkid (check-tagged-id i)) + (define sig + (bound-identifier-mapping-get lnk-table + (cdr tagged-lnkid) + (lambda () #f))) + (unless sig + (raise-stx-err "unknown linking identifier" i)) + (make-link-record (car tagged-lnkid) + (cdr tagged-lnkid) + (link-record-sigid sig) + (link-record-siginfo sig))) + is)) + (check-duplicate-subs + (map + (lambda (lr) (cons (link-record-tag lr) (link-record-siginfo lr))) + lrs) + is) + (complete-imports sig-table + lrs + (map (process-tagged-sigid sig-introducer) + (unit-info-import-sig-ids unit)) + unit-stx)) + (syntax->list #'((l ...) ...)) + units + sig-introducers + us)] + [exports + (map + (lambda (e) + (define tid (check-tagged-id e)) + (define lookup (bound-identifier-mapping-get + lnk-table + (cdr tid) + (lambda () #f))) + (cond + [lookup (unprocess-tagged-id tid)] + [else + (let ([lnkid (hash-ref + sig-table + (car (siginfo-ctime-ids (signature-siginfo (lookup-signature (cdr tid))))) + #f)]) + (cond + [(not lnkid) + (raise-stx-err "no sub unit exports this signature" (cdr tid))] + [(eq? lnkid 'duplicate) + (raise-stx-err "multiple sub units export this signature" (cdr tid))] + [else + (unprocess-tagged-id + (cons (car tid) lnkid))]))])) + (syntax->list #'(export ...)))]) + (with-syntax (((import ...) + (map unprocess-link-record-bind import-sigs)) + (((out ...) ...) + (map + (lambda (out) + (map unprocess-link-record-bind out)) + sub-outs)) + (((in ...) ...) + (map + (lambda (ins) + (map unprocess-link-record-use ins)) + sub-ins)) + ((unit-id ...) (map + (lambda (u stx) + (quasisyntax/loc stx #,(unit-info-unit-id u))) + units (syntax->list #'(u ...))))) + (build-compound-unit #`((import ...) + #,exports + (((out ...) unit-id in ...) ...))))))) + (((i ...) (e ...) (l ...)) + (for-each check-link-line-syntax (syntax->list #'(l ...)))))) + + +(define-for-syntax (check-compound/infer-syntax stx) + (syntax-case (check-compound-syntax stx) () + ((i e (b ...)) + (with-syntax (((b ...) + (map + (lambda (b) + (if (identifier? b) + #`(() #,b) + b)) + (syntax->list #'(b ...))))) + #'(i e (b ...)))))) + +(define-syntax/err-param (compound-unit/infer stx) + (let-values (((u i e d) + (build-compound-unit/infer + (check-compound/infer-syntax + (syntax-case stx () ((_ . x) #'x)))))) + u)) + +(define-for-syntax (do-define-compound-unit/infer stx) + (build-define-unit stx + (lambda (clause) + (build-compound-unit/infer (check-compound/infer-syntax clause))) + "missing unit name")) + +(define-syntax/err-param (define-compound-unit/infer stx) + (do-define-compound-unit/infer stx)) + +;; (syntax or listof[syntax]) boolean (boolean or listof[syntax]) -> syntax +(define-for-syntax (build-invoke-unit/infer units define? exports) + (define (imps/exps-from-unit u) + (let* ([ui (lookup-def-unit u)] + [unprocess (let ([i (make-syntax-delta-introducer u (unit-info-orig-binder ui))]) + (lambda (p) + (unprocess-tagged-id (cons (car p) (i (cdr p))))))] + [isigs (map unprocess (unit-info-import-sig-ids ui))] + [esigs (map unprocess (unit-info-export-sig-ids ui))]) + (values isigs esigs))) + (define (drop-from-other-list exp-tagged imp-tagged imp-sources) + (let loop ([ts imp-tagged] [ss imp-sources]) + (cond + [(null? ts) null] + [(ormap (lambda (tinfo2) + (and (eq? (car (car ts)) (car tinfo2)) + (siginfo-subtype (cdr tinfo2) (cdr (car ts))))) + exp-tagged) + (loop (cdr ts) (cdr ss))] + [else (cons (car ss) (loop (cdr ts) (cdr ss)))]))) + + (define (drop-duplicates tagged-siginfos sources) + (let loop ([ts tagged-siginfos] [ss sources] [res-t null] [res-s null]) + (cond + [(null? ts) (values res-t res-s)] + [(ormap (lambda (tinfo2) + (and (eq? (car (car ts)) (car tinfo2)) + (siginfo-subtype (cdr tinfo2) (cdr (car ts))))) + (cdr ts)) + (loop (cdr ts) (cdr ss) res-t res-s)] + [else (loop (cdr ts) (cdr ss) (cons (car ts) res-t) (cons (car ss) res-s))]))) + + (define (imps/exps-from-units units exports) + (define-values (isigs esigs) + (let loop ([units units] [imps null] [exps null]) + (if (null? units) + (values imps exps) + (let-values ([(i e) (imps/exps-from-unit (car units))]) + (loop (cdr units) (append i imps) (append e exps)))))) + (define-values (isig tagged-import-sigs import-tagged-infos + import-tagged-sigids import-sigs) + (process-unit-import (datum->syntax #f isigs))) + + (define-values (esig tagged-export-sigs export-tagged-infos + export-tagged-sigids export-sigs) + (process-unit-export (datum->syntax #f esigs))) + (check-duplicate-subs export-tagged-infos esig) + (let-values ([(itagged isources) (drop-duplicates import-tagged-infos isig)]) + (values (drop-from-other-list export-tagged-infos itagged isources) + (cond + [(list? exports) + (let-values ([(spec-esig spec-tagged-export-sigs spec-export-tagged-infos + spec-export-tagged-sigids spec-export-sigs) + (process-unit-export (datum->syntax #f exports))]) + (restrict-exports export-tagged-infos + spec-esig spec-export-tagged-infos))] + [else esig])))) + + (define (restrict-exports unit-tagged-exports spec-exports spec-tagged-exports) + (for-each (lambda (se ste) + (unless (ormap (lambda (ute) + (and (eq? (car ute) (car ste)) + (siginfo-subtype (cdr ute) (cdr ste)))) + unit-tagged-exports) + (raise-stx-err (format "no subunit exports signature ~a" + (syntax->datum se)) + se))) + spec-exports + spec-tagged-exports) + spec-exports) + (when (and (not define?) exports) + (error 'build-invoke-unit/infer + "internal error: exports for invoke-unit/infer")) + (when (null? units) + (raise-stx-err "no units in link clause")) + (cond [(identifier? units) + (let-values ([(isig esig) (imps/exps-from-units (list units) exports)]) + (with-syntax ([u units] + [(esig ...) esig] + [(isig ...) isig]) + (if define? + (syntax/loc (error-syntax) (define-values/invoke-unit u (import isig ...) (export esig ...))) + (syntax/loc (error-syntax) (invoke-unit u (import isig ...))))))] + [(list? units) + (let-values ([(isig esig) (imps/exps-from-units units exports)]) + (with-syntax ([(new-unit) (generate-temporaries '(new-unit))] + [(unit ...) units] + [(esig ...) esig] + [(isig ...) isig]) + (with-syntax ([u (let-values ([(u i e d) + (build-compound-unit/infer + (check-compound/infer-syntax + #'((import isig ...) + (export esig ...) + (link unit ...))))]) u)]) + (if define? + (syntax/loc (error-syntax) + (define-values/invoke-unit u + (import isig ...) (export esig ...))) + (syntax/loc (error-syntax) + (invoke-unit u + (import isig ...)))))))] + ;; just for error handling + [else (lookup-def-unit units)])) + +(define-syntax/err-param (define-values/invoke-unit/infer stx) + (syntax-case stx (export link) + [(_ (link unit ...)) + (build-invoke-unit/infer (syntax->list #'(unit ...)) #t #f)] + [(_ (export e ...) (link unit ...)) + (build-invoke-unit/infer (syntax->list #'(unit ...)) #t (syntax->list #'(e ...)))] + [(_ (export e ...) u) + (build-invoke-unit/infer #'u #t (syntax->list #'(e ...)))] + [(_ u) + (build-invoke-unit/infer #'u #t #f)] + [(_) + (raise-stx-err "missing unit" stx)] + [(_ . b) + (raise-stx-err + (format "expected syntax matching (~a [(export )] ) or (~a [(export )] (link ...))" + (syntax-e (stx-car stx)) (syntax-e (stx-car stx))))])) + +(define-syntax/err-param (invoke-unit stx) + (syntax-case stx (import) + ((_ unit) + (syntax/loc stx + (invoke-unit/core unit))) + ((_ unit (import isig ...)) + (with-syntax (((u ...) (generate-temporaries (syntax->list #'(isig ...)))) + (((U Ul isig) ...) (map temp-id-with-tags + (generate-temporaries #'(isig ...)) + (syntax->list #'(isig ...)))) + ((isig-id ...) (map cdadr + (map process-tagged-import + (syntax->list #'(isig ...)))))) + (syntax/loc stx + (let () + (define-unit-from-context u isig) + ... + (define-compound-unit u2 (import) (export) + (link [((U : isig-id)) u] ... [() unit Ul ...])) + (invoke-unit/core u2))))) + (_ (raise-stx-err (format + "expected (~a ) or (~a (import ...))" + (syntax-e (stx-car stx)) + (syntax-e (stx-car stx))))))) + +(define-syntax/err-param (invoke-unit/infer stx) + (syntax-case stx () + [(_ (link unit ...)) + (build-invoke-unit/infer (syntax->list #'(unit ...)) #f #f)] + [(_ u) (build-invoke-unit/infer #'u #f #f)] + [(_) + (raise-stx-err "missing unit" stx)] + [(_ . b) + (raise-stx-err + (format "expected syntax matching (~a ) or (~a (link ...))" + (syntax-e (stx-car stx)) (syntax-e (stx-car stx))))])) + +(define-for-syntax (build-unit/s stx) + (syntax-case stx (import export init-depend) + [((import i ...) (export e ...) (init-depend d ...) u) + (let* ([ui (lookup-def-unit #'u)] + [unprocess (let ([i (make-syntax-delta-introducer #'u (unit-info-orig-binder ui))]) + (lambda (p) + (unprocess-tagged-id (cons (car p) (i (cdr p))))))]) + (with-syntax ([(isig ...) (map unprocess (unit-info-import-sig-ids ui))] + [(esig ...) (map unprocess (unit-info-export-sig-ids ui))]) + (build-unit/new-import-export + (syntax/loc stx + ((import i ...) (export e ...) (init-depend d ...) ((esig ...) u isig ...))))))])) + +(define-syntax/err-param (define-unit/s stx) + (build-define-unit stx (λ (stx) (build-unit/s (check-unit-syntax stx))) + "missing unit name")) + +(define-syntax/err-param (unit/s stx) + (syntax-case stx () + [(_ . stx) + (let-values ([(u x y z) (build-unit/s (check-unit-syntax #'stx))]) + u)])) diff --git a/collects/mzlib/zip.rkt b/collects/mzlib/zip.rkt index d1c59e6bae..e67c2dbf3e 100644 --- a/collects/mzlib/zip.rkt +++ b/collects/mzlib/zip.rkt @@ -1,6 +1,269 @@ -#lang racket/base +;; A modification of Dave Herman's zip module -;; deprecated library, see `file/zip` +(module zip mzscheme + (require mzlib/deflate racket/file mzlib/kw) -(require file/zip) -(provide (all-from-out file/zip)) + ;; =========================================================================== + ;; DATA DEFINITIONS + ;; =========================================================================== + + ;; An msdos-time or an msdos-date is an exact-integer in the respective format + ;; described at: + ;; + ;; http://msdn.microsoft.com/library/en-us/com/htm/cmf_a2c_25gl.asp + + ;; metadata : path * bytes * boolean * integer * integer * nat * integer + (define-struct metadata + (path name directory? time date compression attributes)) + + ;; header : metadata * exact-integer * nat * nat * nat + (define-struct header (metadata crc compressed uncompressed size)) + + ;; =========================================================================== + ;; CONSTANTS etc + ;; =========================================================================== + + (define *spec-version* 62) ; version 6.2 + (define *required-version* 20) ; version 2.0 + (define *compression-level* 8) ; I don't think this is configurable + (define *zip-comment* #"packed by Racket - http://racket-lang.org/") + + ;; PKZIP specification: + ;; http://www.pkware.com/company/standards/appnote/ + + (define *local-file-header* #x04034b50) + (define *archive-extra-record* #x08064b50) + (define *central-file-header* #x02014b50) + (define *digital-signature* #x05054b50) + (define *zip64-end-of-central-directory-record* #x06064b50) + (define *zip64-end-of-central-directory-locator* #x07064b50) + (define *end-of-central-directory-record* #x06054b50) + + (define *system* + (case (system-type) + [(unix oskit) 3] + [(windows) 0] + [(macos) 7] + [(macosx) 19])) + (define *os-specific-separator-regexp* + (case (system-type) + [(unix macosx oskit) #rx"/"] + [(windows) #rx"\\\\"] + [(macos) #rx":"])) + + (provide zip-verbose) + (define zip-verbose (make-parameter #f)) + + ;; =========================================================================== + ;; FILE CREATION + ;; =========================================================================== + + ;; date->msdos-time : date -> msdos-time + (define (date->msdos-time date) + (bitwise-ior (ceiling (/ (date-second date) 2)) + (arithmetic-shift (date-minute date) 5) + (arithmetic-shift (date-hour date) 11))) + + ;; date->msdos-date : date -> msdos-date + (define (date->msdos-date date) + (bitwise-ior (date-day date) + (arithmetic-shift (date-month date) 5) + (arithmetic-shift (- (date-year date) 1980) 9))) + + ;; seekable-port? : port -> boolean + (define (seekable-port? port) + (and (file-stream-port? port) + (with-handlers ([void (lambda (exn) #f)]) + (file-position port (file-position port)) + #t))) + + (define (write-int n size) + (write-bytes (integer->integer-bytes n size #f #f))) + + ;; zip-one-entry : metadata boolean -> header + (define (zip-one-entry metadata seekable?) + (let* ([directory? (metadata-directory? metadata)] + [path (metadata-path metadata)] + [filename (metadata-name metadata)] + [filename-length (bytes-length filename)] + [bits (if seekable? 0 #b1000)] + [time (metadata-time metadata)] + [date (metadata-date metadata)] + [compression (metadata-compression metadata)] + [mark1 #f] + [mark2 #f]) + (when (zip-verbose) + (eprintf "zip: compressing ~a...\n" filename)) + ;; write the contents to the output stream: + (write-int *local-file-header* 4) ; signature + (write-int *required-version* 2) ; version + (write-int bits 2) ; bits + (write-int compression 2) ; compression + (write-int time 2) ; time + (write-int date 2) ; date + (when seekable? (set! mark1 (file-position (current-output-port)))) + (write-int 0 4) ; crc-32 + (write-int 0 4) ; compressed + (write-int 0 4) ; uncompressed + (write-int filename-length 2) ; filename-length + (write-int 0 2) ; extra-length + (write-bytes filename) ; filename + (if directory? + (make-header metadata 0 0 0 (+ filename-length 30)) + (let-values ([(uncompressed compressed crc) + (with-input-from-file path + (lambda () + (deflate (current-input-port) + (current-output-port))))]) + (if seekable? + (begin (set! mark2 (file-position (current-output-port))) + (file-position (current-output-port) mark1)) + (write-int #x08074b50 4)) ; EXT signature + (write-int crc 4) ; crc-32 + (write-int compressed 4) ; compressed + (write-int uncompressed 4) ; uncompressed + (when seekable? (file-position (current-output-port) mark2)) + + ;; return the header information + (make-header metadata crc compressed uncompressed + (+ filename-length compressed + (if seekable? 30 46))))))) + + ;; write-end-of-central-directory : nat nat nat -> + (define (write-end-of-central-directory count start size) + (let ([comment-length (bytes-length *zip-comment*)]) + (write-int #x06054b50 4) ; signature + (write-int 0 2) ; # this disk + (write-int 0 2) ; # disk with start of central dir. + (write-int count 2) ; # entries in central dir. on this disk + (write-int count 2) ; # entries in central dir. + (write-int size 4) ; size of central dir. + (write-int start 4) ; offset of start of central dir. + (write-int comment-length 2) + (write-bytes *zip-comment*))) + + ;; write-central-directory : (listof header) -> + (define (write-central-directory headers) + (let ([count (length headers)]) + (let loop ([headers headers] [offset 0] [size 0]) + (if (null? headers) + ;; no digital signature (why?) + (write-end-of-central-directory count offset size) + (let* ([header (car headers)] + [metadata (header-metadata header)] + [filename-length (bytes-length (metadata-name metadata))] + [attributes (metadata-attributes metadata)] + [compression (metadata-compression metadata)] + [version (bitwise-ior *spec-version* + (arithmetic-shift *system* 8))]) + (write-int #x02014b50 4) + (write-int version 2) + (write-int *required-version* 2) + (write-int 0 2) + (write-int compression 2) + (write-int (metadata-time metadata) 2) + (write-int (metadata-date metadata) 2) + (write-int (header-crc header) 4) + (write-int (header-compressed header) 4) + (write-int (header-uncompressed header) 4) + (write-int filename-length 2) + (write-int 0 2) + (write-int 0 2) ; comment length + (write-int 0 2) + (write-int 0 2) ; internal attributes + (write-int attributes 4) ; external attributes + (write-int offset 4) + (write-bytes (metadata-name metadata)) + (loop (cdr headers) + (+ offset (header-size header)) + (+ size filename-length 46))))))) + + ;; The PKZIP specification includes an entry in the central directory for + ;; an entry's "external file attributes," which for standard ZIP files is + ;; the MS-DOS (i.e., FAT) directory attribute byte, and the Unix zip adds + ;; the Unix bits as the higher two bytes. + + ;; This is for reference + ;; (define *msdos:read-only* #x01) + ;; (define *msdos:hidden* #x02) + ;; (define *msdos:system* #x04) + ;; (define *msdos:volume* #x08) + ;; (define *msdos:directory* #x10) + ;; (define *msdos:archive* #x20) + ;; (define *unix:directory* #o40000) + ;; (define *unix:char-dev* #o20000) + ;; (define *unix:fifo* #o10000) + ;; (define *unix:suid* #o04000) + ;; (define *unix:sgid* #o02000) + ;; (define *unix:sticky* #o01000) + ;; (define *unix:owner-read* #o00400) + ;; (define *unix:owner-write* #o00200) + ;; (define *unix:owner-exe* #o00100) + ;; (define *unix:group-read* #o00040) + ;; (define *unix:group-write* #o00020) + ;; (define *unix:group-exe* #o00010) + ;; (define *unix:other-read* #o00004) + ;; (define *unix:other-write* #o00002) + ;; (define *unix:other-exe* #o00001) + (define (path-attributes path dir?) + (let ([dos (if dir? #x10 0)] + [unix (apply bitwise-ior (if dir? #o40000 0) + (map (lambda (p) + (case p + [(read) #o444] + [(write) #o200] ; mask out write bits + [(execute) #o111])) + (file-or-directory-permissions path)))]) + (bitwise-ior dos (arithmetic-shift unix 16)))) + + ;; with-trailing-slash : bytes -> bytes + (define (with-trailing-slash bytes) + (regexp-replace #rx#"/*$" bytes "/")) + + ;; with-slash-separator : bytes -> bytes + (define (with-slash-separator bytes) + (regexp-replace* *os-specific-separator-regexp* bytes #"/")) + + ;; build-metadata : relative-path -> metadata + (define (build-metadata path) + (let* ([mod (seconds->date (file-or-directory-modify-seconds path))] + [dir? (directory-exists? path)] + [path (cond [(path? path) path] + [(string? path) (string->path path)] + [(bytes? path) (bytes->path path)])] + [name (with-slash-separator (path->bytes path))] + [name (if dir? (with-trailing-slash name) name)] + [time (date->msdos-time mod)] + [date (date->msdos-date mod)] + [comp (if dir? 0 *compression-level*)] + [attr (path-attributes path dir?)]) + (make-metadata path name dir? time date comp attr))) + + ;; =========================================================================== + ;; FRONT END + ;; =========================================================================== + + ;; zip-write : (listof relative-path) -> + ;; writes a zip file to current-output-port + (provide zip->output) + (define/kw (zip->output files #:optional [out (current-output-port)]) + (parameterize ([current-output-port out]) + (let* ([seekable? (seekable-port? (current-output-port))] + [headers ; note: Racket's `map' is always left-to-right + (map (lambda (file) + (zip-one-entry (build-metadata file) seekable?)) + files)]) + (when (zip-verbose) + (eprintf "zip: writing headers...\n")) + (write-central-directory headers)) + (when (zip-verbose) + (eprintf "zip: done.\n")))) + + ;; zip : output-file paths -> + (provide zip) + (define (zip zip-file . paths) + (when (null? paths) (error 'zip "no paths specified")) + (with-output-to-file zip-file + (lambda () (zip->output (pathlist-closure paths))))) + + ) diff --git a/collects/racket/control.rkt b/collects/racket/control.rkt index d59f00ffb7..541f42dfc2 100644 --- a/collects/racket/control.rkt +++ b/collects/racket/control.rkt @@ -1,268 +1,4 @@ -#lang racket/base - -(require (for-syntax racket/base)) - -(provide call/prompt call/comp abort/cc - - abort - - fcontrol % - - control prompt control-at prompt-at - ;; `-at' variations expect a prompt tag - - shift reset shift-at reset-at - - control0 prompt0 control0-at prompt0-at - shift0 reset0 shift0-at reset0-at - - spawn - - splitter - - new-prompt set cupto) - -;; ---------------------------------------- - -(define call/prompt call-with-continuation-prompt) -(define call/comp call-with-composable-continuation) -(define abort/cc abort-current-continuation) - -;; ---------------------------------------- - -(define (abort . vals) - (abort-current-continuation - (default-continuation-prompt-tag) - (lambda () (apply values vals)))) - -;; ---------------------------------------- -;; Sitaram, PLDI'93 -;; The `%' here is compable with Sitaram & Felleisen, LSC'90, -;; since we make the handler optional. - -(define (fcontrol f #:tag [prompt-tag (default-continuation-prompt-tag)]) - (call-with-composable-continuation - (lambda (k) - (abort-current-continuation - prompt-tag - f - k)))) - -(define-syntax % - (syntax-rules () - [(_ expr handler #:tag prompt-tag) - (call-with-continuation-prompt - (lambda () expr) - prompt-tag - handler)] - [(_ expr handler) - (call-with-continuation-prompt - (lambda () expr) - (default-continuation-prompt-tag) - handler)] - [(_ expr) - (call-with-continuation-prompt - (lambda () expr))])) - -;; ---------------------------------------- -;; Predecessors of Sitaram, PLDI'93 -;; Felleisen, Wand, Friedman, & Duba, LFP'88 -;; Instead of `#', we use `prompt' as in Felleisen, POPL'88 -;; (where `control' is called `F') -;; See also Sitaram and Felleisen, LSC'90 - -;; Helpder function: abort-current-continuation/keep-prompt is -;; like abort-current-continuation, but it always leaves the -;; prompt in place, independent of the prompt's handler. -;; This is possible via call/cc (i.e., it must be possible -;; to abort and keep a prompt, because call/cc needs it). -(define (abort-current-continuation/keep-prompt tag thunk) - ((call-with-continuation-prompt - (lambda () - ((call-with-current-continuation - (lambda (k) (lambda () k)) - tag))) - tag) - thunk)) - -;; call-with-control, parameterized over whether to keep the -;; prompt (if the prompt's handler gives us the option of -;; removing it). The generated function is the same -;; as fcontrol when `abort-cc' is `abort-current-continuation'. -(define (make-call-with-control abort-cc) - ;; Uses call/cc to always keep the enclosing prompt. - (letrec ([call-with-control - (case-lambda - [(f) (call-with-control f (default-continuation-prompt-tag))] - [(f tag) (call-with-composable-continuation - (lambda (k) - (abort-cc - tag - (lambda () - (f k)))) - tag)])]) - call-with-control)) - -(define call-with-control - (make-call-with-control abort-current-continuation/keep-prompt)) - -(define-syntax define-control-macros - (syntax-rules () - [(_ control control-at call-with-control) - (begin - (define-syntax (control stx) - (syntax-case stx () - [(control id expr0 expr (... ...)) - (identifier? #'id) - #'(call-with-control (lambda (id) expr0 expr (... ...)))])) - (define-syntax (control-at stx) - (syntax-case stx () - [(control-at tag id expr0 expr (... ...)) - (identifier? #'id) - #'(call-with-control (lambda (id) expr0 expr (... ...)) tag)])))])) - -(define-control-macros control control-at call-with-control) - -(define-syntax define-prompt-macros - (syntax-rules () - [(_ prompt prompt-at call-with-prompt) - (begin - (define-syntax prompt - (syntax-rules () - [(prompt expr0 expr (... ...)) - (call-with-prompt (lambda () expr0 expr (... ...)))])) - (define-syntax prompt-at - (syntax-rules () - [(prompt-at tag expr0 expr (... ...)) - (call-with-prompt (lambda () expr0 expr (... ...)) tag)])))])) - -(define-prompt-macros prompt prompt-at call-with-continuation-prompt) - -;; ---------------------------------------- -;; Danvy & Filinski, LFP'90 - -;; call-with-shift, parameterized over whether to keep the prompt -;; (if the prompt's handler gives us the option of removing it), -;; and whether the new one is removable: -(define (make-call-with-shift abort-cc inserted-handler) - (letrec ([call-with-shift - (case-lambda - [(f) (call-with-shift f (default-continuation-prompt-tag))] - [(f tag) - (call-with-composable-continuation - (lambda (k) - (abort-cc - tag - (lambda () - (f (lambda vals - (call-with-continuation-prompt - (lambda () - (apply k vals)) - tag - inserted-handler)))))) - tag)])]) - call-with-shift)) - -(define call-with-shift - (make-call-with-shift abort-current-continuation/keep-prompt #f)) - -(define-control-macros shift shift-at call-with-shift) - -(define-prompt-macros reset reset-at call-with-continuation-prompt) - -;; ---------------------------------------- -;; Shan, SCHEME'04 -;; Kiselyov, Indiana CS TR-611, 2005 -;; -;; The `control0' and `shift0' here are closer to Kiselyov, in that -;; `control0' and `shift0' only behave as in Shan when paired with -;; `prompt0' or `reset0' (which are two names for the same thing). -;; When paired with `prompt' or `reset' (again, the same thing), -;; they act like `control' and `shift'. -;; -;; This difference is intentional. The programmer that inserts a -;; prompt should choose whether the current continuation is visible -;; or not. Note, also, that `control' and `shift' work whether -;; they're paired with `prompt'/`reset' or `prompt0'/`reset0'. - -(define call-with-control0 - ;; Uses abort-current-continuation, so that the prompt - ;; is removed --- if the prompt is willing to be removed. - (make-call-with-control abort-current-continuation)) - -(define call-with-shift0 - ;; Uses abort-current-continuation, so that the prompt - ;; is removed --- if the prompt is willing to be removed. - ;; The prompt installed with the captured continuation is - ;; itself willing to be removed. - (make-call-with-shift abort-current-continuation (lambda (thunk) (thunk)))) - -(define-control-macros control0 control0-at call-with-control0) - -(define-control-macros shift0 shift0-at call-with-shift0) - -(define call-with-prompt0 - (case-lambda - [(thunk) (call-with-prompt0 thunk (default-continuation-prompt-tag))] - [(thunk tag) - (call-with-continuation-prompt thunk tag (lambda (thunk) (thunk)))])) - -(define-prompt-macros prompt0 prompt0-at call-with-prompt0) - -(define-prompt-macros reset0 reset0-at call-with-prompt0) - -;; ---------------------------------------- -;; Hieb & Dybvig, PPOPP'90 - -(define (spawn f) - (let ([p (make-continuation-prompt-tag)]) - (call-with-continuation-prompt - (lambda () - (f (lambda (f) - (call-with-composable-continuation - (lambda (k) - (abort-current-continuation - p - (lambda () - (f (lambda vals - (call-with-continuation-prompt - (lambda () - (apply k vals)) - p - (lambda (thunk) (thunk)))))))) - p)))) - p - (lambda (thunk) (thunk))))) - -;; ---------------------------------------- -;; Queinnec & Serpette, POPL'91 - -(define (splitter receiver) - (let ([p (make-continuation-prompt-tag)]) - (call-with-continuation-prompt - (lambda () - (receiver (lambda (thunk) - (abort-current-continuation - p - thunk)) - (lambda (proc) - (call-with-composable-continuation - proc - p)))) - p - (lambda (thunk) (thunk))))) - -;; ---------------------------------------- -;; Gunter, Remy, & Rieke, FPLCA'95 -;; Unfortunately, the "prompt"s in Gunter et al. are what -;; we call "prompt tags". In our terminology, a "prompt" -;; is a tagged instance in a continuation. - -(define (new-prompt) (make-continuation-prompt-tag)) - -(define-syntax set (make-rename-transformer #'prompt0-at)) - -(define-syntax cupto (make-rename-transformer #'control0-at)) - -;; ---------------------------------------- +(module control racket/base + (require mzlib/control) + (provide (all-from-out mzlib/control))) diff --git a/collects/racket/date.rkt b/collects/racket/date.rkt index c37deeabdd..53e336af93 100644 --- a/collects/racket/date.rkt +++ b/collects/racket/date.rkt @@ -1,367 +1,3 @@ -#lang racket/base -(require racket/promise - racket/match - racket/list - racket/function - racket/contract/base) - -(provide/contract - [current-date (-> date?)] - [date->seconds ((date?) (any/c) . ->* . exact-integer?)] - [date->string ((date?) (any/c) . ->* . string?)] - [date-display-format (parameter/c (symbols 'american 'chinese 'german 'indian 'irish 'julian 'iso-8601 'rfc2822))] - [find-seconds (((integer-in 0 61) - (integer-in 0 59) - (integer-in 0 23) - (integer-in 1 31) - (integer-in 1 12) - exact-nonnegative-integer?) - (any/c) - . ->* . - exact-integer?)] - [date->julian/scalinger (date? . -> . exact-integer?)] - [julian/scalinger->string (exact-integer? . -> . string?)]) - -(define (current-date) - (seconds->date (current-seconds))) - -;; Support for Julian calendar added by Shriram; -;; current version only works until 2099 CE Gregorian - -(define date-display-format - (make-parameter 'american)) - -(define (month/number->string x) - (case x - [(12) "December"] [(1) "January"] [(2) "February"] - [(3) "March"] [(4) "April"] [(5) "May"] - [(6) "June"] [(7) "July"] [(8) "August"] - [(9) "September"] [(10) "October"] [(11) "November"] - [else ""])) - -(define (day/number->string x) - (case x - [(0) "Sunday"] - [(1) "Monday"] - [(2) "Tuesday"] - [(3) "Wednesday"] - [(4) "Thursday"] - [(5) "Friday"] - [(6) "Saturday"] - [else ""])) - -(define (add-zero n) - (if (< n 10) - (string-append "0" (number->string n)) - (number->string n))) - -(define (date->string date [time? #f]) - (define year (number->string (date-year date))) - (define num-month (number->string (date-month date))) - (define week-day (day/number->string (date-week-day date))) - (define week-day-num (date-week-day date)) - (define month (month/number->string (date-month date))) - (define day (number->string (date-day date))) - (define day-th - (if (<= 11 (date-day date) 13) - "th" - (case (modulo (date-day date) 10) - [(1) "st"] - [(2) "nd"] - [(3) "rd"] - [(0 4 5 6 7 8 9) "th"]))) - (define hour (date-hour date)) - (define am-pm (if (>= hour 12) "pm" "am")) - (define hour24 (add-zero hour)) - (define hour12 - (number->string - (cond - [(zero? hour) 12] - [(> hour 12) (- hour 12)] - [else hour]))) - (define minute (add-zero (date-minute date))) - (define second (add-zero (date-second date))) - (define-values - (day-strs time-strs) - (case (date-display-format) - [(american) - (values (list week-day ", " month " " day day-th ", " year) - (list " " hour12 ":" minute ":" second am-pm))] - [(chinese) - (values - (list year "/" num-month "/" day - " \u661F\u671F" (case (date-week-day date) - [(0) "\u5929"] - [(1) "\u4E00"] - [(2) "\u4E8C"] - [(3) "\u4e09"] - [(4) "\u56DB"] - [(5) "\u4E94"] - [(6) "\u516D"] - [else ""])) - (list " " hour24 ":" minute ":" second))] - [(indian) - (values (list day "-" num-month "-" year) - (list " " hour12 ":" minute ":" second am-pm))] - [(german) - (values (list day ". " - (case (date-month date) - [(1) "Januar"] - [(2) "Februar"] - [(3) "M\344rz"] - [(4) "April"] - [(5) "Mai"] - [(6) "Juni"] - [(7) "Juli"] - [(8) "August"] - [(9) "September"] - [(10) "Oktober"] - [(11) "November"] - [(12) "Dezember"] - [else ""]) - " " year) - (list ", " hour24 "." minute))] - [(irish) - (values (list week-day ", " day day-th " " month " " year) - (list ", " hour12 ":" minute am-pm))] - [(julian) - (values (list (julian/scalinger->string - (date->julian/scalinger date))) - (list ", " hour24 ":" minute ":" second))] - [(iso-8601) - (values - (list year "-" (add-zero (date-month date)) "-" (add-zero (date-day date))) - (list " " hour24 ":" minute ":" second))] - [(rfc2822) - (values - (list (substring week-day 0 3) ", " day " " (substring month 0 3) " " year) - (list* " " hour24 ":" minute ":" second " " - (let* ([delta (date-time-zone-offset date)] - [hours (quotient delta 3600)] - [minutes (modulo (quotient delta 60) 60)]) - (list - (if (negative? delta) "-" "+") - (add-zero (abs hours)) - (add-zero minutes)))))] - [else (error 'date->string "unknown date-display-format: ~s" - (date-display-format))])) - (apply string-append - (if time? - (append day-strs time-strs) - day-strs))) - -(define (leap-year? year) - (or (= 0 (modulo year 400)) - (and (= 0 (modulo year 4)) - (not (= 0 (modulo year 100)))))) - -;; it's not clear what months mean in this context -- use days -(define-struct date-offset (second minute hour day year)) - -(define (fixup s x) (if (< s 0) (+ s x) s)) -(define (date- date1 date2) - (define second (- (date-second date1) (date-second date2))) - (define minute - (+ (- (date-minute date1) (date-minute date2)) - (if (< second 0) -1 0))) - (define hour - (+ (- (date-hour date1) (date-hour date2)) - (if (< minute 0) -1 0) - (cond [(equal? (date-dst? date1) (date-dst? date2)) 0] - [(date-dst? date1) -1] - [(date-dst? date2) 1]))) - (define day - (+ (- (date-year-day date1) (date-year-day date2)) - (if (< hour 0) -1 0))) - (define year - (+ (- (date-year date1) (date-year date2)) - (if (< day 0) -1 0))) - (make-date-offset - (fixup second 60) - (fixup minute 60) - (fixup hour 24) - (fixup day (if (leap-year? (date-year date1)) 366 365)) - year)) - -(define (one-entry b) - (string-append - (number->string (first b)) - " " - (second b) - (if (= 1 (first b)) "" "s"))) -(define (date-offset->string date [seconds? #f]) - (define fields - (list (list (date-offset-year date) "year") - (list (date-offset-day date) "day") - (list (date-offset-hour date) "hour") - (list (date-offset-minute date) "minute") - (list (if seconds? (date-offset-second date) 0) "second"))) - (define non-zero-fields - (filter (negate (compose (curry = 0) first)) fields)) - (match non-zero-fields - [(list) ""] - [(list one) (one-entry one)] - [_ - (for/fold ([string ""]) - ([b (in-list non-zero-fields)]) - (cond - [(= 0 (first b)) string] - [(string=? string "") - (string-append "and " - (one-entry b) - string)] - [else (string-append (one-entry b) ", " string)]))])) - -(define (days-per-month year month) - (cond - [(and (= month 2) (leap-year? year)) 29] - [(= month 2) 28] - [(<= month 7) (+ 30 (modulo month 2))] - [else (+ 30 (- 1 (modulo month 2)))])) - -(define (find-extreme-date-seconds start offset) - (let/ec found - (letrec ([find-between - (lambda (lo hi) - (let ([mid (floor (/ (+ lo hi) 2))]) - (if (or (and (positive? offset) (= lo mid)) - (and (negative? offset) (= hi mid))) - (found lo) - (let ([mid-ok? - (with-handlers ([exn:fail? (lambda (exn) #f)]) - (seconds->date mid) - #t)]) - (if mid-ok? - (find-between mid hi) - (find-between lo mid))))))]) - (let loop ([lo start][offset offset]) - (let ([hi (+ lo offset)]) - (with-handlers ([exn:fail? - (lambda (exn) - ; failed - must be between lo & hi - (find-between lo hi))]) - (seconds->date hi)) - ; succeeded; double offset again - (loop hi (* 2 offset))))))) - -(define get-min-seconds - (let ([d (delay (find-extreme-date-seconds (current-seconds) -1))]) - (lambda () - (force d)))) -(define get-max-seconds - (let ([d (delay (find-extreme-date-seconds (current-seconds) 1))]) - (lambda () - (force d)))) - -(define (date->seconds date [local-time? #t]) - (find-seconds - (date-second date) - (date-minute date) - (date-hour date) - (date-day date) - (date-month date) - (date-year date) - local-time?)) - -(define (find-seconds sec min hour day month year [local-time? #t]) - (define (signal-error msg) - (error 'find-secs (string-append - msg - " (inputs: ~a ~a ~a ~a ~a ~a)") - sec min hour day month year)) - (let loop ([below-secs (get-min-seconds)] - [secs (floor (/ (+ (get-min-seconds) (get-max-seconds)) 2))] - [above-secs (get-max-seconds)]) - (let* ([date (seconds->date secs local-time?)] - [compare - (let loop ([inputs (list year month day - hour min sec)] - [tests (list (date-year date) - (date-month date) - (date-day date) - (date-hour date) - (date-minute date) - (date-second date))]) - (cond - [(null? inputs) 'equal] - [else (let ([input (car inputs)] - [test (car tests)]) - (if (= input test) - (loop (cdr inputs) (cdr tests)) - (if (<= input test) - 'input-smaller - 'test-smaller)))]))]) - ; (printf "~a ~a ~a\n" compare secs (date->string date)) - (cond - [(eq? compare 'equal) secs] - [(or (= secs below-secs) (= secs above-secs)) - (signal-error "non-existent date")] - [(eq? compare 'input-smaller) - (loop below-secs (floor (/ (+ secs below-secs) 2)) secs)] - [(eq? compare 'test-smaller) - (loop secs (floor (/ (+ above-secs secs) 2)) above-secs)])))) - -;; date->julian/scalinger : -;; date -> number [julian-day] - -;; Note: This code is correct until 2099 CE Gregorian - -(define (date->julian/scalinger date) - (define day (date-day date)) - (define month (date-month date)) - (define d-year (date-year date)) - (define year (+ 4712 d-year)) - (define adj-year (if (< month 3) (sub1 year) year)) - (define cycle-number (quotient adj-year 4)) - (define cycle-position (remainder adj-year 4)) - (define base-day (+ (* 1461 cycle-number) (* 365 cycle-position))) - (define month-day-number - (case month - ((3) 0) - ((4) 31) - ((5) 61) - ((6) 92) - ((7) 122) - ((8) 153) - ((9) 184) - ((10) 214) - ((11) 245) - ((12) 275) - ((1) 306) - ((2) 337))) - (define total-days (+ base-day month-day-number day)) - (define total-days/march-adjustment (+ total-days 59)) - (define gregorian-adjustment - (cond - ((< adj-year 1700) 11) - ((< adj-year 1800) 12) - (else 13))) - (define final-date - (- total-days/march-adjustment - gregorian-adjustment)) - final-date) - -;; julian/scalinger->string : -;; number [julian-day] -> string [julian-day-format] - -(define (julian/scalinger->string julian-day) - (apply string-append - (cons "JD " - (reverse - (let loop ((reversed-digits (map number->string - (let loop ((jd julian-day)) - (if (zero? jd) null - (cons (remainder jd 10) - (loop (quotient jd 10)))))))) - (cond - ((or (null? reversed-digits) - (null? (cdr reversed-digits)) - (null? (cdr (cdr reversed-digits))) - (null? (cdr (cdr (cdr reversed-digits))))) - (list (apply string-append (reverse reversed-digits)))) - (else (cons (apply string-append - (list " " - (caddr reversed-digits) - (cadr reversed-digits) - (car reversed-digits))) - (loop (cdr (cdr (cdr reversed-digits)))))))))))) +(module date racket/base + (require mzlib/date) + (provide (all-from-out mzlib/date))) diff --git a/collects/racket/place.rkt b/collects/racket/place.rkt index 3bd93d60ce..8ef59178f9 100644 --- a/collects/racket/place.rkt +++ b/collects/racket/place.rkt @@ -9,7 +9,7 @@ racket/vector racket/place/private/th-place racket/place/private/prop - racket/private/streams + mzlib/private/streams unstable/lazy-require diff --git a/collects/racket/port.rkt b/collects/racket/port.rkt index 6b50ac0c99..9496e2553b 100644 --- a/collects/racket/port.rkt +++ b/collects/racket/port.rkt @@ -1,13 +1,10 @@ #lang racket/base -;; Additional I/O functions for Racket - -(require (for-syntax racket/base) - racket/contract/base - "private/port.rkt" +(require mzlib/port "private/portlines.rkt") - -(provide port->string +(provide (except-out (all-from-out mzlib/port) + strip-shell-command-start) + port->string port->bytes port->lines port->bytes-lines @@ -22,66 +19,7 @@ with-input-from-string with-input-from-bytes call-with-input-string - call-with-input-bytes - - ;; `mzlib/port` exports - open-output-nowhere - make-pipe-with-specials - make-input-port/read-to-peek - peeking-input-port - relocate-input-port - transplant-input-port - filter-read-input-port - special-filter-input-port - relocate-output-port - transplant-output-port - merge-input - copy-port - input-port-append - convert-stream - make-limited-input-port - reencode-input-port - reencode-output-port - dup-input-port - dup-output-port - - (contract-out - [read-bytes-avail!-evt (mutable-bytes? input-port-with-progress-evts? - . -> . evt?)] - [peek-bytes-avail!-evt (mutable-bytes? exact-nonnegative-integer? evt?/false - input-port-with-progress-evts? - . -> . evt?)] - [read-bytes!-evt (mutable-bytes? input-port-with-progress-evts? . -> . evt?)] - [peek-bytes!-evt (mutable-bytes? exact-nonnegative-integer? evt?/false - input-port-with-progress-evts? - . -> . evt?)] - [read-bytes-evt (exact-nonnegative-integer? input-port-with-progress-evts? - . -> . evt?)] - [peek-bytes-evt (exact-nonnegative-integer? exact-nonnegative-integer? - evt?/false input-port-with-progress-evts? - . -> . evt?)] - [read-string!-evt (mutable-string? input-port-with-progress-evts? - . -> . evt?)] - [peek-string!-evt (mutable-string? exact-nonnegative-integer? evt?/false - input-port-with-progress-evts? - . -> . evt?)] - [read-string-evt (exact-nonnegative-integer? input-port-with-progress-evts? - . -> . evt?)] - [peek-string-evt (exact-nonnegative-integer? exact-nonnegative-integer? - evt?/false input-port-with-progress-evts? - . -> . evt?)] - [regexp-match-evt ((or/c regexp? byte-regexp? string? bytes?) - input-port-with-progress-evts? - . -> . evt?)] - [read-bytes-line-evt (case-> (input-port-with-progress-evts? . -> . evt?) - (input-port-with-progress-evts? line-mode-symbol? - . -> . evt?))] - [read-line-evt (case-> (input-port-with-progress-evts? . -> . evt?) - (input-port-with-progress-evts? line-mode-symbol? - . -> . evt?))] - [eof-evt (input-port-with-progress-evts? . -> . evt?)])) - -;; ---------------------------------------- + call-with-input-bytes) (define (port->string-port who p) (unless (input-port? p) (raise-argument-error who "input-port?" p)) @@ -156,1782 +94,3 @@ (define (call-with-input-bytes str proc) (with-input-from-x 'call-with-input-bytes 1 #t str proc)) - -;; ---------------------------------------- -;; the code below used to be in `mzlib/port` - -(define (input-port-with-progress-evts? ip) - (and (input-port? ip) - (port-provides-progress-evts? ip))) - -(define (mutable-bytes? b) - (and (bytes? b) (not (immutable? b)))) -(define (mutable-string? b) - (and (string? b) (not (immutable? b)))) - -(define (line-mode-symbol? s) - (memq s '(linefeed return return-linefeed any any-one))) - -(define (evt?/false v) - (or (eq? #f v) (evt? v))) - -;; ---------------------------------------- - -(define merge-input - (case-lambda - [(a b) (merge-input a b 4096)] - [(a b limit) - (or (input-port? a) - (raise-argument-error 'merge-input "input-port?" a)) - (or (input-port? b) - (raise-argument-error 'merge-input "input-port?" b)) - (or (not limit) - (and (number? limit) (positive? limit) (exact? limit) (integer? limit)) - (raise-argument-error 'merge-input "(or/c exact-positive-integer #f)" limit)) - (let-values ([(rd wt) (make-pipe-with-specials limit)] - [(other-done?) #f] - [(sema) (make-semaphore 1)]) - (let ([copy - (lambda (from) - (thread - (lambda () - (copy-port from wt) - (semaphore-wait sema) - (if other-done? - (close-output-port wt) - (set! other-done? #t)) - (semaphore-post sema))))]) - (copy a) - (copy b) - rd))])) - -;; `make-input-port/read-to-peek' sometimes needs to wrap a special-value -;; procedure so that it's only called once when the value is both -;; peeked and read. -(define-values (struct:memoized make-memoized memoized? memoized-ref memoized-set!) - (make-struct-type 'memoized #f 1 0 #f null (current-inspector) 0)) -(define (memoize p) - (define result #f) - (make-memoized - (if (procedure-arity-includes? p 0) - ;; original p accepts 0 or 4 arguments: - (case-lambda - [() (unless result (set! result (box (p)))) (unbox result)] - [(src line col pos) - (unless result (set! result (box (p src line col pos)))) - (unbox result)]) - ;; original p accepts only 4 arguments: - (lambda (src line col pos) - (unless result (set! result (box (p src line col pos)))) - (unbox result))))) - -;; Not kill-safe. -;; If the `read' proc returns an event, the event must produce -;; 0 always (which implies that the `read' proc must not return -;; a pipe input port). -(define make-input-port/read-to-peek - (lambda (name read fast-peek close - [location-proc #f] - [count-lines!-proc void] - [init-position 1] - [buffer-mode-proc #f] - [buffering? #f] - [on-consumed #f]) - (define lock-semaphore (make-semaphore 1)) - (define commit-semaphore (make-semaphore 1)) - (define-values (peeked-r peeked-w) (make-pipe)) - (define special-peeked null) - (define special-peeked-tail #f) - (define progress-requested? #f) - (define line-counting? #f) - (define use-manager? #f) - (define manager-th #f) - (define manager-ch (make-channel)) - (define resume-ch (make-channel)) - (define buf (make-bytes 4096)) - (define (try-again) - (wrap-evt - (semaphore-peek-evt lock-semaphore) - (lambda (x) 0))) - (define (suspend-manager) - (channel-put manager-ch 'suspend)) - (define (resume-manager) - (channel-put resume-ch 'resume)) - (define (with-manager-lock thunk) - (thread-resume manager-th (current-thread)) - (dynamic-wind suspend-manager thunk resume-manager)) - (define (make-progress) - ;; We dont worry about this byte getting picked up directly - ;; from peeked-r, because the pipe must have been empty when - ;; we grabed the lock, and since we've grabbed the lock, - ;; no other thread could have re-returned the pipe behind - ;; our back. - (write-byte 0 peeked-w) - (read-byte peeked-r)) - (define (consume-from-peeked s) - (let ([n (read-bytes-avail!* s peeked-r)]) - (when on-consumed (on-consumed n)) - n)) - (define (read-it-with-lock s) - (if use-manager? - (with-manager-lock (lambda () (do-read-it s))) - (do-read-it s))) - (define (read-it s) - (call-with-semaphore lock-semaphore read-it-with-lock try-again s)) - (define (do-read-it s) - (if (byte-ready? peeked-r) - (if on-consumed (consume-from-peeked s) peeked-r) - ;; If nothing is saved from a peeking read, dispatch to - ;; `read', otherwise return previously peeked data - (cond - [(null? special-peeked) - (when progress-requested? (make-progress)) - (if (and buffering? ((bytes-length s) . < . 10)) - ;; Buffering is enabled, so read more to move things - ;; along: - (let ([r (read buf)]) - (if (and (number? r) (positive? r)) - (begin (write-bytes buf peeked-w 0 r) - (if on-consumed (consume-from-peeked s) peeked-r)) - (begin (when on-consumed (on-consumed r)) - r))) - ;; Just read requested amount: - (let ([v (read s)]) - (when on-consumed (on-consumed v)) - v))] - [else (if (bytes? (mcar special-peeked)) - (let ([b (mcar special-peeked)]) - (write-bytes b peeked-w) - (set! special-peeked (mcdr special-peeked)) - (when (null? special-peeked) (set! special-peeked-tail #f)) - (consume-from-peeked s)) - (let ([v (mcar special-peeked)]) - (make-progress) - (set! special-peeked (mcdr special-peeked)) - (when on-consumed (on-consumed v)) - (when (null? special-peeked) (set! special-peeked-tail #f)) - v))]))) - (define (peek-it-with-lock s skip unless-evt) - (if use-manager? - (with-manager-lock (lambda () (do-peek-it s skip unless-evt))) - (do-peek-it s skip unless-evt))) - (define (peek-it s skip unless-evt) - (let ([v (peek-bytes-avail!* s skip unless-evt peeked-r)]) - (if (eq? v 0) - (call-with-semaphore lock-semaphore - peek-it-with-lock try-again s skip unless-evt) - v))) - (define (do-peek-it s skip unless-evt) - (let ([v (peek-bytes-avail!* s skip unless-evt peeked-r)]) - (if (eq? v 0) - ;; The peek may have failed because peeked-r is empty, - ;; because unless-evt is ready, or because the skip is - ;; far. Handle nicely the common case where there are no - ;; specials. - (cond - [(and unless-evt (sync/timeout 0 unless-evt)) - #f] - [(null? special-peeked) - ;; Empty special queue, so read through the original proc. - ;; We only only need - ;; (- (+ skip (bytes-length s)) (pipe-content-length peeked-w)) - ;; bytes, but if buffering is enabled, read more (up to size of - ;; buf) to help move things along. - (let* ([dest (if buffering? - buf - (make-bytes (- (+ skip (bytes-length s)) - (pipe-content-length peeked-w))))] - [r (read dest)]) - (cond - [(number? r) - ;; The nice case --- reading gave us more bytes - (write-bytes dest peeked-w 0 r) - ;; Now try again - (peek-bytes-avail!* s skip #f peeked-r)] - [(evt? r) - (if unless-evt - ;; Technically, there's a race condition here. - ;; We might choose r (and return 0) even when - ;; unless-evt becomes available first. However, - ;; this race is detectable only by the inside - ;; of `read'. - (choice-evt r (wrap-evt unless-evt (lambda (x) #f))) - r)] - [else - (set! special-peeked (mcons r null)) - (set! special-peeked-tail special-peeked) - ;; Now try again - (do-peek-it s skip unless-evt)]))] - [else - ;; Non-empty special queue, so try to use it - (let* ([avail (pipe-content-length peeked-r)] - [sk (- skip avail)]) - (let loop ([sk sk] [l special-peeked]) - (cond - [(null? l) - ;; Not enough even in the special queue. - ;; Read once and add it. - (let* ([t (make-bytes (min 4096 (+ sk (bytes-length s))))] - [r (read t)]) - (cond - [(evt? r) - (if unless-evt - ;; See note above - (choice-evt r (wrap-evt unless-evt (lambda (x) #f))) - r)] - [(eq? r 0) - ;; Original read thinks a spin is ok, - ;; so we return 0 to skin, too. - 0] - [else (let ([v (if (number? r) - (subbytes t 0 r) - r)]) - (let ([pr (mcons v null)]) - (set-mcdr! special-peeked-tail pr) - (set! special-peeked-tail pr)) - ;; Got something; now try again - (do-peek-it s skip unless-evt))]))] - [(eof-object? (mcar l)) - ;; No peeking past an EOF - eof] - [(procedure? (mcar l)) - (if (zero? sk) - ;; We should call the procedure only once. Change - ;; (mcar l) to a memoizing function, if it isn't already: - (let ([proc (mcar l)]) - (if (memoized? proc) - proc - (let ([proc (memoize proc)]) - (set-mcar! l proc) - proc))) - ;; Skipping over special... - (loop (sub1 sk) (mcdr l)))] - [(bytes? (mcar l)) - (let ([len (bytes-length (mcar l))]) - (if (sk . < . len) - (let ([n (min (bytes-length s) - (- len sk))]) - (bytes-copy! s 0 (mcar l) sk (+ sk n)) - n) - (loop (- sk len) (mcdr l))))])))]) - v))) - (define (commit-it-with-lock amt unless-evt done-evt) - (if use-manager? - (with-manager-lock (lambda () (do-commit-it amt unless-evt done-evt))) - (do-commit-it amt unless-evt done-evt))) - (define (commit-it amt unless-evt done-evt) - (call-with-semaphore lock-semaphore - commit-it-with-lock #f amt unless-evt done-evt)) - (define (do-commit-it amt unless-evt done-evt) - (if (sync/timeout 0 unless-evt) - #f - (let* ([avail (pipe-content-length peeked-r)] - [p-commit (min avail amt)]) - (let loop ([amt (- amt p-commit)] - [l special-peeked] - ;; result is either bytes (if needed for line ounting) - ;; or an integer count (for on-consumed) - [result (if line-counting? null 0)]) - (cond - [(amt . <= . 0) - ;; Enough has been peeked. Do commit... - (actual-commit p-commit l unless-evt done-evt result)] - [(null? l) - ;; Requested commit was larger than previous peeks - #f] - [(bytes? (mcar l)) - (let ([bl (bytes-length (mcar l))]) - (if (bl . > . amt) - ;; Split the string - (let ([next (mcons (subbytes (mcar l) amt) (mcdr l))]) - (set-mcar! l (subbytes (mcar l) 0 amt)) - (set-mcdr! l next) - (when (eq? l special-peeked-tail) - (set! special-peeked-tail next)) - (loop 0 (mcdr l) (if line-counting? - (cons (subbytes (mcar l) 0 amt) result) - (+ amt result)))) - ;; Consume this string... - (loop (- amt bl) (mcdr l) (if line-counting? - (cons (mcar l) result) - (+ bl result)))))] - [else - (loop (sub1 amt) (mcdr l) (if line-counting? - (cons #"." result) - (add1 result)))]))))) - (define (actual-commit p-commit l unless-evt done-evt result) - ;; The `finish' proc finally, actually, will commit... - (define (finish) - (let ([result (if line-counting? - (cons (peek-bytes p-commit 0 peeked-r) result) - (+ p-commit result))]) - (unless (zero? p-commit) - (peek-byte peeked-r (sub1 p-commit)) - (port-commit-peeked p-commit unless-evt always-evt peeked-r)) - (set! special-peeked l) - (when (null? special-peeked) (set! special-peeked-tail #f)) - (when (and progress-requested? (zero? p-commit)) (make-progress)) - (if line-counting? - ;; bytes representation of committed text allows line counting - ;; to be updated correctly (when line counting is implemented - ;; automatically) - (let ([bstr (apply bytes-append (reverse result))]) - (when on-consumed (on-consumed (bytes-length bstr))) - bstr) - (begin - (when on-consumed (on-consumed result)) - #t)))) - ;; If we can sync done-evt immediately, then finish. - (if (sync/timeout 0 (wrap-evt done-evt (lambda (x) #t))) - (finish) - ;; We need to wait, so we'll have to release the lock. - ;; Send the work to a manager thread. - (let ([result-ch (make-channel)] - [w/manager? use-manager?]) - (if w/manager? - ;; Resume manager if it was running: - (resume-manager) - ;; Start manager if it wasn't running: - (begin (set! manager-th (thread manage-commits)) - (set! use-manager? #t) - (thread-resume manager-th (current-thread)))) - ;; Sets use-manager? if the manager wasn't already running: - (channel-put manager-ch (list finish unless-evt done-evt result-ch)) - ;; Release locks: - (semaphore-post lock-semaphore) - (begin0 ;; Wait for manager to complete commit: - (sync result-ch) - ;; Grab locks again, so they're released - ;; properly on exit: - (semaphore-wait lock-semaphore) - (when w/manager? (suspend-manager)))))) - (define (manage-commits) - (let loop ([commits null]) - (apply - sync - (handle-evt manager-ch - (lambda (c) - (case c - [(suspend) - (channel-get resume-ch) - (loop commits)] - [else - ;; adding a commit - (loop (cons c commits))]))) - (map (lambda (c) - (define (send-result v) - ;; Create a new thread to send the result asynchronously: - (thread-resume - (thread (lambda () (channel-put (list-ref c 3) v))) - (current-thread)) - (when (null? (cdr commits)) - (set! use-manager? #f)) - (loop (remq c commits))) - ;; Choose between done and unless: - (if (sync/timeout 0 (list-ref c 1)) - (handle-evt always-evt (lambda (x) (send-result #f))) - (choice-evt - (handle-evt (list-ref c 1) - (lambda (x) - ;; unless ready, which means that the commit must fail - (send-result #f))) - (handle-evt (list-ref c 2) - (lambda (x) - ;; done-evt ready, which means that the commit - ;; must succeed. - ;; If we get here, then commits are not - ;; suspended, so we implicitly have the - ;; lock. - ((list-ref c 0)) - (send-result #t)))))) - commits)))) - (make-input-port - name - ;; Read - read-it - ;; Peek - (if fast-peek - (let ([fast-peek-k (lambda (s skip) (peek-it s skip #f))]) - (lambda (s skip unless-evt) - (if (or unless-evt - (byte-ready? peeked-r) - (mpair? special-peeked)) - (peek-it s skip unless-evt) - (fast-peek s skip fast-peek-k)))) - peek-it) - close - (lambda () - (set! progress-requested? #t) - (port-progress-evt peeked-r)) - commit-it - location-proc - (lambda () - (set! line-counting? #t) - (count-lines!-proc)) - init-position - (and buffer-mode-proc - (case-lambda - [() (buffer-mode-proc)] - [(mode) - (set! buffering? (eq? mode 'block)) - (buffer-mode-proc mode)]))))) - -(define (peeking-input-port orig-in - [name (object-name orig-in)] - [delta 0] - #:init-position [init-position 1]) - (make-input-port/read-to-peek - name - (lambda (s) - (let ([r (peek-bytes-avail!* s delta #f orig-in)]) - (set! delta (+ delta (if (number? r) r 1))) - (if (eq? r 0) (wrap-evt orig-in (lambda (v) 0)) r))) - (lambda (s skip default) - (peek-bytes-avail!* s (+ delta skip) #f orig-in)) - void - #f - void - init-position)) - -(define relocate-input-port - (lambda (p line col pos [close? #t]) - (transplant-to-relocate transplant-input-port p line col pos close?))) - -(define transplant-input-port - (lambda (p location-proc pos [close? #t] [count-lines!-proc void]) - (make-input-port - (object-name p) - (lambda (s) - (let ([v (read-bytes-avail!* s p)]) - (if (eq? v 0) (wrap-evt p (lambda (x) 0)) v))) - (lambda (s skip evt) - (let ([v (peek-bytes-avail!* s skip evt p)]) - (if (eq? v 0) - (choice-evt - (wrap-evt p (lambda (x) 0)) - (if evt (wrap-evt evt (lambda (x) #f)) never-evt)) - v))) - (lambda () - (when close? (close-input-port p))) - (and (port-provides-progress-evts? p) - (lambda () (port-progress-evt p))) - (and (port-provides-progress-evts? p) - (lambda (n evt target-evt) (port-commit-peeked n evt target-evt p))) - location-proc - count-lines!-proc - pos))) - -(define filter-read-input-port - (lambda (p wrap-read wrap-peek [close? #t]) - (make-input-port - (object-name p) - (lambda (s) - (let ([v (read-bytes-avail!* s p)]) - (wrap-read - s - (if (eq? v 0) (wrap-evt p (lambda (x) 0)) v)))) - (lambda (s skip evt) - (let ([v (peek-bytes-avail!* s skip evt p)]) - (wrap-peek - s skip evt - (if (eq? v 0) - (choice-evt - (wrap-evt p (lambda (x) 0)) - (if evt (wrap-evt evt (lambda (x) #f)) never-evt)) - v)))) - (lambda () - (when close? (close-input-port p))) - (and (port-provides-progress-evts? p) - (lambda () (port-progress-evt p))) - (and (port-provides-progress-evts? p) - (lambda (n evt target-evt) (port-commit-peeked n evt target-evt p))) - (lambda () (port-next-location p)) - (lambda () (port-count-lines! p)) - (add1 (file-position p))))) - -;; Not kill-safe. -(define make-pipe-with-specials - ;; This implementation of pipes is almost CML-style, with a manager thread - ;; to guard access to the pipe content. But we only enable the manager - ;; thread when write evts are active; otherwise, we use a lock semaphore. - ;; (Actually, the lock semaphore has to be used all the time, to guard - ;; the flag indicating whether the manager thread is running.) - (lambda ([limit (expt 2 64)] [in-name 'pipe] [out-name 'pipe]) - (let-values ([(r w) (make-pipe limit)] - [(more) null] - [(more-last) #f] - [(more-sema) #f] - [(close-w?) #f] - [(lock-semaphore) (make-semaphore 1)] - [(mgr-th) #f] - [(via-manager?) #f] - [(mgr-ch) (make-channel)]) - (define (flush-more) - (if (null? more) - (begin (set! more-last #f) - (when close-w? (close-output-port w))) - (when (bytes? (mcar more)) - (let ([amt (bytes-length (mcar more))]) - (let ([wrote (write-bytes-avail* (mcar more) w)]) - (if (= wrote amt) - (begin (set! more (mcdr more)) - (flush-more)) - (begin - ;; This means that we let too many bytes - ;; get written while a special was pending. - ;; (The limit is disabled when a special - ;; is in the pipe.) - (set-mcar! more (subbytes (mcar more) wrote)) - ;; By peeking, make room for more: - (peek-byte r (sub1 (min (pipe-content-length w) - (- amt wrote)))) - (flush-more)))))))) - (define (read-one s) - (let ([v (read-bytes-avail!* s r)]) - (if (eq? v 0) - (if more-last - ;; Return a special - (let ([a (mcar more)]) - (set! more (mcdr more)) - (flush-more) - (lambda (file line col ppos) a)) - ;; Nothing available, yet. - (begin (unless more-sema (set! more-sema (make-semaphore))) - (wrap-evt (semaphore-peek-evt more-sema) - (lambda (x) 0)))) - v))) - (define (close-it) - (set! close-w? #t) - (unless more-last (close-output-port w)) - (when more-sema (semaphore-post more-sema))) - (define (write-these-bytes str start end) - (begin0 (if more-last - (let ([p (mcons (subbytes str start end) null)]) - (set-mcdr! more-last p) - (set! more-last p) - (- end start)) - (let ([v (write-bytes-avail* str w start end)]) - (if (zero? v) (wrap-evt w (lambda (x) #f)) v))) - (when more-sema - (semaphore-post more-sema) - (set! more-sema #f)))) - (define (write-spec v) - (let ([p (mcons v null)]) - (if more-last (set-mcdr! more-last p) (set! more p)) - (set! more-last p) - (when more-sema - (semaphore-post more-sema) - (set! more-sema #f)))) - (define (serve) - ;; A request is - ;; (list sym result-ch nack-evt . v) - ;; where `v' varies for different `sym's - ;; The possible syms are: read, reply, close, - ;; write, write-spec, write-evt, write-spec-evt - (let loop ([reqs null]) - (apply - sync - ;; Listen for a request: - (handle-evt - mgr-ch - (lambda (req) - (let ([req - ;; Most requests we handle immediately and - ;; convert to a reply. The manager thread - ;; implicitly has the lock. - (let ([reply (lambda (v) - (list 'reply (cadr req) (caddr req) v))]) - (case (car req) - [(read) - (reply (read-one (cadddr req)))] - [(close) - (reply (close-it))] - [(write) - (reply (apply write-these-bytes (cdddr req)))] - [(write-spec) - (reply (write-spec (cadddr req)))] - [else req]))]) - (loop (cons req reqs))))) - (if (and (null? reqs) via-manager?) - ;; If we can get the lock before another request - ;; turn off manager mode: - (handle-evt lock-semaphore - (lambda (x) - (set! via-manager? #f) - (semaphore-post lock-semaphore) - (loop null))) - never-evt) - (append - (map (lambda (req) - (case (car req) - [(reply) - (handle-evt (channel-put-evt (cadr req) (cadddr req)) - (lambda (x) (loop (remq req reqs))))] - [(write-spec-evt) - (if close-w? - ;; Report close error: - (handle-evt (channel-put-evt (cadr req) 'closed) - (lambda (x) (loop (remq req reqs)))) - ;; Try to write special: - (handle-evt (channel-put-evt (cadr req) #t) - (lambda (x) - ;; We sync'd, so now we *must* write - (write-spec (cadddr req)) - (loop (remq req reqs)))))] - [(write-evt) - (if close-w? - ;; Report close error: - (handle-evt (channel-put-evt (cadr req) 'closed) - (lambda (x) (loop (remq req reqs)))) - ;; Try to write bytes: - (let* ([start (list-ref req 4)] - [end (list-ref req 5)] - [len (if more-last - (- end start) - (min (- end start) - (max 0 - (- limit (pipe-content-length w)))))]) - (if (and (zero? len) (null? more)) - (handle-evt w (lambda (x) (loop reqs))) - (handle-evt - (channel-put-evt (cadr req) len) - (lambda (x) - ;; We sync'd, so now we *must* write - (write-these-bytes (cadddr req) start (+ start len)) - (loop (remq req reqs)))))))])) - reqs) - ;; nack => remove request (could be anything) - (map (lambda (req) - (handle-evt (caddr req) - (lambda (x) (loop (remq req reqs))))) - reqs))))) - (define (via-manager what req-sfx) - (thread-resume mgr-th (current-thread)) - (let ([ch (make-channel)]) - (sync (nack-guard-evt - (lambda (nack) - (channel-put mgr-ch (list* what ch nack req-sfx)) - ch))))) - (define (start-mgr) - (unless mgr-th (set! mgr-th (thread serve))) - (set! via-manager? #t)) - (define (evt what req-sfx) - (nack-guard-evt - (lambda (nack) - (resume-mgr) - (let ([ch (make-channel)]) - (call-with-semaphore - lock-semaphore - (lambda () - (unless mgr-th (set! mgr-th (thread serve))) - (set! via-manager? #t) - (thread-resume mgr-th (current-thread)) - (channel-put mgr-ch (list* what ch nack req-sfx)) - (wrap-evt ch (lambda (x) - (if (eq? x 'close) - (raise-mismatch-error 'write-evt "port is closed: " out) - x))))))))) - (define (resume-mgr) - (when mgr-th (thread-resume mgr-th (current-thread)))) - (define in - ;; ----- Input ------ - (make-input-port/read-to-peek - in-name - (lambda (s) - (let ([v (read-bytes-avail!* s r)]) - (if (eq? v 0) - (begin (resume-mgr) - (call-with-semaphore - lock-semaphore - (lambda () - (if via-manager? - (via-manager 'read (list s)) - (read-one s))))) - v))) - #f - void)) - (define out - ;; ----- Output ------ - (make-output-port - out-name - w - ;; write - (lambda (str start end buffer? w/break?) - (if (= start end) - 0 - (begin - (resume-mgr) - (call-with-semaphore - lock-semaphore - (lambda () - (if via-manager? - (via-manager 'write (list str start end)) - (write-these-bytes str start end))))))) - ;; close - (lambda () - (resume-mgr) - (call-with-semaphore - lock-semaphore - (lambda () - (if via-manager? (via-manager 'close null) (close-it))))) - ;; write-special - (lambda (v buffer? w/break?) - (resume-mgr) - (call-with-semaphore - lock-semaphore - (lambda () - (if via-manager? - (via-manager 'write-spec (list v)) - (write-spec v))))) - ;; write-evt - (lambda (str start end) - (if (= start end) - (wrap-evt always-evt (lambda (x) 0)) - (evt 'write-evt (list str start end)))) - ;; write-special-evt - (lambda (v) - (evt 'write-spec-evt (list v))))) - (values in out)))) - -(define input-port-append - (lambda (close-orig? . ports) - (make-input-port - (map object-name ports) - (lambda (str) - ;; Reading is easy -- read from the first port, - ;; and get rid of it if the result is eof - (if (null? ports) - eof - (let ([n (read-bytes-avail!* str (car ports))]) - (cond - [(eq? n 0) (wrap-evt (car ports) (lambda (x) 0))] - [(eof-object? n) - (when close-orig? (close-input-port (car ports))) - (set! ports (cdr ports)) - 0] - [else n])))) - (lambda (str skip unless-evt) - ;; Peeking is more difficult, due to skips. - (let loop ([ports ports][skip skip]) - (if (null? ports) - eof - (let ([n (peek-bytes-avail!* str skip unless-evt (car ports))]) - (cond - [(eq? n 0) - ;; Not ready, yet. - (peek-bytes-avail!-evt str skip unless-evt (car ports))] - [(eof-object? n) - ;; Port is exhausted, or we skipped past its input. - ;; If skip is not zero, we need to figure out - ;; how many chars were skipped. - (loop (cdr ports) - (- skip (compute-avail-to-skip skip (car ports))))] - [else n]))))) - (lambda () - (when close-orig? - (map close-input-port ports)))))) - -(define (convert-stream from from-port to to-port) - (let ([c (bytes-open-converter from to)] - [in (make-bytes 4096)] - [out (make-bytes 4096)]) - (unless c - (error 'convert-stream "could not create converter from ~e to ~e" - from to)) - (dynamic-wind - void - (lambda () - (let loop ([got 0]) - (let ([n (read-bytes-avail! in from-port got)]) - (let ([got (+ got (if (number? n) n 0))]) - (let-values ([(wrote used status) (bytes-convert c in 0 got out)]) - (when (eq? status 'error) - (error 'convert-stream "conversion error")) - (unless (zero? wrote) - (write-bytes out to-port 0 wrote)) - (bytes-copy! in 0 in used got) - (if (not (number? n)) - (begin - (unless (= got used) - (error 'convert-stream - "input stream ~a with a partial conversion" - (if (eof-object? n) "ended" "hit a special value"))) - (let-values ([(wrote status) (bytes-convert-end c out)]) - (when (eq? status 'error) - (error 'convert-stream "conversion-end error")) - (unless (zero? wrote) - (write-bytes out to-port 0 wrote)) - (if (eof-object? n) - ;; Success - (void) - (begin (write-special n to-port) - (loop 0))))) - (loop (- got used)))))))) - (lambda () (bytes-close-converter c))))) - -;; Helper for input-port-append; given a skip count -;; and an input port, determine how many characters -;; (up to upto) are left in the port. We figure this -;; out using binary search. -(define (compute-avail-to-skip upto p) - (let ([str (make-bytes 1)]) - (let loop ([upto upto][skip 0]) - (if (zero? upto) - skip - (let* ([half (quotient upto 2)] - [n (peek-bytes-avail!* str (+ skip half) #f p)]) - (if (eq? n 1) - (loop (- upto half 1) (+ skip half 1)) - (loop half skip))))))) - -(define make-limited-input-port - (lambda (port limit [close-orig? #t]) - (let ([got 0] - [lock-semaphore (make-semaphore 1)]) - (define (do-read str) - (let ([count (min (- limit got) (bytes-length str))]) - (if (zero? count) - eof - (let ([n (read-bytes-avail!* str port 0 count)]) - (cond [(eq? n 0) (wrap-evt port (lambda (x) 0))] - [(number? n) (set! got (+ got n)) n] - [(procedure? n) (set! got (add1 got)) n] - [else n]))))) - (define (do-peek str skip progress-evt) - (let ([count (max 0 (min (- limit got skip) (bytes-length str)))]) - (if (zero? count) - eof - (let ([n (peek-bytes-avail!* str skip progress-evt port 0 count)]) - (if (eq? n 0) - (wrap-evt port (lambda (x) 0)) - n))))) - (define (try-again) - (wrap-evt - (semaphore-peek-evt lock-semaphore) - (lambda (x) 0))) - (make-input-port - (object-name port) - (lambda (str) - (call-with-semaphore - lock-semaphore - do-read - try-again - str)) - (lambda (str skip progress-evt) - (call-with-semaphore - lock-semaphore - do-peek - try-again - str skip progress-evt)) - (lambda () - (when close-orig? - (close-input-port port))) - (and (port-provides-progress-evts? port) - (lambda () (port-progress-evt port))) - (and (port-provides-progress-evts? port) - (lambda (n evt target-evt) - (let loop () - (if (semaphore-try-wait? lock-semaphore) - (let ([ok? (port-commit-peeked n evt target-evt port)]) - (when ok? (set! got (+ got n))) - (semaphore-post lock-semaphore) - ok?) - (sync (handle-evt evt (lambda (v) #f)) - (handle-evt (semaphore-peek-evt lock-semaphore) - (lambda (v) (loop)))))))) - (lambda () (port-next-location port)) - (lambda () (port-count-lines! port)) - (add1 (file-position port)))))) - -(define special-filter-input-port - (lambda (p filter [close? #t]) - (unless (input-port? p) - (raise-argument-error 'special-filter-input-port "input-port?" p)) - (unless (and (procedure? filter) - (procedure-arity-includes? filter 2)) - (raise-argument-error 'special-filter-input-port "(any/c bytes? . -> . any/c)" filter)) - (make-input-port - (object-name p) - (lambda (s) - (let ([v (read-bytes-avail!* s p)]) - (cond - [(eq? v 0) (wrap-evt p (lambda (x) 0))] - [(procedure? v) (filter v s)] - [else v]))) - (lambda (s skip evt) - (let ([v (peek-bytes-avail!* s skip evt p)]) - (cond - [(eq? v 0) - (choice-evt - (wrap-evt p (lambda (x) 0)) - (if evt (wrap-evt evt (lambda (x) #f)) never-evt))] - [(procedure? v) (filter v s)] - [else v]))) - (lambda () - (when close? (close-input-port p))) - (and (port-provides-progress-evts? p) - (lambda () (port-progress-evt p))) - (and (port-provides-progress-evts? p) - (lambda (n evt target-evt) (port-commit-peeked n evt target-evt p))) - (lambda () (port-next-location p)) - (lambda () (port-count-lines! p)) - (add1 (file-position p))))) - -;; ---------------------------------------- - -(define (poll-or-spawn go) - (poll-guard-evt - (lambda (poll?) - (if poll? - ;; In poll mode, call `go' directly: - (let ([v (go never-evt #f #t)]) - (if v (wrap-evt always-evt (lambda (x) v)) never-evt)) - ;; In non-poll mode, start a thread to call go - (nack-guard-evt - (lambda (nack) - (define ch (make-channel)) - (define ready (make-semaphore)) - (let ([t (thread (lambda () - (parameterize-break #t - (with-handlers ([exn:break? void]) - (semaphore-post ready) - (go nack ch #f)))))]) - (thread (lambda () - (sync nack) - (semaphore-wait ready) - (break-thread t)))) - ch)))))) - -(define (read-at-least-bytes!-evt orig-bstr input-port need-more? shrink combo - peek-offset prog-evt) - ;; go is the main reading function, either called directly for - ;; a poll, or called in a thread for a non-poll read - (define (go nack ch poll?) - (let try-again ([pos 0] [bstr orig-bstr] [progress-evt #f]) - (let* ([progress-evt - ;; if no progress event is given, get one to ensure that - ;; consecutive bytes are read and can be committed: - (or progress-evt prog-evt (port-progress-evt input-port))] - [v (and - ;; to implement weak support for reusing the buffer in `read-bytes!-evt', - ;; need to check nack after getting progress-evt: - (not (sync/timeout 0 nack)) - ;; try to get bytes: - ((if poll? peek-bytes-avail!* peek-bytes-avail!) - bstr (+ pos (or peek-offset 0)) progress-evt input-port pos))]) - (cond - ;; the first two cases below are shortcuts, and not - ;; strictly necessary - [(sync/timeout 0 nack) - (void)] - [(sync/timeout 0 progress-evt) - (cond [poll? #f] - [prog-evt (void)] - [else (try-again 0 bstr #f)])] - [(and poll? (equal? v 0)) #f] - [(and (number? v) (need-more? bstr (+ pos v))) - => (lambda (bstr) (try-again (+ v pos) bstr progress-evt))] - [else - (let* ([v2 (cond [(number? v) (shrink bstr (+ v pos))] - [(positive? pos) pos] - [else v])] - [result (combo bstr v2)]) - (cond - [peek-offset - (if poll? - result - (sync (or prog-evt never-evt) - (channel-put-evt ch result)))] - [(port-commit-peeked (if (number? v2) v2 1) - progress-evt - (if poll? - always-evt - (channel-put-evt ch result)) - input-port) - result] - [(and (eof-object? eof) - (zero? pos) - (not (sync/timeout 0 progress-evt))) - ;; Must be a true end-of-file - (let ([result (combo bstr eof)]) - (if poll? result (channel-put ch result)))] - [poll? #f] - [else (try-again 0 orig-bstr #f)]))])))) - (if (zero? (bytes-length orig-bstr)) - (wrap-evt always-evt (lambda (x) 0)) - (poll-or-spawn go))) - -(define (-read-bytes-avail!-evt bstr input-port peek-offset prog-evt) - (read-at-least-bytes!-evt bstr input-port - (lambda (bstr v) (if (zero? v) bstr #f)) - (lambda (bstr v) v) - (lambda (bstr v) v) - peek-offset prog-evt)) - -(define (read-bytes-avail!-evt bstr input-port) - (-read-bytes-avail!-evt bstr input-port #f #f)) - -(define (peek-bytes-avail!-evt bstr peek-offset prog-evt input-port) - (-read-bytes-avail!-evt bstr input-port peek-offset prog-evt)) - -(define (-read-bytes!-evt bstr input-port peek-offset prog-evt) - (read-at-least-bytes!-evt bstr input-port - (lambda (bstr v) - (if (v . < . (bytes-length bstr)) bstr #f)) - (lambda (bstr v) v) - (lambda (bstr v) v) - peek-offset prog-evt)) - -(define (read-bytes!-evt bstr input-port [progress-evt #f]) - (-read-bytes!-evt bstr input-port #f progress-evt)) - -(define (peek-bytes!-evt bstr peek-offset prog-evt input-port) - (-read-bytes!-evt bstr input-port peek-offset prog-evt)) - -(define (-read-bytes-evt len input-port peek-offset prog-evt) - (guard-evt - (lambda () - (let ([bstr (make-bytes len)]) - (wrap-evt - (-read-bytes!-evt bstr input-port peek-offset prog-evt) - (lambda (v) - (if (number? v) - (if (= v len) bstr (subbytes bstr 0 v)) - v))))))) - -(define (read-bytes-evt len input-port) - (-read-bytes-evt len input-port #f #f)) - -(define (peek-bytes-evt len peek-offset prog-evt input-port) - (-read-bytes-evt len input-port peek-offset prog-evt)) - -(define (-read-string-evt goal input-port peek-offset prog-evt) - (if (zero? goal) - (wrap-evt always-evt (lambda (x) "")) - (guard-evt - (lambda () - (let ([bstr (make-bytes goal)] - [c (bytes-open-converter "UTF-8-permissive" "UTF-8")]) - (wrap-evt - (read-at-least-bytes!-evt - bstr input-port - (lambda (bstr v) - (if (= v (bytes-length bstr)) - ;; We can't easily use bytes-utf-8-length here, - ;; because we may need more bytes to figure out - ;; the true role of the last byte. The - ;; `bytes-convert' function lets us deal with - ;; the last byte properly. - (let-values ([(bstr2 used status) - (bytes-convert c bstr 0 v)]) - (let ([got (bytes-utf-8-length bstr2)]) - (if (= got goal) - ;; Done: - #f - ;; Need more bytes: - (let ([bstr2 (make-bytes (+ v (- goal got)))]) - (bytes-copy! bstr2 0 bstr) - bstr2)))) - ;; Need more bytes in bstr: - bstr)) - (lambda (bstr v) - ;; We may need one less than v, - ;; because we may have had to peek - ;; an extra byte to discover an - ;; error in the stream. - (if ((bytes-utf-8-length bstr #\? 0 v) . > . goal) (sub1 v) v)) - cons - peek-offset prog-evt) - (lambda (bstr+v) - (let ([bstr (car bstr+v)] - [v (cdr bstr+v)]) - (if (number? v) - (bytes->string/utf-8 bstr #\? 0 v) - v))))))))) - -(define (read-string-evt goal input-port) - (-read-string-evt goal input-port #f #f)) - -(define (peek-string-evt goal peek-offset prog-evt input-port) - (-read-string-evt goal input-port peek-offset prog-evt)) - -(define (-read-string!-evt str input-port peek-offset prog-evt) - (wrap-evt - (-read-string-evt (string-length str) input-port peek-offset prog-evt) - (lambda (s) - (if (string? s) - (begin (string-copy! str 0 s) - (string-length s)) - s)))) - -(define (read-string!-evt str input-port) - (-read-string!-evt str input-port #f #f)) - -(define (peek-string!-evt str peek-offset prog-evt input-port) - (-read-string!-evt str input-port peek-offset prog-evt)) - -(define (regexp-match-evt pattern input-port) - (define (go nack ch poll?) - (let try-again () - (if (port-closed? input-port) - #f - (let* ([progress-evt (port-progress-evt input-port)] - [m ((if poll? - regexp-match-peek-positions-immediate - regexp-match-peek-positions) - pattern input-port 0 #f progress-evt)]) - (cond - [(sync/timeout 0 nack) (void)] - [(sync/timeout 0 progress-evt) (try-again)] - [(not m) - (if poll? - #f - (sync nack - (handle-evt progress-evt - (lambda (x) (try-again)))))] - [else - (let ([m2 (map (lambda (p) - (and p - (let ([bstr (make-bytes (- (cdr p) (car p)))]) - (unless (= (car p) (cdr p)) - (let loop ([offset 0]) - (let ([v (peek-bytes-avail! bstr (car p) progress-evt input-port offset)]) - (unless (zero? v) - (when ((+ offset v) . < . (bytes-length bstr)) - (loop (+ offset v))))))) - bstr))) - m)]) - (cond - [(and (zero? (cdar m)) (or poll? (channel-put ch m2))) - m2] - [(port-commit-peeked - (cdar m) - progress-evt - (if poll? always-evt (channel-put-evt ch m2)) - input-port) - m2] - [poll? #f] - [else (try-again)]))]))))) - (poll-or-spawn go)) - -(define-syntax (newline-rx stx) - (syntax-case stx () - [(_ str) - (datum->syntax - #'here - (byte-regexp (string->bytes/latin-1 - (format "^(?:(.*?)~a)|(.*?$)" (syntax-e #'str)))))])) - -(define read-bytes-line-evt - (lambda (input-port [mode 'linefeed]) - (wrap-evt - (regexp-match-evt (case mode - [(linefeed) (newline-rx "\n")] - [(return) (newline-rx "\r")] - [(return-linefeed) (newline-rx "\r\n")] - [(any) (newline-rx "(?:\r\n|\r|\n)")] - [(any-one) (newline-rx "[\r\n]")]) - input-port) - (lambda (m) - (or (cadr m) - (let ([l (caddr m)]) - (if (and l (zero? (bytes-length l))) eof l))))))) - -(define read-line-evt - (lambda (input-port [mode 'linefeed]) - (wrap-evt - (read-bytes-line-evt input-port mode) - (lambda (s) - (if (eof-object? s) s (bytes->string/utf-8 s #\?)))))) - -(define (eof-evt input-port) - (wrap-evt (regexp-match-evt #rx#"^$" input-port) - (lambda (x) eof))) - -;; -------------------------------------------------- - -;; Helper for reencode-input-port: simulate the composition -;; of a CRLF/CRNEL/NEL/LS -> LF decoding and some other -;; decoding. -;; The "converter" `c' is (mcons converter saved), where -;; saved is #f if no byte is saved, otherwise it's a saved -;; byte. It would be nicer and closer to the `bytes-convert' -;; interface to not consume a trailing CR, but we don't -;; know the inner encoding, and so we can't rewind it. -(define (bytes-convert/post-nl c buf buf-start buf-end dest) - (cond - [(and (mcdr c) (= buf-start buf-end)) - ;; No more bytes to convert; provide single - ;; saved byte if it's not #\return, otherwise report 'aborts - (if (eq? (mcdr c) (char->integer #\return)) - (values 0 0 'aborts) - (begin (bytes-set! dest 0 (mcdr c)) - (set-mcdr! c #f) - (values 1 0 'complete)))] - [(and (mcdr c) (= 1 (bytes-length dest))) - ;; We have a saved byte, but the destination is only 1 byte. - ;; If the saved byte is a return, we need to try decoding more, - ;; which means we may end up saving a non-#\return byte: - (if (eq? (mcdr c) (char->integer #\return)) - (let-values ([(got-c used-c status) - (bytes-convert (mcar c) buf buf-start buf-end dest)]) - (if (positive? got-c) - (cond - [(eq? (bytes-ref dest 0) (char->integer #\newline)) - ;; Found CRLF, so just produce LF (and nothing to save) - (set-mcdr! c #f) - (values 1 used-c status)] - [else - ;; Next char fits in a byte, so it isn't NEL, etc. - ;; Save it, and for now return the #\return. - (set-mcdr! c (bytes-ref dest 0)) - (bytes-set! dest 0 (char->integer #\newline)) - (values 1 used-c 'continues)]) - ;; Didn't decode any more; ask for bigger input, etc. - (values 0 0 status))) - ;; Saved a non-#\return, so use that up now. - (begin (bytes-set! dest 0 (mcdr c)) - (set-mcdr! c #f) - (values 1 0 'continues)))] - [else - ;; Normal convert, maybe prefixed: - (let-values ([(got-c used-c status) - (bytes-convert (mcar c) buf buf-start buf-end dest - (if (mcdr c) 1 0))]) - (let* ([got-c (if (mcdr c) - ;; Insert saved character: - (begin (bytes-set! dest 0 (char->integer #\return)) - (set-mcdr! c #f) - (add1 got-c)) - got-c)] - [got-c (if (and (positive? got-c) - (eq? (bytes-ref dest (sub1 got-c)) - (char->integer #\return)) - (not (eq? status 'error))) - ;; Save trailing carriage return: - (begin (set-mcdr! c (char->integer #\return)) - (sub1 got-c)) - got-c)]) - ;; Iterate through the converted bytes to apply the newline - ;; conversions: - (let loop ([i 0] [j 0]) - (cond - [(= i got-c) - (values (- got-c (- i j)) - used-c - (if (and (eq? 'complete status) (mcdr c)) - 'aborts - status))] - [(eq? (bytes-ref dest i) (char->integer #\return)) - (cond [(= (add1 i) got-c) - ;; Found lone CR: - (bytes-set! dest j (char->integer #\newline)) - (loop (add1 i) (add1 j))] - [(eq? (bytes-ref dest (add1 i)) (char->integer #\newline)) - ;; Found CRLF: - (bytes-set! dest j (char->integer #\newline)) - (loop (+ i 2) (add1 j))] - [(and (eq? (bytes-ref dest (add1 i)) #o302) - (eq? (bytes-ref dest (+ i 2)) #o205)) - ;; Found CRNEL: - (bytes-set! dest j (char->integer #\newline)) - (loop (+ i 3) (add1 j))] - [else - ;; Found lone CR: - (bytes-set! dest j (char->integer #\newline)) - (loop (add1 i) (add1 j))])] - [(and (eq? (bytes-ref dest i) #o302) - (eq? (bytes-ref dest (+ i 1)) #o205)) - ;; Found NEL: - (bytes-set! dest j (char->integer #\newline)) - (loop (+ i 2) (add1 j))] - [(and (eq? (bytes-ref dest i) #o342) - (eq? (bytes-ref dest (+ i 1)) #o200) - (eq? (bytes-ref dest (+ i 2)) #o250)) - ;; Found LS: - (bytes-set! dest j (char->integer #\newline)) - (loop (+ i 3) (add1 j))] - [else - ;; Anything else: - (unless (= i j) - (bytes-set! dest j (bytes-ref dest i))) - (loop (add1 i) (add1 j))]))))])) - -(define reencode-input-port - (lambda (port encoding [error-bytes #f] [close? #f] - [name (object-name port)] - [newline-convert? #f] - [decode-error (lambda (msg port) - (error 'reencode-input-port - (format "~a: ~~e" msg) - port))]) - (let ([c (let ([c (bytes-open-converter encoding "UTF-8")]) - (if newline-convert? (mcons c #f) c))] - [ready-bytes (make-bytes 1024)] - [ready-start 0] - [ready-end 0] - [buf (make-bytes 1024)] - [buf-start 0] - [buf-end 0] - [buf-eof? #f] - [buf-eof-result #f] - [buffer-mode (or (file-stream-buffer-mode port) 'none)]) - ;; Main reader entry: - (define (read-it s) - (cond - [(> ready-end ready-start) - ;; We have leftover converted bytes: - (let ([cnt (min (bytes-length s) (- ready-end ready-start))]) - (bytes-copy! s 0 ready-bytes ready-start (+ ready-start cnt)) - (set! ready-start (+ ready-start cnt)) - cnt)] - [else - ;; Try converting already-read bytes: - (let-values ([(got-c used-c status) - (if (= buf-start buf-end) - (values 0 0 'aborts) - ((if newline-convert? - bytes-convert/post-nl - bytes-convert) - c buf buf-start buf-end s))]) - (when (positive? used-c) (set! buf-start (+ used-c buf-start))) - (cond - [(positive? got-c) - ;; We converted some bytes into s. - got-c] - [(eq? status 'aborts) - (if buf-eof? - ;; Had an EOF or special in the stream. - (if (= buf-start buf-end) - (if (and newline-convert? (mcdr c)) ; should be bytes-convert-end - ;; Have leftover CR: - (begin - (bytes-set! s 0 - (if (eq? (mcdr c) (char->integer #\return)) - (char->integer #\newline) - (mcdr c))) - (set-mcdr! c #f) - 1) - ;; Return EOF: - (begin0 buf-eof-result - (set! buf-eof? #f) - (set! buf-eof-result #f))) - (handle-error s)) - ;; Need more bytes. - (begin - (when (positive? buf-start) - (bytes-copy! buf 0 buf buf-start buf-end) - (set! buf-end (- buf-end buf-start)) - (set! buf-start 0)) - (let* ([amt (bytes-length s)] - [c (read-bytes-avail!* - buf port buf-end - (if (eq? buffer-mode 'block) - (bytes-length buf) - (min (bytes-length buf) (+ buf-end amt))))]) - (cond - [(or (eof-object? c) (procedure? c)) - ;; Got EOF/procedure - (set! buf-eof? #t) - (set! buf-eof-result c) - (read-it s)] - [(zero? c) - ;; No bytes ready --- try again later. - (wrap-evt port (lambda (v) 0))] - [else - ;; Got some bytes; loop to decode. - (set! buf-end (+ buf-end c)) - (read-it s)]))))] - [(eq? status 'error) - (handle-error s)] - [(eq? status 'continues) - ;; Need more room to make progress at all. - ;; Decode into ready-bytes. - (let-values ([(got-c used-c status) ((if newline-convert? - bytes-convert/post-nl - bytes-convert) - c buf buf-start buf-end ready-bytes)]) - (unless (memq status '(continues complete)) - (decode-error "unable to make decoding progress" - port)) - (set! ready-start 0) - (set! ready-end got-c) - (set! buf-start (+ used-c buf-start)) - (read-it s))]))])) - - ;; Raise exception or discard first buffered byte. - ;; We assume that read-bytes is empty - (define (handle-error s) - (if error-bytes - (begin - (set! buf-start (add1 buf-start)) - (let ([cnt (min (bytes-length s) - (bytes-length error-bytes))]) - (bytes-copy! s 0 error-bytes 0 cnt) - (bytes-copy! ready-bytes 0 error-bytes cnt) - (set! ready-start 0) - (set! ready-end (- (bytes-length error-bytes) cnt)) - cnt)) - (decode-error "decoding error in input stream" port))) - - (unless c - (error 'reencode-input-port - "could not create converter from ~e to UTF-8" - encoding)) - - (make-input-port/read-to-peek - name - read-it - #f - (lambda () - (when close? (close-input-port port)) - (bytes-close-converter (if newline-convert? (mcar c) c))) - #f void 1 - (case-lambda - [() buffer-mode] - [(mode) (set! buffer-mode mode)]) - (eq? buffer-mode 'block))))) - -;; -------------------------------------------------- - -(define reencode-output-port - (lambda (port encoding [error-bytes #f] [close? #f] - [name (object-name port)] - [convert-newlines-to #f] - [decode-error (lambda (msg port) - (error 'reencode-output-port - (format "~a: ~~e" msg) - port))]) - (let ([c (bytes-open-converter "UTF-8" encoding)] - [ready-bytes (make-bytes 1024)] - [ready-start 0] - [ready-end 0] - [out-bytes (make-bytes 1024)] - [out-start 0] - [out-end 0] - [buffer-mode (or (file-stream-buffer-mode port) 'block)] - [debuffer-buf #f] - [newline-buffer #f]) - (define-values (buffered-r buffered-w) (make-pipe 4096)) - - ;; The main writing entry point: - (define (write-it s start end no-buffer&block? enable-break?) - (cond - [(= start end) - ;; This is a flush request; no-buffer&block? must be #f - ;; Note: we could get stuck because only half an encoding - ;; is available in out-bytes. - (flush-buffer-pipe #f enable-break?) - (flush-some #f enable-break?) - (if (buffer-flushed?) - 0 - (write-it s start end no-buffer&block? enable-break?))] - [no-buffer&block? - (case (flush-all #t enable-break?) - [(not-done) - ;; We couldn't flush right away, so give up. - #f] - [(done) - (non-blocking-write s start end)] - [(stuck) - ;; We need more bytes to make progress. - ;; Add out-bytes and s into one string for non-blocking-write. - (let ([s2 (bytes-append (subbytes out-bytes out-start out-end) - (subbytes s start end))] - [out-len (- out-end out-start)]) - (let ([c (non-blocking-write s2 0 (bytes-length s2))]) - (and c (begin (set! out-start 0) - (set! out-end 0) - (- c out-len)))))])] - [(and (eq? buffer-mode 'block) - (zero? (pipe-content-length buffered-r))) - ;; The port system can buffer to a pipe faster, so give it a pipe. - buffered-w] - [else - ;; Flush/buffer from pipe, first: - (flush-buffer-pipe #f enable-break?) - ;; Flush as needed to make room in the buffer: - (make-buffer-room #f enable-break?) - ;; Buffer some bytes: - (let-values ([(s2 start2 cnt2 used) - (convert-newlines s start - (- end start) - (- (bytes-length out-bytes) out-end))]) - (if (zero? used) - ;; No room --- try flushing again: - (write-it s start end #f enable-break?) - ;; Buffer and report success: - (begin - (bytes-copy! out-bytes out-end s2 start2 (+ start2 cnt2)) - (set! out-end (+ cnt2 out-end)) - (case buffer-mode - [(none) (flush-all-now enable-break?)] - [(line) (when (regexp-match-positions #rx#"[\r\n]" s start - (+ start used)) - (flush-all-now enable-break?))]) - used)))])) - - (define (convert-newlines s start cnt avail) - ;; If newline converting is on, try convert up to cnt - ;; bytes to produce a result that fits in avail bytes. - (if convert-newlines-to - ;; Conversion: - (let ([end (+ start cnt)] - [avail (min avail 1024)]) - (unless newline-buffer - (set! newline-buffer (make-bytes 1024))) - (let loop ([i start][j 0]) - (cond - [(or (= j avail) (= i end)) (values newline-buffer 0 j i)] - [(eq? (char->integer #\newline) (bytes-ref s i)) - ;; Newline conversion - (let ([len (bytes-length convert-newlines-to)]) - (if ((+ j len) . > . avail) - ;; No room - (values newline-buffer 0 j i) - ;; Room - (begin (bytes-copy! newline-buffer j convert-newlines-to) - (loop (add1 i) (+ j len)))))] - [else - (bytes-set! newline-buffer j (bytes-ref s i)) - (loop (add1 i) (add1 j))]))) - ;; No conversion: - (let ([cnt (min cnt avail)]) - (values s start cnt cnt)))) - - (define (make-buffer-room non-block? enable-break?) - (when (or (> ready-end ready-start) - (< (- (bytes-length out-bytes) out-end) 100)) - ;; Make room for conversion. - (flush-some non-block? enable-break?) ;; convert some - (flush-some non-block? enable-break?)) ;; write converted - ;; Make room in buffer - (when (positive? out-start) - (bytes-copy! out-bytes 0 out-bytes out-start out-end) - (set! out-end (- out-end out-start)) - (set! out-start 0))) - - (define (flush-buffer-pipe non-block? enable-break?) - (let loop () - (if (zero? (pipe-content-length buffered-r)) - 'done - (begin - (unless debuffer-buf (set! debuffer-buf (make-bytes 4096))) - (make-buffer-room non-block? enable-break?) - (let ([amt (- (bytes-length out-bytes) out-end)]) - (if (zero? amt) - 'stuck - (if convert-newlines-to - ;; Peek, convert newlines, write, then read converted amount: - (let ([cnt (peek-bytes-avail! debuffer-buf 0 #f buffered-r - 0 amt)]) - (let-values ([(s2 start2 cnt2 used) - (convert-newlines debuffer-buf 0 cnt amt)]) - (bytes-copy! out-bytes out-end s2 start2 cnt2) - (set! out-end (+ cnt2 out-end)) - (read-bytes-avail! debuffer-buf buffered-r 0 used) - (loop))) - ;; Skip an indirection: read directly and write: - (let ([cnt (read-bytes-avail! debuffer-buf buffered-r - 0 amt)]) - (bytes-copy! out-bytes out-end debuffer-buf 0 cnt) - (set! out-end (+ cnt out-end)) - (loop))))))))) - - (define (non-blocking-write s start end) - ;; For now, everything that we can flushed is flushed. - ;; Try to write the minimal number of bytes, and hope for the - ;; best. If none of all of the minimal bytes get written, - ;; everyone is happy enough. If some of the bytes get written, - ;; the we will have buffered bytes when we shouldn't have. - ;; That probably won't happen, but we can't guarantee it. - (if (sync/timeout 0.0 port) - ;; We should be able to write one byte... - (let loop ([len 1]) - (let*-values ([(s2 start2 len2 used) - (convert-newlines s start (- end start) len)] - [(got-c used-c status) - (bytes-convert c s2 start2 (+ start2 len2) - ready-bytes)]) - (cond - [(positive? got-c) - (try-flush-ready got-c used-c) - ;; If used-c < len2, then we converted only partially - ;; --- which is strange, because we kept adding - ;; bytes one at a time. we will just guess is that - ;; the unused bytes were not converted bytes, and - ;; generally hope that this sort of encoding doesn't - ;; show up. - (- used (- len2 used-c))] - [(eq? status 'aborts) - (if (< len (- end start)) - ;; Try converting a bigger chunk - (loop (add1 len)) - ;; We can't flush half an encoding, so just buffer it. - (begin (when (> len2 (bytes-length out-bytes)) - (raise-insane-decoding-length)) - (bytes-copy! out-bytes 0 s2 start2 (+ start2 len2)) - (set! out-start 0) - (set! out-end len2) - used))] - [(eq? status 'continues) - ;; Not enough room in ready-bytes!? We give up. - (raise-insane-decoding-length)] - [else - ;; Encoding error. Try to flush error bytes. - (let ([cnt (bytes-length error-bytes)]) - (bytes-copy! ready-bytes 0 error-bytes) - (try-flush-ready cnt 1) - used)]))) - ;; Port is not ready for writing: - #f)) - - (define (write-special-it v no-buffer&block? enable-break?) - (cond - [(buffer-flushed?) - ((if no-buffer&block? - write-special-avail* - (if enable-break? - (lambda (v p) (parameterize-break #t (write-special v p))) - write-special)) - v port)] - [else - ;; Note: we could get stuck because only half an encoding - ;; is available in out-bytes. - (flush-buffer-pipe no-buffer&block? enable-break?) - (flush-some no-buffer&block? enable-break?) - (if (or (buffer-flushed?) (not no-buffer&block?)) - (write-special-it v no-buffer&block? enable-break?) - #f)])) - - ;; flush-all : -> 'done, 'not-done, or 'stuck - (define (flush-all non-block? enable-break?) - (if (eq? (flush-buffer-pipe non-block? enable-break?) 'done) - (let ([orig-none-ready? (= ready-start ready-end)] - [orig-out-start out-start] - [orig-out-end out-end]) - (flush-some non-block? enable-break?) - (if (buffer-flushed?) - 'done - ;; Couldn't flush everything. One possibility is that we need - ;; more bytes to convert before a flush. - (if (and orig-none-ready? - (= ready-start ready-end) - (= orig-out-start out-start) - (= orig-out-end out-end)) - 'stuck - 'not-done))) - 'stuck)) - - (define (flush-all-now enable-break?) - (case (flush-all #f enable-break?) - [(not-done) (flush-all-now enable-break?)])) - - (define (buffer-flushed?) - (and (= ready-start ready-end) - (= out-start out-end) - (zero? (pipe-content-length buffered-r)))) - - ;; Try to flush immediately a certain number of bytes. - ;; we've already converted them, so we have to keep - ;; the bytes in any case. - (define (try-flush-ready got-c used-c) - (let ([c (write-bytes-avail* ready-bytes port 0 got-c)]) - (unless (= c got-c) - (set! ready-start c) - (set! ready-end got-c)))) - - ;; Try to make progress flushing buffered bytes - (define (flush-some non-block? enable-break?) - (unless (= ready-start ready-end) - ;; Flush converted bytes: - (let ([cnt ((cond [non-block? write-bytes-avail*] - [enable-break? write-bytes-avail/enable-break] - [else write-bytes-avail]) - ready-bytes port ready-start ready-end)]) - (set! ready-start (+ ready-start cnt)))) - (when (= ready-start ready-end) - ;; Convert more, if available: - (set! ready-start 0) - (set! ready-end 0) - (when (> out-end out-start) - (let-values ([(got-c used-c status) - (bytes-convert c out-bytes out-start out-end - ready-bytes)]) - (set! ready-end got-c) - (set! out-start (+ out-start used-c)) - (when (and (eq? status 'continues) (zero? used-c)) - ;; Yikes! Size of ready-bytes isn't enough room for progress!? - (raise-insane-decoding-length)) - (when (and (eq? status 'error) (zero? used-c)) - ;; No progress before an encoding error. - (if error-bytes - ;; Write error bytes and drop an output byte: - (begin (set! out-start (add1 out-start)) - (bytes-copy! ready-bytes 0 error-bytes) - (set! ready-end (bytes-length error-bytes))) - ;; Raise an exception: - (begin - (set! out-start out-end) ;; flush buffer so close can work - (decode-error - "error decoding output to stream" - port)))))))) - - ;; This error is used when decoding wants more bytes to make - ;; progress even though we've supplied hundreds of bytes - (define (raise-insane-decoding-length) - (decode-error "unable to make decoding progress" port)) - - ;; Check that a decoder is available: - (unless c - (error 'reencode-output-port - "could not create converter from ~e to UTF-8" - encoding)) - - (make-output-port - name - port - write-it - (lambda () - ;; Flush output - (write-it #"" 0 0 #f #f) - (when close? - (close-output-port port)) - (bytes-close-converter c)) - write-special-it - #f #f - #f void - 1 - (case-lambda - [() buffer-mode] - [(mode) (let ([old buffer-mode]) - (set! buffer-mode mode) - (when (or (and (eq? old 'block) (memq mode '(none line))) - (and (eq? old 'line) (memq mode '(none)))) - ;; Flush output - (write-it #"" 0 0 #f #f)))]))))) - -;; ---------------------------------------- - -(define dup-output-port - (lambda (p [close? #f]) - (let ([new (transplant-output-port - p - (lambda () (port-next-location p)) - (add1 (file-position p)) - close? - (lambda () (port-count-lines! p)))]) - (port-display-handler new (port-display-handler p)) - (port-write-handler new (port-write-handler p)) - new))) - -(define dup-input-port - (lambda (p [close? #f]) - (let ([new (transplant-input-port - p - (lambda () (port-next-location p)) - (add1 (file-position p)) - close? - (lambda () (port-count-lines! p)))]) - (port-read-handler new (port-read-handler p)) - new))) diff --git a/collects/racket/pretty.rkt b/collects/racket/pretty.rkt index 61e8f274bb..e622a8066a 100644 --- a/collects/racket/pretty.rkt +++ b/collects/racket/pretty.rkt @@ -10,7 +10,7 @@ ;; (current-print pretty-print-handler) (module pretty racket/base - (require racket/private/port) + (require mzlib/private/port) (provide pretty-print pretty-write diff --git a/collects/racket/runtime-path.rkt b/collects/racket/runtime-path.rkt index 207da5c5a1..2781ef9bc8 100644 --- a/collects/racket/runtime-path.rkt +++ b/collects/racket/runtime-path.rkt @@ -1,20 +1,8 @@ #lang racket/base +(require (for-syntax racket/base)) -;; Library for accessing paths relative to a source file at runtime - -(require racket/list - setup/dirs - "private/this-expression-source-directory.rkt" - (only-in "private/runtime-path-table.rkt" table) - (for-syntax racket/base)) - -(provide ;; used to be in `mzlib/runtime-path` - define-runtime-path - define-runtime-paths - define-runtime-path-list - define-runtime-module-path-index - runtime-paths - ;; from `racket/runtime-path` +(require mzlib/runtime-path) +(provide (all-from-out mzlib/runtime-path) (for-syntax #%datum) define-runtime-module-path) @@ -44,164 +32,3 @@ (module-path-index-resolve (module-path-index-join mod-path (variable-reference->resolved-module-path vr)))) - -;; ---------------------------------------- -;; the code below used to be in `mzlib/runtime-path` - -(define-for-syntax ext-file-table (make-hasheq)) - -(define (lookup-in-table var-ref p) - ;; This function is designed to cooperate with a table embedded - ;; in an executable by create-embedding-executable. - (let ([modname (variable-reference->resolved-module-path var-ref)]) - (let ([p (hash-ref - table - (cons (resolved-module-path-name modname) - (if (path? p) - (path->bytes p) - (if (and (pair? p) (eq? 'module (car p))) - (list 'module (cadr p)) - p))) - #f)]) - (and p - (car p) - (let* ([p (car p)] - [p (if (bytes? p) - (bytes->path p) - p)]) - (if (symbol? p) - (module-path-index-join (list 'quote p) #f) ; make it a module path index - (if (absolute-path? p) - p - (parameterize ([current-directory (find-system-path 'orig-dir)]) - (or (find-executable-path (find-system-path 'exec-file) p #t) - (build-path (current-directory) p)))))))))) - -(define (resolve-paths tag-stx get-base paths) - (let ([base #f]) - (map (lambda (p) - (or - ;; Check table potentially substituted by - ;; mzc --exe: - (and table - (lookup-in-table tag-stx p)) - ;; Normal resolution - (cond - [(and (or (string? p) (path? p)) - (not (complete-path? p))) - (unless base - (set! base (get-base))) - (path->complete-path p base)] - [(string? p) (string->path p)] - [(path? p) p] - [(and (list? p) - (= 2 (length p)) - (eq? 'so (car p)) - (string? (cadr p))) - (let ([f (path-replace-suffix (cadr p) (system-type 'so-suffix))]) - (or (ormap (lambda (p) - (let ([p (build-path p f)]) - (and (file-exists? p) - p))) - (get-lib-search-dirs)) - (cadr p)))] - [(and (list? p) - ((length p) . > . 1) - (eq? 'lib (car p)) - (andmap string? (cdr p))) - (let* ([strs (regexp-split #rx"/" - (let ([s (cadr p)]) - (if (regexp-match? #rx"[./]" s) - s - (string-append s "/main.rkt"))))]) - (apply collection-file-path - (last strs) - (if (and (null? (cddr p)) - (null? (cdr strs))) - (list "mzlib") - (append (cddr p) (drop-right strs 1)))))] - [(and (list? p) - ((length p) . = . 3) - (eq? 'module (car p)) - (or (not (caddr p)) - (variable-reference? (caddr p)))) - (let ([p (cadr p)] - [vr (caddr p)]) - (unless (module-path? p) - (error 'runtime-path "not a module path: ~.s" p)) - (let ([base (and vr - (variable-reference->resolved-module-path vr))]) - (if (and (pair? p) - (eq? (car p) 'submod) - (path? (cadr p))) - (module-path-index-join `(submod "." ,@(cddr p)) - (module-path-index-join (cadr p) base)) - (module-path-index-join p base))))] - [else (error 'runtime-path "unknown form: ~.s" p)]))) - paths))) - -(define-for-syntax (register-ext-files var-ref paths) - (let ([modname (variable-reference->resolved-module-path var-ref)]) - (let ([files (hash-ref ext-file-table modname null)]) - (hash-set! ext-file-table modname (append paths files))))) - -(define-syntax (-define-runtime-path stx) - (syntax-case stx () - [(_ orig-stx (id ...) expr to-list to-values) - (let ([ids (syntax->list #'(id ...))]) - (unless (memq (syntax-local-context) '(module module-begin top-level)) - (raise-syntax-error #f "allowed only at the top level" #'orig-stx)) - (for-each (lambda (id) - (unless (identifier? id) - (raise-syntax-error - #f - #'orig-stx - id))) - ids) - #`(begin - (define-values (id ...) - (let-values ([(id ...) expr]) - (let ([get-dir (lambda () - #,(datum->syntax - #'orig-stx - `(,#'this-expression-source-directory) - #'orig-stx))]) - (apply to-values (resolve-paths (#%variable-reference) - get-dir - (to-list id ...)))))) - (begin-for-syntax - (register-ext-files - (#%variable-reference) - (let-values ([(id ...) expr]) - (to-list id ...))))))])) - -(define-syntax (define-runtime-path stx) - (syntax-case stx () - [(_ id expr) #`(-define-runtime-path #,stx (id) expr list values)])) - -(define-syntax (define-runtime-paths stx) - (syntax-case stx () - [(_ (id ...) expr) #`(-define-runtime-path #,stx (id ...) expr list values)])) - -(define-syntax (define-runtime-path-list stx) - (syntax-case stx () - [(_ id expr) #`(-define-runtime-path #,stx (id) expr values list)])) - -(define-syntax (define-runtime-module-path-index stx) - (syntax-case stx () - [(_ id expr) #`(-define-runtime-path #,stx (id) `(module ,expr ,(#%variable-reference)) list values)])) - -(define-syntax (runtime-paths stx) - (syntax-case stx () - [(_ mp) - #`(quote - #,(hash-ref - ext-file-table - (module-path-index-resolve - (let ([p (syntax->datum #'mp)] - [base (syntax-source-module stx)]) - (if (and (pair? p) (eq? (car p) 'submod) (path? (cadr p))) - (module-path-index-join `(submod "." ,@(cddr p)) - (module-path-index-join (cadr p) base)) - (module-path-index-join p base)))) - null))])) diff --git a/collects/racket/shared.rkt b/collects/racket/shared.rkt index f6af9d4aae..853e479b94 100644 --- a/collects/racket/shared.rkt +++ b/collects/racket/shared.rkt @@ -1,21 +1,4 @@ #lang racket/base -(require (for-syntax racket/base - syntax/kerncase - syntax/struct - racket/struct-info - racket/include)) +(require mzlib/shared) (provide shared) - -(define-for-syntax code-insp (variable-reference->module-declaration-inspector - (#%variable-reference))) - -(define undefined (letrec ([x x]) x)) -(require (only-in racket/base [cons the-cons])) - -(define-syntax shared - (lambda (stx) - (define make-check-cdr #f) - ;; Include the implementation. - ;; See private/shared-body.rkt. - (include "private/shared-body.rkt"))) diff --git a/collects/racket/signature/lang.rkt b/collects/racket/signature/lang.rkt index 3f845168b6..0752de7fe5 100644 --- a/collects/racket/signature/lang.rkt +++ b/collects/racket/signature/lang.rkt @@ -3,8 +3,8 @@ (require scheme/unit scheme/contract (for-syntax scheme/base - racket/private/unit-compiletime - racket/private/unit-syntax)) + mzlib/private/unit-compiletime + mzlib/private/unit-syntax)) (provide (rename-out [module-begin #%module-begin]) (except-out (all-from-out scheme/base) #%module-begin) diff --git a/collects/racket/system.rkt b/collects/racket/system.rkt index 49f556232e..1dcc88c73f 100644 --- a/collects/racket/system.rkt +++ b/collects/racket/system.rkt @@ -1,207 +1,3 @@ -#lang racket/base -(provide process - process* - process/ports - process*/ports - system - system* - system/exit-code - system*/exit-code) - -(require "private/streams.rkt") - -;; Helpers: ---------------------------------------- - -(define (shell-path/args who argstr) - (case (system-type) - [(unix macosx) (append '("/bin/sh" "-c") (list argstr))] - [(windows) (let ([cmd - (let ([d (find-system-path 'sys-dir)]) - (let ([cmd (build-path d "cmd.exe")]) - (if (file-exists? cmd) - cmd - (let ([cmd (build-path d "command.com")]) - (if (file-exists? cmd) - cmd - ;; One last try: up a dir - (build-path d 'up "command.com"))))))]) - (list cmd - 'exact - (format "~a /c \"~a\"" (path->string cmd) argstr)))] - [else (raise-mismatch-error - who - (format "~a: don't know what shell to use for platform: " who) - (system-type))])) - -(define (check-exe who exe) - (unless (path-string? exe) - (raise-argument-error who "path-string?" exe)) - exe) - -(define (path-or-ok-string? s) - ;; use `path-string?' t check for nul characters in a string, - ;; but allow the empty string (which is not an ok path), too: - (or (path-string? s) - (equal? "" s))) - -(define (string-no-nuls? s) - (and (string? s) (path-or-ok-string? s))) - -(define (bytes-no-nuls? s) - (and (bytes? s) - (not (regexp-match? #rx#"\0" s)))) - -(define (check-args who args) - (cond - [(null? args) (void)] - [(eq? (car args) 'exact) - (when (null? (cdr args)) - (raise-mismatch-error - who - "expected a single string argument after: " - (car args))) - (unless (and (>= 2 (length args)) - (string? (cadr args)) - (path-or-ok-string? (cadr args))) - (raise-mismatch-error who - "expected a single string argument after 'exact, given: " - (cadr args))) - (when (pair? (cddr args)) - (raise-mismatch-error - who - "expected a single string argument after 'exact, given additional argument: " - (caddr args)))] - [else - (for ([s (in-list args)]) - (unless (or (path-or-ok-string? s) - (bytes-no-nuls? s)) - (raise-argument-error - who - (string-append "(or/c path-string?\n" - " (and/c bytes? (lambda (bs) (not (memv 0 (bytes->list bs))))))") - s)))]) - args) - -(define (check-command who str) - (unless (or (string-no-nuls? str) - (bytes-no-nuls? str)) - (raise-argument-error - who - (string-append "(or/c (and/c string? (lambda (s) (not (memv #\\nul (string->list s)))))\n" - " (and/c bytes? (lambda (bs) (not (memv 0 (bytes->list bs))))))") - str))) - -;; Old-style functions: ---------------------------------------- - -(define (do-process*/ports who cout cin cerr exe . args) - (let-values ([(subp out in err) (apply subprocess - (if-stream-out who cout) - (if-stream-in who cin) - (if-stream-out who cerr #t) - (check-exe who exe) - (check-args who args))] - [(it-ready) (make-semaphore)]) - (let ([so (streamify-out cout out)] - [si (streamify-in cin in (lambda (ok?) - (if ok? - (semaphore-post it-ready) - (semaphore-wait it-ready))))] - [se (streamify-out cerr err)] - [aport (lambda (x) (and (port? x) x))]) - (when (thread? si) - ;; Wait for process to end, then stop copying input: - (thread (lambda () - (sync subp si) - (semaphore-wait it-ready) - (break-thread si)))) - (let ([threads-still-going? - (lambda () - (ormap (lambda (s) (and (thread? s) (thread-running? s))) - (list so si se)))]) - (define (control m) - (case m - [(status) - (let ([s (subprocess-status subp)]) - (cond [(or (not (integer? s)) (threads-still-going?)) - 'running] - [(zero? s) 'done-ok] - [else 'done-error]))] - [(exit-code) - (if (threads-still-going?) - #f - (let ([s (subprocess-status subp)]) (and (integer? s) s)))] - [(wait) - (subprocess-wait subp) - (let ([twait (lambda (t) (when (thread? t) (thread-wait t)))]) - (twait so) - (twait si) - (twait se))] - [(interrupt) (subprocess-kill subp #f)] - [(kill) (subprocess-kill subp #t)] - [else (raise-argument-error - 'control-process - "(or/c 'status 'exit-code 'wait 'interrupt 'kill)" m)])) - (list (aport so) - (aport si) - (subprocess-pid subp) - (aport se) - control))))) - -(define (process*/ports cout cin cerr exe . args) - (apply do-process*/ports 'process*/ports cout cin cerr exe args)) - -(define (process/ports out in err str) - (apply do-process*/ports 'process/ports out in err (shell-path/args 'process/ports str))) - -(define (process* exe . args) - (apply do-process*/ports 'process* #f #f #f exe args)) - -(define (process str) - (check-command 'process str) - (apply do-process*/ports 'process #f #f #f (shell-path/args 'process str))) - -;; Note: these always use current ports -(define (do-system*/exit-code who exe . args) - (let ([cout (current-output-port)] - [cin (current-input-port)] - [cerr (current-error-port)] - [it-ready (make-semaphore)]) - (let-values ([(subp out in err) - (apply subprocess - (if-stream-out who cout) - (if-stream-in who cin) - (if-stream-out who cerr #t) - (check-exe who exe) - (check-args who args))]) - (let ([ot (streamify-out cout out)] - [it (streamify-in cin in (lambda (ok?) - (if ok? - (semaphore-post it-ready) - (semaphore-wait it-ready))))] - [et (streamify-out cerr err)]) - (subprocess-wait subp) - (when it - ;; stop piping output to subprocess - (semaphore-wait it-ready) - (break-thread it)) - ;; wait for other pipes to run dry: - (when (thread? ot) (thread-wait ot)) - (when (thread? et) (thread-wait et)) - (when err (close-input-port err)) - (when out (close-input-port out)) - (when in (close-output-port in))) - (subprocess-status subp)))) - -(define (system*/exit-code exe . args) - (apply do-system*/exit-code 'system*/exit-code exe args)) - -(define (system* exe . args) - (zero? (apply do-system*/exit-code 'system* exe args))) - -(define (system str) - (check-command 'system str) - (zero? (apply do-system*/exit-code 'system (shell-path/args 'system str)))) - -(define (system/exit-code str) - (check-command 'system/exit-code str) - (apply do-system*/exit-code 'system/exit-code (shell-path/args 'system/exit-code str))) +(module system racket/base + (require mzlib/process) + (provide (all-from-out mzlib/process))) diff --git a/collects/racket/unit-exptime.rkt b/collects/racket/unit-exptime.rkt index df22354598..45f290e5a0 100644 --- a/collects/racket/unit-exptime.rkt +++ b/collects/racket/unit-exptime.rkt @@ -1,27 +1,4 @@ #lang racket/base -(require "private/unit-syntax.rkt" - "private/unit-compiletime.rkt") - -(provide unit-static-signatures - signature-members) - -(define (unit-static-signatures name err-stx) - (parameterize ((error-syntax err-stx)) - (let ((ui (lookup-def-unit name))) - (values (apply list (unit-info-import-sig-ids ui)) - (apply list (unit-info-export-sig-ids ui)))))) - -(define (signature-members name err-stx) - (parameterize ((error-syntax err-stx)) - (let ([s (lookup-signature name)]) - (values - ;; extends: - (and (pair? (cdr (siginfo-names (signature-siginfo s)))) - (cadr (siginfo-names (signature-siginfo s)))) - ;; vars - (apply list (signature-vars s)) - ;; defined vars - (apply list (apply append (map car (signature-val-defs s)))) - ;; defined stxs - (apply list (apply append (map car (signature-stx-defs s)))))))) +(require mzlib/unit-exptime) +(provide (all-from-out mzlib/unit-exptime)) diff --git a/collects/racket/unit.rkt b/collects/racket/unit.rkt index 3b8c588eef..586e2b064d 100644 --- a/collects/racket/unit.rkt +++ b/collects/racket/unit.rkt @@ -1,2339 +1,8 @@ -#lang racket/base -;; Library for first-class components with recursive linking - -(require (for-syntax racket/base - syntax/boundmap - syntax/context - syntax/kerncase - syntax/name - syntax/parse - syntax/struct - racket/struct-info - syntax/stx - syntax/location - "private/unit-contract-syntax.rkt" - "private/unit-compiletime.rkt" - "private/unit-syntax.rkt")) - -(require racket/block - racket/contract/base - racket/contract/region - racket/stxparam - syntax/location - "private/unit-contract.rkt" - "private/unit-keywords.rkt" - "private/unit-runtime.rkt" - "private/unit-utils.rkt" - (rename-in racket/private/struct [struct struct~])) - -(provide define-signature-form open - define-signature provide-signature-elements - only except rename import export prefix link tag init-depend extends contracted - define-values-for-export - unit? - (rename-out [:unit unit]) define-unit - compound-unit define-compound-unit compound-unit/infer define-compound-unit/infer - invoke-unit define-values/invoke-unit - invoke-unit/infer define-values/invoke-unit/infer - unit-from-context define-unit-from-context - define-unit-binding - unit/new-import-export define-unit/new-import-export - unit/s define-unit/s - unit/c define-unit/contract - (rename-out [struct~r/ctc struct/ctc])) - -(define-syntax/err-param (define-signature-form stx) - (syntax-case stx () - ((_ (name arg) . val) - (begin - (check-id #'name) - (check-id #'arg) - #'(define-syntax name - (make-set!-transformer - (make-signature-form (λ (arg) . val)))))) - ((_ . l) - (let ((l (checked-syntax->list stx))) - (unless (>= 3 (length l)) - (raise-stx-err - (format "expected syntax matching (~a (id id) expr ...)" - (syntax-e (stx-car stx))))) - (unless (= 2 (length (checked-syntax->list (car l)))) - (raise-stx-err - "expected syntax matching (identifier identifier)" - (car l))))))) - -(module+ compat - ;; export only for compatibility with `mzlib/unit` - (provide (protect-out struct)) - - (define-signature-form (struct stx) - (parameterize ((error-syntax stx)) - (syntax-case stx () - ((_ name (field ...) . omissions) - (let ([omit-selectors #f] - [omit-setters #f] - [omit-constructor #f] - [omit-type #f]) - (define (remove-ctor&type-name l) - (cond - ((and omit-constructor omit-type) - (cddr l)) - (omit-type - (cdr l)) - (omit-constructor - (cons (car l) (cddr l))) - (else - l))) - (define (remove-ctor&type-info l) - (define new-type - (if omit-type - #f - (cadr l))) - (define new-ctor - (if omit-constructor - #f - (caddr l))) - (cons (car l) - (cons new-type - (cons new-ctor - (cdddr l))))) - (check-id #'name) - (for-each check-id (syntax->list #'(field ...))) - (for-each - (lambda (omission) - (cond - ((and (identifier? omission) - (free-identifier=? omission #'-selectors)) - (set! omit-selectors #t)) - ((and (identifier? omission) - (free-identifier=? omission #'-setters)) - (set! omit-setters #t)) - ((and (identifier? omission) - (free-identifier=? omission #'-constructor)) - (set! omit-constructor #t)) - ((and (identifier? omission) - (free-identifier=? omission #'-type)) - (set! omit-type #t)) - (else - (raise-stx-err - "expected \"-selectors\" or \"-setters\" or \"-constructor\" or \"-type\"" - omission)))) - (checked-syntax->list #'omissions)) - (cons - #`(define-syntaxes (name) - #,(remove-ctor&type-info - (build-struct-expand-info - #'name (syntax->list #'(field ...)) - omit-selectors omit-setters - #f '(#f) '(#f)))) - (remove-ctor&type-name - (build-struct-names #'name (syntax->list #'(field ...)) - omit-selectors omit-setters #f))))) - ((_ name (x . y) . omissions) - ;; Will fail - (checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))) - ((_ name fields . omissions) - (raise-stx-err "expected syntax matching (identifier ...)" #'fields)) - ((_ name) - (raise-stx-err "missing fields")) - ((_) - (raise-stx-err "missing name and fields")))))) - -(begin-for-syntax - (define-struct self-name-struct-info (id) - #:super struct:struct-info - #:property prop:procedure (lambda (me stx) - (syntax-case stx () - [(_ arg ...) (datum->syntax - stx - (cons ((self-name-struct-info-id me)) - #'(arg ...)) - stx - stx)] - [_ (let ([id ((self-name-struct-info-id me))]) - (datum->syntax id - (syntax-e id) - stx - stx))])) - #:omit-define-syntaxes)) - -(define-for-syntax option-keywords - "#:mutable, #:constructor-name, #:extra-constructor-name, #:omit-constructor, #:omit-define-syntaxes, or #:omit-define-values") - -;; Replacement `struct' signature form for `scheme/unit': -(define-for-syntax (do-struct~ stx extra-make?) - (syntax-case stx () - ((_ name (field ...) opt ...) - (begin - (unless (identifier? #'name) - (raise-syntax-error #f - "expected an identifier to name the structure type" - stx - #'name)) - (for-each (lambda (field) - (unless (identifier? field) - (syntax-case field () - [(id #:mutable) - (identifier? #'id) - 'ok] - [_ - (raise-syntax-error #f - "bad field specification" - stx - field)]))) - (syntax->list #'(field ...))) - (let*-values ([(no-ctr? mutable? no-stx? no-rt? opt-cname) - (let loop ([opts (syntax->list #'(opt ...))] - [no-ctr? #f] - [mutable? #f] - [no-stx? #f] - [no-rt? #f] - [cname #f]) - (if (null? opts) - (values no-ctr? mutable? no-stx? no-rt? cname) - (let ([opt (car opts)]) - (case (syntax-e opt) - [(#:constructor-name #:extra-constructor-name) - (if cname - (raise-syntax-error #f - "redundant option" - stx - opt) - (if (null? (cdr opts)) - (raise-syntax-error #f - "missing identifier after option" - stx - opt) - (if (identifier? (cadr opts)) - (loop (cddr opts) #f mutable? no-stx? no-rt? - (if (eq? (syntax-e opt) '#:extra-constructor-name) - (list (cadr opts)) - (cadr opts))) - (raise-syntax-error #f - "not an identifier for a constructor name" - stx - (cadr opts)))))] - [(#:omit-constructor) - (if no-ctr? - (raise-syntax-error #f - "redundant option" - stx - opt) - (loop (cdr opts) #t mutable? no-stx? no-rt? cname))] - [(#:mutable) - (if mutable? - (raise-syntax-error #f - "redundant option" - stx - opt) - (loop (cdr opts) no-ctr? #t no-stx? no-rt? cname))] - [(#:omit-define-syntaxes) - (if no-stx? - (raise-syntax-error #f - "redundant option" - stx - opt) - (loop (cdr opts) no-ctr? mutable? #t no-rt? cname))] - [(#:omit-define-values) - (if no-rt? - (raise-syntax-error #f - "redundant option" - stx - opt) - (loop (cdr opts) no-ctr? mutable? no-stx? #t cname))] - [else - (raise-syntax-error #f - (string-append - "expected a keyword to specify option: " - option-keywords) - stx - opt)]))))] - [(def-cname) (cond - [opt-cname (if (pair? opt-cname) - (car opt-cname) - opt-cname)] - [extra-make? #f] - [else (car (generate-temporaries #'(name)))])] - [(cname) (cond - [opt-cname (if (pair? opt-cname) - (cons def-cname #'name) - (cons opt-cname opt-cname))] - [extra-make? #f] - [else (cons def-cname #'name)])] - [(self-ctr?) (and cname (bound-identifier=? #'name (cdr cname)))]) - (cons - #`(define-syntaxes (name) - #,(let ([e (build-struct-expand-info - #'name (syntax->list #'(field ...)) - #f (not mutable?) - #f '(#f) '(#f) - #:omit-constructor? no-ctr? - #:constructor-name def-cname)]) - (if self-ctr? - #`(make-self-name-struct-info - (lambda () #,e) - (lambda () (quote-syntax #,def-cname))) - e))) - (let ([names (build-struct-names #'name (syntax->list #'(field ...)) - #f (not mutable?) - #:constructor-name def-cname)]) - (cond - [no-ctr? (cons (car names) (cddr names))] - [self-ctr? (cons #`(define-values-for-export (#,def-cname) name) - names)] - [else names])))))) - ((_ name fields opt ...) - (raise-syntax-error #f - "bad syntax; expected a parenthesized sequence of fields" - stx - #'fields)) - ((_ name) - (raise-syntax-error #f - "bad syntax; missing fields" - stx)) - ((_) - (raise-syntax-error #f - "missing name and fields" - stx)))) - -(module+ compat - ;; export only for compatibility with `mzlib/unit` - (provide (protect-out struct~s) struct~r) - - (define-signature-form (struct~s stx) - (do-struct~ stx #t))) - -;; this binding is used by `racket/unit` for `define-signature` -(define-signature-form (struct~r stx) - (do-struct~ stx #f)) - -(define-signature-form (struct/ctc stx) - (parameterize ((error-syntax stx)) - (syntax-case stx () - ((_ name ([field ctc] ...) . omissions) - (let ([omit-selectors #f] - [omit-setters #f] - [omit-constructor #f] - [omit-type #f]) - (define (remove-ctor&type-info l) - (define new-type - (if omit-type - #f - (cadr l))) - (define new-ctor - (if omit-constructor - #f - (caddr l))) - (cons (car l) - (cons new-type - (cons new-ctor - (cdddr l))))) - (define (add-contracts l) - (let* ([pred (caddr l)] - [ctor-ctc #`(-> ctc ... #,pred)] - [pred-ctc #`(-> any/c boolean?)] - [field-ctcs (apply append - (map (λ (c) - (append (if omit-selectors - null - (list #`(-> #,pred #,c))) - (if omit-setters - null - (list #`(-> #,pred #,c void?))))) - (syntax->list #'(ctc ...))))]) - (list* (car l) - (list (cadr l) ctor-ctc) - (list pred pred-ctc) - (map list (cdddr l) field-ctcs)))) - (check-id #'name) - (for-each check-id (syntax->list #'(field ...))) - (for-each - (lambda (omission) - (cond - ((and (identifier? omission) - (free-identifier=? omission #'-selectors)) - (set! omit-selectors #t)) - ((and (identifier? omission) - (free-identifier=? omission #'-setters)) - (set! omit-setters #t)) - ((and (identifier? omission) - (free-identifier=? omission #'-constructor)) - (set! omit-constructor #t)) - ((and (identifier? omission) - (free-identifier=? omission #'-type)) - (set! omit-type #t)) - (else - (raise-stx-err - "expected \"-selectors\" or \"-setters\" or \"-constructor\" or \"-type\"" - omission)))) - (checked-syntax->list #'omissions)) - (cons - #`(define-syntaxes (name) - #,(remove-ctor&type-info - (build-struct-expand-info - #'name (syntax->list #'(field ...)) - omit-selectors omit-setters - #f '(#f) '(#f)))) - (let* ([res (add-contracts - (build-struct-names #'name (syntax->list #'(field ...)) - omit-selectors omit-setters #f))] - [cpairs (cons 'contracted (if omit-constructor (cddr res) (cdr res)))]) - (if omit-type - (list cpairs) - (list (car res) cpairs)))))) - ((_ name (x . y) . omissions) - ;; Will fail - (checked-syntax->list (stx-car (stx-cdr (stx-cdr stx))))) - ((_ name fields . omissions) - (raise-stx-err "expected syntax matching (identifier ...)" #'fields)) - ((_ name) - (raise-stx-err "missing fields")) - ((_) - (raise-stx-err "missing name and fields"))))) - -;; Replacement struct/ctc form for `scheme/unit': -(define-for-syntax (do-struct~/ctc stx extra-make?) - (syntax-case stx () - ((_ name ([field ctc] ...) opt ...) - (begin - (unless (identifier? #'name) - (raise-syntax-error #f - "expected an identifier to name the structure type" - stx - #'name)) - (for-each (lambda (field) - (unless (identifier? field) - (syntax-case field () - [(id #:mutable) - (identifier? #'id) - 'ok] - [_ - (raise-syntax-error #f - "bad field specification" - stx - field)]))) - (syntax->list #'(field ...))) - (let*-values ([(no-ctr? mutable? no-stx? no-rt? opt-cname) - (let loop ([opts (syntax->list #'(opt ...))] - [no-ctr? #f] - [mutable? #f] - [no-stx? #f] - [no-rt? #f] - [cname #f]) - (if (null? opts) - (values no-ctr? mutable? no-stx? no-rt? cname) - (let ([opt (car opts)]) - (case (syntax-e opt) - [(#:constructor-name #:extra-constructor-name) - (if cname - (raise-syntax-error #f - "redundant option" - stx - opt) - (if (null? (cdr opts)) - (raise-syntax-error #f - "missing identifier after option" - stx - opt) - (if (identifier? (cadr opts)) - (loop (cddr opts) #f mutable? no-stx? no-rt? - (if (eq? (syntax-e opt) '#:extra-constructor-name) - (list (cadr opts)) - (cadr opts))) - (raise-syntax-error #f - "not an identifier for a constructor name" - stx - (cadr opts)))))] - [(#:omit-constructor) - (if no-ctr? - (raise-syntax-error #f - "redundant option" - stx - opt) - (loop (cdr opts) #t mutable? no-stx? no-rt? cname))] - [(#:mutable) - (if mutable? - (raise-syntax-error #f - "redundant option" - stx - opt) - (loop (cdr opts) no-ctr? #t no-stx? no-rt? cname))] - [(#:omit-define-syntaxes) - (if no-stx? - (raise-syntax-error #f - "redundant option" - stx - opt) - (loop (cdr opts) no-ctr? mutable? #t no-rt? cname))] - [(#:omit-define-values) - (if no-rt? - (raise-syntax-error #f - "redundant option" - stx - opt) - (loop (cdr opts) no-ctr? mutable? no-stx? #t cname))] - [else - (raise-syntax-error #f - (string-append - "expected a keyword to specify option: " - option-keywords) - stx - opt)]))))] - [(def-cname) (cond - [opt-cname (if (pair? opt-cname) - (car opt-cname) - opt-cname)] - [extra-make? #f] - [else (car (generate-temporaries #'(name)))])] - [(cname) (cond - [opt-cname (if (pair? opt-cname) - (cons def-cname #'name) - (cons def-cname def-cname))] - [extra-make? #f] - [else (cons def-cname #'name)])] - [(self-ctr?) (and cname (bound-identifier=? #'name (cdr cname)))]) - (define (add-contracts l) - (let* ([pred (caddr l)] - [ctor-ctc #`(-> ctc ... #,pred)] - [pred-ctc #'(-> any/c boolean?)] - [field-ctcs - (apply append - (map (λ (f c) - (cons #`(-> #,pred #,c) - (if (and (not mutable?) - (not (pair? (syntax-e f)))) - null - #`(-> #,pred #,c void?)))) - (syntax->list #'(field ...)) - (syntax->list #'(ctc ...))))]) - (list* (car l) - (list (cadr l) ctor-ctc) - (list pred pred-ctc) - (map list (cdddr l) field-ctcs)))) - (cons - #`(define-syntaxes (name) - #,(let ([e (build-struct-expand-info - #'name (syntax->list #'(field ...)) - #f (not mutable?) - #f '(#f) '(#f) - #:omit-constructor? no-ctr? - #:constructor-name def-cname)]) - (if self-ctr? - #`(make-self-name-struct-info - (lambda () #,e) - (lambda () (quote-syntax #,def-cname))) - e))) - (let* ([names (add-contracts - (build-struct-names #'name (syntax->list #'(field ...)) - #f (not mutable?) - #:constructor-name def-cname))] - [cpairs (cons 'contracted - (cond - [no-ctr? (cddr names)] - [else (cdr names)]))] - [l (list (car names) cpairs)]) - (if self-ctr? - (cons #`(define-values-for-export (#,def-cname) name) l) - l)))))) - ((_ name fields opt ...) - (raise-syntax-error #f - "bad syntax; expected a parenthesized sequence of fields" - stx - #'fields)) - ((_ name) - (raise-syntax-error #f - "bad syntax; missing fields" - stx)) - ((_) - (raise-syntax-error #f - "missing name and fields" - stx)))) -(module+ compat - ;; export only for compatibility with `mzlib/unit` - (provide (protect-out struct~s/ctc)) - - (define-signature-form (struct~s/ctc stx) - (do-struct~/ctc stx #t))) - -(define-signature-form (struct~r/ctc stx) - (do-struct~/ctc stx #f)) - -;; build-val+macro-defs : sig -> (list syntax-object^3) -(define-for-syntax (build-val+macro-defs sig) - (if (and (null? (cadr sig)) - (null? (caddr sig))) - ;; No renames needed; this shortcut avoids - ;; an explosion of renamings, especially with chains - ;; of `open': - (list #'(() (values)) #'() #'()) - ;; Renames and macros needes: - (with-syntax ([(((int-ivar . ext-ivar) ...) - ((((int-vid . ext-vid) ...) . vbody) ...) - ((((int-sid . ext-sid) ...) . sbody) ...) - _ - _) - (map-sig (lambda (x) x) - (make-syntax-introducer) - sig)]) - (list - #'((ext-ivar ... ext-vid ... ... ext-sid ... ...) - (make-rename-transformers - (quote-syntax - (int-ivar ... - int-vid ... ... - int-sid ... ...)))) - #'(((int-sid ...) sbody) ...) - #'(((int-vid ...) vbody) ...))))) - -;; build-post-val-defs : sig -> (list syntax-object) -(define-for-syntax (build-post-val-defs sig) - (with-syntax ([(((int-ivar . ext-ivar) ...) - ((((int-vid . ext-vid) ...) . _) ...) - ((((int-sid . ext-sid) ...) . _) ...) - _ - (((post-id ...) . post-rhs) ...)) - (map-sig (lambda (x) x) - (make-syntax-introducer) - sig)]) - (list - #'((ext-ivar ... ext-vid ... ... ext-sid ... ...) - (make-rename-transformers - (quote-syntax - (int-ivar ... - int-vid ... ... - int-sid ... ...)))) - #'(post-rhs ...)))) - -;; Using `make-rename-transformers' helps improve sharing in -;; a syntax-quoted list of identifiers, although it risks -;; losting certificates as the list is broken apart; since the -;; identifiers are bound at the same point that the rename -;; transformer is introduced, certificate loss should be ok. -(define-for-syntax (make-rename-transformers ids) - (apply values - (map - make-rename-transformer - (syntax->list ids)))) - -(define-signature-form (open stx) - (define (build-sig-elems sig) - (map (λ (p c) - (if c #`(contracted [#,(car p) #,c]) (car p))) - (car sig) - (cadddr sig))) - (parameterize ([error-syntax stx]) - (syntax-case stx () - ((_ export-spec) - (let ([sig (process-spec #'export-spec)]) - (with-syntax (((sig-elem ...) - (build-sig-elems sig)) - ((renames - (((mac-name ...) mac-body) ...) - (((val-name ...) val-body) ...)) - (build-val+macro-defs sig))) - (syntax->list - #'(sig-elem ... - (define-syntaxes . renames) - (define-syntaxes (mac-name ...) mac-body) ... - (define-values (val-name ...) val-body) ...))))) - (_ - (raise-stx-err (format "must match (~a export-spec)" - (syntax-e (stx-car stx)))))))) - -(define-signature-form (define-values-for-export stx) - (raise-syntax-error #f "internal error" stx)) - -(define-for-syntax (introduce-def d) - (cons (map syntax-local-introduce (car d)) - (syntax-local-introduce (cdr d)))) - -;; build-define-syntax : identifier (or/c identifier #f) syntax-object -> syntax-object -(define-for-syntax (build-define-signature sigid super-sigid sig-exprs) - (unless (or (stx-null? sig-exprs) (stx-pair? sig-exprs)) - (raise-stx-err "expected syntax matching (sig-expr ...)" sig-exprs)) - (let ([ses (checked-syntax->list sig-exprs)]) - (define-values (super-names super-ctimes super-rtimes super-bindings - super-val-defs super-stx-defs super-post-val-defs - super-ctcs) - (if super-sigid - (let* ([super-sig (lookup-signature super-sigid)] - [super-siginfo (signature-siginfo super-sig)]) - (values (siginfo-names super-siginfo) - (siginfo-ctime-ids super-siginfo) - (map syntax-local-introduce - (siginfo-rtime-ids super-siginfo)) - (map syntax-local-introduce (signature-vars super-sig)) - (map introduce-def (signature-val-defs super-sig)) - (map introduce-def (signature-stx-defs super-sig)) - (map introduce-def (signature-post-val-defs super-sig)) - (map (lambda (ctc) - (if ctc - (syntax-local-introduce ctc) - ctc)) - (signature-ctcs super-sig)))) - (values '() '() '() '() '() '() '() '()))) - (let loop ((sig-exprs ses) - (bindings null) - (val-defs null) - (stx-defs null) - (post-val-defs null) - (ctcs null)) - (cond - ((null? sig-exprs) - (let* ([all-bindings (append super-bindings (reverse bindings))] - [all-val-defs (append super-val-defs (reverse val-defs))] - [all-stx-defs (append super-stx-defs (reverse stx-defs))] - [all-post-val-defs (append super-post-val-defs (reverse post-val-defs))] - [all-ctcs (append super-ctcs (reverse ctcs))] - [dup - (check-duplicate-identifier - (append all-bindings - (apply append (map car all-val-defs)) - (apply append (map car all-stx-defs))))]) - (when dup - (raise-stx-err "duplicate identifier" dup)) - (with-syntax (((super-rtime ...) super-rtimes) - ((super-name ...) super-names) - ((var ...) all-bindings) - ((ctc ...) all-ctcs) - ((((vid ...) . vbody) ...) all-val-defs) - ((((sid ...) . sbody) ...) all-stx-defs) - ((((pvid ...) . pvbody) ...) all-post-val-defs)) - #`(begin - (define signature-tag (gensym)) - (define-syntax #,sigid - (make-set!-transformer - (make-signature - (make-siginfo (list #'#,sigid #'super-name ...) - (list (quote-syntax signature-tag) - #'super-rtime - ...)) - (list (quote-syntax var) ...) - (list (cons (list (quote-syntax vid) ...) - (quote-syntax vbody)) - ...) - (list (cons (list (quote-syntax sid) ...) - (quote-syntax sbody)) - ...) - (list (cons (list (quote-syntax pvid) ...) - (quote-syntax pvbody)) - ...) - (list #,@(map (lambda (c) - (if c - #`(quote-syntax #,c) - #'#f)) - all-ctcs)) - (quote-syntax #,sigid)))) - (define-values () - (begin - (λ (var ...) - (letrec-syntaxes+values - ([(sid ...) sbody] ...) ([(vid ...) vbody] ...) - ctc ... - (void))) - (values))))))) - (else - (syntax-case (car sig-exprs) (define-values define-syntaxes contracted) - (x - (identifier? #'x) - (loop (cdr sig-exprs) (cons #'x bindings) val-defs stx-defs post-val-defs (cons #f ctcs))) - ((x (y z) ...) - (and (identifier? #'x) - (free-identifier=? #'x #'contracted) - (andmap identifier? (syntax->list #'(y ...)))) - (loop (cdr sig-exprs) - (append (syntax->list #'(y ...)) bindings) - val-defs - stx-defs - post-val-defs - (append (syntax->list #'(z ...)) ctcs))) - ((x . z) - (and (identifier? #'x) - (free-identifier=? #'x #'contracted)) - (raise-syntax-error - 'define-signature - "expected a list of [id contract] pairs after the contracted keyword" - (car sig-exprs))) - ((x . y) - (and (identifier? #'x) - (or (free-identifier=? #'x #'define-values) - (free-identifier=? #'x #'define-syntaxes) - (free-identifier=? #'x #'define-values-for-export))) - (begin - (check-def-syntax (car sig-exprs)) - (syntax-case #'y () - (((name ...) body) - (begin - (for-each (lambda (id) (check-id id)) - (syntax->list #'(name ...))) - (let ((b #'body)) - (loop (cdr sig-exprs) - bindings - (if (free-identifier=? #'x #'define-values) - (cons (cons (syntax->list #'(name ...)) b) - val-defs) - val-defs) - (if (free-identifier=? #'x #'define-syntaxes) - (cons (cons (syntax->list #'(name ...)) b) - stx-defs) - stx-defs) - (if (free-identifier=? #'x #'define-values-for-export) - (cons (cons (syntax->list #'(name ...)) b) - post-val-defs) - post-val-defs) - ctcs))))))) - ((x . y) - (let ((trans - (set!-trans-extract - (syntax-local-value - ;; redirect struct~ to struct~r - (if (free-identifier=? #'x #'struct~) - #'struct~r - (syntax-local-introduce #'x)) - (lambda () - (raise-stx-err "unknown signature form" #'x)))))) - (unless (signature-form? trans) - (raise-stx-err "not a signature form" #'x)) - (let ((results ((signature-form-f trans) (car sig-exprs)))) - (unless (list? results) - (raise-stx-err - (format "expected list of results from signature form, got ~e" results) - (car sig-exprs))) - (loop (append results (cdr sig-exprs)) - bindings - val-defs - stx-defs - post-val-defs - ctcs)))) - (x (raise-stx-err - "expected either an identifier or signature form" - #'x)))))))) - - -(define-syntax/err-param (define-signature stx) - (syntax-case stx (extends) - ((_ sig-name sig-exprs) - (begin - (check-id #'sig-name) - (build-define-signature #'sig-name #f #'sig-exprs))) - ((_ sig-name extends super-name sig-exprs) - (begin - (check-id #'sig-name) - (check-id #'super-name) - (build-define-signature #'sig-name #'super-name #'sig-exprs))) - (_ - (begin - (checked-syntax->list stx) - (raise-stx-err - (format "expected syntax matching (~a identifier (sig-expr ...)) or (~a identifier extends identifier (sig-expr ...))" - (syntax-e (stx-car stx)) (syntax-e (stx-car stx)))))))) - -(define-for-syntax (signature->identifiers sigids) - (define provide-tagged-sigs (map process-tagged-import sigids)) - (define provide-sigs (map caddr provide-tagged-sigs)) - (map sig-int-names provide-sigs)) - -(define-syntax/err-param (provide-signature-elements stx) - (syntax-case stx () - ((_ . p) - (let* ((sigs (checked-syntax->list #'p)) - (nameses (signature->identifiers sigs)) - ;; Export only the names that would be visible to uses - ;; with the same lexical context as p. Otherwise, we - ;; can end up with collisions with renamings that are - ;; symbolically the same, such as those introduced by - ;; `open'. - (nameses (map (lambda (sig names) - (filter (lambda (name) - (bound-identifier=? - name - (datum->syntax sig (syntax-e name)))) - names)) - sigs nameses)) - (names (apply append nameses)) - (dup (check-duplicate-identifier names))) - (when dup - (raise-stx-err (format "duplicate binding for ~.s" (syntax-e dup)))) - (quasisyntax/loc stx - (provide #,@names)))))) - -;; A unit is -;; - (unit (import import-spec ...) (export export-spec ...) unit-body-expr ...) - -(define-for-syntax (localify exp def-ctx) - (cadr (syntax->list - (local-expand #`(stop #,exp) - 'expression - (list #'stop) - def-ctx)))) - -(define-for-syntax (tagged-sigid->tagged-siginfo x) - (cons (car x) - (signature-siginfo (lookup-signature (cdr x))))) - -(define-for-syntax (make-import-unboxing var renamings loc ctc) - (if ctc - (with-syntax ([ctc-stx (syntax-property ctc 'inferred-name var)]) - (quasisyntax/loc (error-syntax) - (quote-syntax (let ([v/c (#,loc)]) - (if (pair? v/c) - (contract (let-syntax #,renamings ctc-stx) (car v/c) (cdr v/c) - (current-contract-region) - (quote #,var) (quote-srcloc #,var)) - (error 'unit "contracted import ~a used before definition" - (quote #,(syntax->datum var)))))))) - (quasisyntax/loc (error-syntax) - (quote-syntax (#,loc))))) - -;; build-unit : syntax-object -> -;; (values syntax-object (listof identifier) (listof identifier)) -;; constructs the code for a unit expression. stx must be -;; such that it passes check-unit-syntax. -;; The two additional values are the identifiers of the unit's import and export -;; signatures -(define-for-syntax (build-unit stx) - (syntax-case stx (import export init-depend) - (((import i ...) - (export e ...) - (init-depend id ...) - . body) - - (let* ([d (syntax->list #'(id ...))] - [dep-tagged-sigids (map check-tagged-id d)] - [dep-tagged-siginfos - (map tagged-sigid->tagged-siginfo dep-tagged-sigids)]) - - (define-values (isig tagged-import-sigs import-tagged-infos - import-tagged-sigids import-sigs) - (process-unit-import #'(i ...))) - - (define-values (esig tagged-export-sigs export-tagged-infos - export-tagged-sigids export-sigs) - (process-unit-export #'(e ...))) - - (check-duplicate-sigs import-tagged-infos isig dep-tagged-siginfos d) - - (check-duplicate-subs export-tagged-infos esig) - - (check-unit-ie-sigs import-sigs export-sigs) - - (with-syntax ((((dept . depr) ...) - (map - (lambda (tinfo) - (cons (car tinfo) - (syntax-local-introduce (car (siginfo-rtime-ids (cdr tinfo)))))) - dep-tagged-siginfos)) - [((renames (mac ...) (val ...)) ...) - (map build-val+macro-defs import-sigs)] - [(((int-ivar . ext-ivar) ...) ...) (map car import-sigs)] - [(((int-evar . ext-evar) ...) ...) (map car export-sigs)] - [((((e-post-id ...) . _) ...) ...) (map (lambda (s) (list-ref s 4)) export-sigs)] - [((post-renames (e-post-rhs ...)) ...) (map build-post-val-defs export-sigs)] - [((iloc ...) ...) - (map (lambda (x) (generate-temporaries (car x))) import-sigs)] - [((eloc ...) ...) - (map (lambda (x) (generate-temporaries (car x))) export-sigs)] - [((ectc ...) ...) - (map (λ (sig) - (map (λ (ctc) - (if ctc - (cons 'contract ctc) - #f)) - (cadddr sig))) export-sigs)] - [((import-key import-super-keys ...) ...) - (map tagged-info->keys import-tagged-infos)] - [((export-key ...) ...) - (map tagged-info->keys export-tagged-infos)] - [(import-name ...) - (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) - import-tagged-infos)] - [(export-name ...) - (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) - export-tagged-infos)] - [name (syntax-local-infer-name (error-syntax))] - [(icount ...) (map - (lambda (import) (length (car import))) - import-sigs)]) - (values - (quasisyntax/loc (error-syntax) - (make-unit - 'name - (vector-immutable (cons 'import-name - (vector-immutable import-key import-super-keys ...)) ...) - (vector-immutable (cons 'export-name - (vector-immutable export-key ...)) ...) - (list (cons 'dept depr) ...) - (syntax-parameterize ([current-contract-region (lambda (stx) #'(quote (unit name)))]) - (lambda () - (let ([eloc (box undefined)] ... ...) - (values - (lambda (import-table) - (let-values ([(iloc ...) - (vector->values (hash-ref import-table import-key) 0 icount)] - ...) - (letrec-syntaxes (#,@(map (lambda (ivs e-ivs ils ics) - (with-syntax ([renamings - (map (λ (ev iv) - #`(#,ev - (make-rename-transformer - (quote-syntax #,iv)))) - (syntax->list e-ivs) - (syntax->list ivs))]) - (quasisyntax/loc (error-syntax) - [#,ivs - (make-id-mappers - #,@(map (lambda (iv l c) - (make-import-unboxing iv #'renamings l c)) - (syntax->list ivs) - (syntax->list ils) - ics))]))) - (syntax->list #'((int-ivar ...) ...)) - (syntax->list #'((ext-ivar ...) ...)) - (syntax->list #'((iloc ...) ...)) - (map cadddr import-sigs))) - (letrec-syntaxes+values (renames ... - mac ... ...) - (val ... ...) - (unit-body #,(error-syntax) - (int-ivar ... ...) - (int-evar ... ...) - (eloc ... ...) - (ectc ... ...) - (begin . body) - (define-values (e-post-id ...) - (letrec-syntaxes+values (post-renames ...) () - e-post-rhs)) ... ...))))) - (unit-export ((export-key ...) (vector-immutable (λ () (unbox eloc)) ...)) ...))))))) - import-tagged-sigids - export-tagged-sigids - dep-tagged-sigids)))))) - -(define-syntax/err-param (:unit stx) - (syntax-case stx () - ((_ . x) - (begin - (let-values (((u x y z) (build-unit (check-unit-syntax #'x)))) - u))))) - -(define-syntax (unit-body stx) - (syntax-case stx () - ((_ err-stx ivars evars elocs ectcs body ...) - (parameterize ((error-syntax #'err-stx)) - (let* ([expand-context (generate-expand-context)] - [def-ctx (syntax-local-make-definition-context)] - [stop-list - (append - (kernel-form-identifier-list) - (syntax->list #'ivars))] - [definition? - (lambda (id) - (and (identifier? id) - (or (free-identifier=? id (quote-syntax define-values)) - (free-identifier=? id (quote-syntax define-syntaxes)))))] - [expanded-body - (let expand-all ((defns&exprs (syntax->list #'(body ...)))) - ;; Also lifted from Matthew, to expand the body enough - (apply - append - (map - (lambda (defn-or-expr) - (let ([defn-or-expr - (local-expand - defn-or-expr - expand-context - stop-list - def-ctx)]) - (syntax-case defn-or-expr (begin define-values define-syntaxes) - [(begin . l) - (let ([l (parameterize ((error-syntax defn-or-expr)) - (checked-syntax->list #'l))]) - (expand-all (map (lambda (s) - (syntax-track-origin s defn-or-expr #'begin)) - l)))] - [(define-syntaxes (id ...) rhs) - (andmap identifier? (syntax->list #'(id ...))) - (with-syntax ([rhs (local-transformer-expand - #'rhs - 'expression - null)]) - (syntax-local-bind-syntaxes (syntax->list #'(id ...)) #'rhs def-ctx) - (list #'(define-syntaxes (id ...) rhs)))] - [(define-values (id ...) rhs) - (andmap identifier? (syntax->list #'(id ...))) - (begin - (syntax-local-bind-syntaxes (syntax->list #'(id ...)) #f def-ctx) - (list defn-or-expr))] - [else (list defn-or-expr)]))) - defns&exprs)))] - ;; Get all the defined names, sorting out variable definitions - ;; from syntax definitions. - [defined-names-table - (let ((table (make-bound-identifier-mapping))) - (for-each - (lambda (defn-or-expr) - (syntax-case defn-or-expr () - ((dv . rest) - (definition? #'dv) - (begin - (check-def-syntax defn-or-expr) - (syntax-case #'rest () - [((id ...) expr) - (for-each - (lambda (id) - (when (bound-identifier-mapping-get table id (lambda () #f)) - (raise-stx-err "variable defined twice" id)) - (bound-identifier-mapping-put! - table id - (make-var-info (free-identifier=? #'dv (quote-syntax define-syntaxes)) - #f - id - #f))) - (syntax->list #'(id ...)))] - [_ (void)]))) - [_ (void)])) - expanded-body) - table)]) - (internal-definition-context-seal def-ctx) - - ;; Mark exported names and - ;; check that all exported names are defined (as var): - (for-each - (lambda (name loc ctc) - (let ([v (bound-identifier-mapping-get defined-names-table - name - (lambda () #f))]) - (unless v - (raise-stx-err (format "undefined export ~a" (syntax-e name)))) - (when (var-info-syntax? v) - (raise-stx-err "cannot export syntax from a unit" name)) - (set-var-info-exported?! v loc) - (when (pair? (syntax-e ctc)) - (set-var-info-ctc! v (localify (cdr (syntax-e ctc)) def-ctx))))) - (syntax->list (localify #'evars def-ctx)) - (syntax->list #'elocs) - (syntax->list #'ectcs)) - - ;; Check that none of the imports are defined - (for-each - (lambda (i) - (let ((defid (bound-identifier-mapping-get defined-names-table - i - (lambda () #f)))) - (when defid - (raise-stx-err - "definition for imported identifier" - (var-info-id defid))))) - (syntax->list (localify #'ivars def-ctx))) - - (let ([marker (lambda (id) ((make-syntax-introducer) (datum->syntax #f (syntax-e id))))]) - (with-syntax ([(defn-or-expr ...) - (apply append - (map (λ (defn-or-expr) - (syntax-case defn-or-expr (define-values) - [(define-values (id ...) body) - (let* ([ids (syntax->list #'(id ...))] - [tmps (map marker ids)] - [do-one - (λ (id tmp) - (let ([var-info (bound-identifier-mapping-get - defined-names-table - id)]) - (cond - [(var-info-exported? var-info) - => - (λ (export-loc) - (let ([ctc (var-info-ctc var-info)]) - (list (if ctc - (quasisyntax/loc defn-or-expr - (begin - (contract #,ctc #,tmp - (current-contract-region) - 'cant-happen - (quote #,id) - (quote-srcloc #,id)) - (set-box! #,export-loc - (cons #,tmp (current-contract-region))))) - (quasisyntax/loc defn-or-expr - (set-box! #,export-loc #,tmp))) - (quasisyntax/loc defn-or-expr - (define-syntax #,id - (make-id-mapper (quote-syntax #,tmp)))))))] - [else (list (quasisyntax/loc defn-or-expr - (define-syntax #,id - (make-rename-transformer (quote-syntax #,tmp)))))])))]) - (cons (quasisyntax/loc defn-or-expr - (define-values #,tmps body)) - (apply append (map do-one ids tmps))))] - [else (list defn-or-expr)])) - expanded-body))]) - #'(block defn-or-expr ...)))))))) - -(define-for-syntax (redirect-imports/exports import?) - (lambda (table-stx - import-tagged-infos - import-sigs - target-import-tagged-infos - target-import-sigs) - (define def-table (make-bound-identifier-mapping)) - (define ctc-table (make-bound-identifier-mapping)) - (define sig-table (make-bound-identifier-mapping)) - (for-each - (lambda (tagged-info sig) - (define v - #`(hash-ref #,table-stx #,(car (tagged-info->keys tagged-info)))) - (for-each - (lambda (int/ext-name index ctc) - (bound-identifier-mapping-put! def-table - (car int/ext-name) - #`(vector-ref #,v #,index)) - (bound-identifier-mapping-put! ctc-table - (car int/ext-name) - ctc) - (bound-identifier-mapping-put! sig-table - (car int/ext-name) - sig)) - (car sig) - (iota (length (car sig))) - (cadddr sig))) - import-tagged-infos - import-sigs) - (with-syntax ((((eloc ...) ...) - (map - (lambda (target-sig) - (map - (lambda (target-int/ext-name target-ctc) - (let* ([var (car target-int/ext-name)] - [vref - (bound-identifier-mapping-get - def-table - var - (lambda () - (raise-stx-err - (format (if import? - "identifier ~a is not present in new imports" - "identifier ~a is not present in old exports") - (syntax-e (car target-int/ext-name))))))] - [ctc (bound-identifier-mapping-get ctc-table var)] - [rename-bindings (get-member-bindings def-table - (bound-identifier-mapping-get sig-table var) - #'(current-contract-region))]) - (with-syntax ([ctc-stx (if ctc (syntax-property - #`(letrec-syntax #,rename-bindings #,ctc) - 'inferred-name var) - ctc)]) - (if target-ctc - #`(λ () - (cons #,(if ctc - #`(let ([old-v/c (#,vref)]) - (contract ctc-stx (car old-v/c) - (cdr old-v/c) (current-contract-region) - (quote #,var) (quote-srcloc #,var))) - #`(#,vref)) - (current-contract-region))) - (if ctc - #`(λ () - (let ([old-v/c (#,vref)]) - (contract ctc-stx (car old-v/c) - (cdr old-v/c) (current-contract-region) - (quote #,var) (quote-srcloc #,var)))) - vref))))) - (car target-sig) - (cadddr target-sig))) - target-import-sigs)) - (((export-keys ...) ...) - (map tagged-info->keys target-import-tagged-infos))) - #`(unit-export ((export-keys ...) - (vector-immutable eloc ...)) ...)))) - -(define-for-syntax redirect-imports (redirect-imports/exports #t)) -(define-for-syntax redirect-exports (redirect-imports/exports #f)) - - -;; build-unit/new-import-export : syntax-object -> -;; (values syntax-object (listof identifier) (listof identifier)) -;; constructs the code for a unit expression that changes the import and export signatures -;; of another. stx must be such that it passes check-unit-syntax. -;; The two additional values are the identifiers of the unit's import and export -;; signatures -(define-for-syntax (build-unit/new-import-export stx) - (syntax-case stx (import export init-depend) - (((import i ...) - (export e ...) - (init-depend id ...) - . body) - - (let* ([d (syntax->list #'(id ...))] - [dep-tagged-sigids (map check-tagged-id d)] - [dep-tagged-siginfos - (map tagged-sigid->tagged-siginfo dep-tagged-sigids)]) - (define-values (isig tagged-import-sigs import-tagged-infos - import-tagged-sigids import-sigs) - (process-unit-import #'(i ...))) - - (define-values (esig tagged-export-sigs export-tagged-infos - export-tagged-sigids export-sigs) - (process-unit-export #'(e ...))) - - (check-duplicate-sigs import-tagged-infos isig dep-tagged-siginfos d) - - (check-duplicate-subs export-tagged-infos esig) - - (check-unit-ie-sigs import-sigs export-sigs) - - (syntax-case #'body () - ((b) (check-link-line-syntax #'b)) - (() (raise-stx-err "missing unit specification")) - (_ (raise-stx-err "expects a single unit specification"))) - - (with-syntax (((((orig-e ...) unit-exp orig-i ...)) #'body)) - (define-values (orig-isig orig-tagged-import-sigs orig-import-tagged-infos - orig-import-tagged-sigids orig-import-sigs) - (process-unit-export #'(orig-i ...))) - - (define-values (orig-esig orig-tagged-export-sigs orig-export-tagged-infos - orig-export-tagged-sigids orig-export-sigs) - (process-unit-import #'(orig-e ...))) - (with-syntax ((((dept . depr) ...) - (map - (lambda (tinfo) - (cons (car tinfo) - (syntax-local-introduce (car (siginfo-rtime-ids (cdr tinfo)))))) - dep-tagged-siginfos)) - [((import-key ...) ...) - (map tagged-info->keys import-tagged-infos)] - [((export-key ...) ...) - (map tagged-info->keys export-tagged-infos)] - [((orig-import-key ...) ...) - (map tagged-info->keys orig-import-tagged-infos)] - [((orig-export-key ...) ...) - (map tagged-info->keys orig-export-tagged-infos)] - [(import-name ...) - (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) - import-tagged-infos)] - [(export-name ...) - (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) - export-tagged-infos)] - [(orig-import-name ...) - (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) - orig-import-tagged-infos)] - [(orig-export-name ...) - (map (lambda (tag/info) (car (siginfo-names (cdr tag/info)))) - orig-export-tagged-infos)] - [name (syntax-local-infer-name (error-syntax))] - [form (syntax-e (stx-car (error-syntax)))]) - (values - (quasisyntax/loc (error-syntax) - (let ([unit-tmp unit-exp]) - (check-unit unit-tmp 'form) - (check-sigs unit-tmp - (vector-immutable - (cons 'orig-import-name - (vector-immutable orig-import-key ...)) ...) - (vector-immutable - (cons 'orig-export-name - (vector-immutable orig-export-key ...)) ...) - 'form) - (make-unit - 'name - (vector-immutable (cons 'import-name - (vector-immutable import-key ...)) ...) - (vector-immutable (cons 'export-name - (vector-immutable export-key ...)) ...) - (list (cons 'dept depr) ...) - (syntax-parameterize ([current-contract-region (lambda (stx) #'(quote (unit name)))]) - (lambda () - (let-values ([(unit-fn export-table) ((unit-go unit-tmp))]) - (values (lambda (import-table) - (unit-fn #,(redirect-imports #'import-table - import-tagged-infos - import-sigs - orig-import-tagged-infos - orig-import-sigs))) - #,(redirect-exports #'export-table - orig-export-tagged-infos - orig-export-sigs - export-tagged-infos - export-sigs)))))))) - import-tagged-sigids - export-tagged-sigids - dep-tagged-sigids))))))) - - -(define-syntax/err-param (unit/new-import-export stx) - (syntax-case stx () - ((_ . x) - (begin - (let-values (((u x y z) (build-unit/new-import-export (check-unit-syntax #'x)))) - u))))) - -;; build-compound-unit : syntax-object -> -;; (values syntax-object (listof identifier) (listof identifier)) -;; constructs the code for a compound-unit expression. stx match the return of -;; check-compound-syntax -;; The two additional values are the identifiers of the compound-unit's import and export -;; signatures -(define-for-syntax (build-compound-unit stx) - (define-struct lnkid-record (access-code names ctime-ids rtime-ids source-idx sigid siginfo)) - (define (lnkid-rec->keys t rec) - (map (lambda (rid) (build-key t rid)) - (lnkid-record-rtime-ids rec))) - (syntax-case stx () - (((import ...) - (export-lnktag ...) - (((sub-out ...) sub-exp sub-in-lnktag ...) ...)) - (with-syntax ((((import-tag import-lnkid . import-sigid) ...) - (map check-tagged-:-clause (syntax->list #'(import ...)))) - (((export-tag . export-lnkid) ...) - (map check-tagged-id - (syntax->list #'(export-lnktag ...)))) - ((((sub-out-tag sub-out-lnkid . sub-out-sigid) ...) ...) - (map (lambda (e) (map check-tagged-:-clause (syntax->list e))) - (syntax->list #'((sub-out ...) ...)))) - ((((sub-in-tag . sub-in-lnkid) ...) ...) - (map (lambda (t) (map check-tagged-id (syntax->list t))) - (syntax->list #'((sub-in-lnktag ...) ...))))) - - (let ([dup (check-duplicate-identifier - (syntax->list #'(import-lnkid ... sub-out-lnkid ... ...)))]) - (when dup - (raise-stx-err "duplicate linking identifier definition" dup))) - - - (let ([bt (make-bound-identifier-mapping)]) - (for-each - (lambda (lnkid) - (bound-identifier-mapping-put! bt lnkid #t)) - (syntax->list #'(import-lnkid ...))) - (for-each - (lambda (lnkid) - (when (bound-identifier-mapping-get bt lnkid (lambda () #f)) - (raise-stx-err "cannot directly export an import" lnkid))) - (syntax->list #'(export-lnkid ...)))) - - - (let* ([idxs (iota (add1 (length (syntax->list #'(sub-exp ...)))))] - [sub-export-table-tmps (generate-temporaries #'(sub-exp ...))] - [link-map - (let ((bt (make-bound-identifier-mapping))) - (for-each - (lambda (tags lnkids sigids tableid i) - (for-each - (lambda (tag lnkid sigid) - (define siginfo (signature-siginfo (lookup-signature sigid))) - (define rtime-ids (map syntax-local-introduce - (siginfo-rtime-ids siginfo))) - (bound-identifier-mapping-put! - bt - lnkid - (make-lnkid-record - #`(hash-ref - #,tableid - #,(build-key (syntax-e tag) (car rtime-ids))) - (siginfo-names siginfo) - (siginfo-ctime-ids siginfo) - rtime-ids - i - sigid - siginfo))) - (syntax->list tags) - (syntax->list lnkids) - (syntax->list sigids))) - (syntax->list #'((import-tag ...) (sub-out-tag ...) ...)) - (syntax->list #'((import-lnkid ...) (sub-out-lnkid ...) ...)) - (syntax->list #'((import-sigid ...) (sub-out-sigid ...) ...)) - (cons #'import-table-id sub-export-table-tmps) - idxs) - (lambda (id) - (bound-identifier-mapping-get - bt - id - (lambda () - (raise-stx-err "unknown linking identifier" id)))))] - [link-deps - (map - (lambda (tags lnkids i) - (define ht (make-hash)) - (for-each - (lambda (t l) - (define et (syntax-e t)) - (define el (syntax-e l)) - (define rec (link-map l)) - (define forward-dep (>= (lnkid-record-source-idx rec) i)) - (define import-dep (= 0 (lnkid-record-source-idx rec))) - (for-each - (lambda (ctime-id rtime-id name) - (hash-set! ht - (build-key et ctime-id) - (list forward-dep import-dep et rtime-id name el))) - (lnkid-record-ctime-ids rec) - (lnkid-record-rtime-ids rec) - (lnkid-record-names rec))) - (syntax->list tags) - (syntax->list lnkids)) - (hash-map ht (lambda (x y) y))) - (syntax->list #'((sub-in-tag ...) ...)) - (syntax->list #'((sub-in-lnkid ...) ...)) - (cdr idxs))]) - - (check-duplicate-subs - (map (lambda (t lid) (cons (syntax-e t) - (lnkid-record-siginfo (link-map lid)))) - (syntax->list #'(export-tag ...)) - (syntax->list #'(export-lnkid ...))) - (syntax->list #'(export-lnktag ...))) - - (with-syntax (((sub-tmp ...) (generate-temporaries #'(sub-exp ...))) - ((sub-export-table-tmp ...) sub-export-table-tmps) - (name (syntax-local-infer-name (error-syntax))) - (((import-key ...) ...) - (map - (lambda (t l) - (lnkid-rec->keys (syntax-e t) (link-map l))) - (syntax->list #'(import-tag ...)) - (syntax->list #'(import-lnkid ...)))) - (((export-key ...) ...) - (map - (lambda (t l) - (lnkid-rec->keys (syntax-e t) (link-map l))) - (syntax->list #'(export-tag ...)) - (syntax->list #'(export-lnkid ...)))) - ((import-name ...) - (map (lambda (l) (car (lnkid-record-names (link-map l)))) - (syntax->list #'(import-lnkid ...)))) - ((export-name ...) - (map (lambda (l) (car (lnkid-record-names (link-map l)))) - (syntax->list #'(export-lnkid ...)))) - (((((sub-in-key sub-in-code) ...) ...) ...) - (map - (lambda (stxed-tags lnkids) - (define lnkid-recs (map link-map (syntax->list lnkids))) - (define tags (map syntax-e (syntax->list stxed-tags))) - (define tagged-siginfos - (map - (lambda (t l) (cons t (lnkid-record-siginfo l))) - tags - lnkid-recs)) - (check-duplicate-subs tagged-siginfos (syntax->list lnkids)) - (map - (lambda (t lr) - (with-syntax (((key ...) - (lnkid-rec->keys t lr))) - #`((key #,(lnkid-record-access-code lr)) ...))) - tags - lnkid-recs)) - (syntax->list #'((sub-in-tag ...) ...)) - (syntax->list #'((sub-in-lnkid ...) ...)))) - ((((sub-out-key ...) ...) ...) - (map - (lambda (lnkids tags) - (map - (lambda (l t) - (lnkid-rec->keys (syntax-e t) (link-map l))) - (syntax->list lnkids) - (syntax->list tags))) - (syntax->list #'((sub-out-lnkid ...) ...)) - (syntax->list #'((sub-out-tag ...) ...)))) - (((export-sigid . export-code) ...) - (map (lambda (lnkid) - (define s (link-map lnkid)) - (cons (lnkid-record-sigid s) - (lnkid-record-access-code s))) - (syntax->list #'(export-lnkid ...)))) - (form (syntax-e (stx-car (error-syntax)))) - ) - - (with-syntax (((check-sub-exp ...) - (map - (lambda (stx link-deps) - (with-syntax (((sub-exp - sub-tmp - ((sub-in-key ...) ...) - ((sub-out-key ...) ...) - sub-in-lnkid - sub-out-lnkid) - stx)) - (with-syntax (((sub-in-signame ...) - (map (lambda (l) (car (lnkid-record-names (link-map l)))) - (syntax->list #'sub-in-lnkid))) - ((sub-out-signame ...) - (map (lambda (l) (car (lnkid-record-names (link-map l)))) - (syntax->list #'sub-out-lnkid))) - (((fdep-tag fdep-rtime fsig-name flnk-name) ...) - (map cddr (filter car link-deps))) - (((rdep-tag rdep-rtime . _) ...) - (map cddr (filter cadr link-deps)))) - #`(begin - #,(syntax/loc #'sub-exp - (check-unit sub-tmp 'form)) - #,(syntax/loc #'sub-exp - (check-sigs sub-tmp - (vector-immutable - (cons 'sub-in-signame - (vector-immutable sub-in-key ...)) - ...) - (vector-immutable - (cons 'sub-out-signame - (vector-immutable sub-out-key ...)) - ...) - 'form)) - (let ([fht (equal-hash-table - ((cons 'fdep-tag fdep-rtime) - (cons 'fsig-name 'flnk-name)) - ...)] - [rht (equal-hash-table - ((cons 'rdep-tag rdep-rtime) - #t) - ...)]) - #,(syntax/loc #'sub-exp (check-deps fht sub-tmp 'form)) - (for-each - (lambda (dep) - (when (hash-ref rht dep #f) - (set! deps (cons dep deps)))) - (unit-deps sub-tmp))))))) - (syntax->list #'((sub-exp - sub-tmp - ((sub-in-key ...) ...) - ((sub-out-key ...) ...) - (sub-in-lnkid ...) - (sub-out-lnkid ...)) - ...)) - link-deps)) - (((sub-in-key-code-workaround ...) ...) - (map - (lambda (x) - (with-syntax ((((a ...) ...) x)) - #'(a ... ...))) - (syntax->list #'((((sub-in-key sub-in-code) ...) ...) ...)))) - ) - (values - (quasisyntax/loc (error-syntax) - (let ([deps '()] - [sub-tmp sub-exp] ...) - check-sub-exp ... - (make-unit - 'name - (vector-immutable - (cons 'import-name - (vector-immutable import-key ...)) - ...) - (vector-immutable - (cons 'export-name - (vector-immutable export-key ...)) - ...) - deps - (lambda () - (let-values ([(sub-tmp sub-export-table-tmp) ((unit-go sub-tmp))] - ...) - (values (lambda (import-table-id) - (void) - (sub-tmp (equal-hash-table sub-in-key-code-workaround ...)) - ...) - (unit-export ((export-key ...) export-code) ...))))))) - (map syntax-e (syntax->list #'((import-tag . import-sigid) ...))) - (map syntax-e (syntax->list #'((export-tag . export-sigid) ...))) - '())))))) - (((i ...) (e ...) (l ...)) - (for-each check-link-line-syntax (syntax->list #'(l ...)))))) - - -(define-syntax/err-param (compound-unit stx) - (let-values (((u x y z) - (build-compound-unit - (check-compound-syntax (syntax-case stx () ((_ . x) #'x)))))) - u)) - - -(define (invoke-unit/core unit) - (check-unit unit 'invoke-unit) - (check-no-imports unit 'invoke-unit) - (let-values ([(f exports) ((unit-go unit))]) - (f #f))) - -(define-syntax/err-param (define-values/invoke-unit/core stx) - (syntax-case stx () - ((_ unit-expr . unit-out) - (let* ((unit-out (checked-syntax->list #'unit-out)) - (tagged-out (map process-tagged-import unit-out)) - (out-tags (map car tagged-out)) - (out-sigs (map caddr tagged-out)) - (dup (check-duplicate-identifier (apply append (map sig-int-names out-sigs)))) - (out-vec (generate-temporaries out-sigs)) - (tmarker (make-syntax-introducer)) - (tmp-bindings (map (λ (s) (map tmarker (map car (car s)))) out-sigs)) - (def-table (make-bound-identifier-mapping))) - (when dup - (raise-stx-err (format "duplicate binding for ~.s" (syntax-e dup)))) - (for-each - (λ (sig new-xs) - (for-each - (λ (old new) - (bound-identifier-mapping-put! def-table old new)) - (map car (car sig)) - new-xs)) - out-sigs - tmp-bindings) - (with-syntax ((((key1 key ...) ...) (map tagged-info->keys out-tags)) - ((((int-binding . ext-binding) ...) ...) (map car out-sigs)) - ((out-vec ...) out-vec) - (((renames - (((mac-name ...) mac-body) ...) - (((val-name ...) val-body) ...)) - ...) - (map build-val+macro-defs out-sigs)) - ((out-names ...) - (map (lambda (info) (car (siginfo-names (cdr info)))) - out-tags)) - (((tmp-binding ...) ...) tmp-bindings) - (((out-code ...) ...) - (map - (lambda (os ov) - (map - (lambda (i) - #`(vector-ref #,ov #,i)) - (iota (length (car os))))) - out-sigs - out-vec)) - (((wrap-code ...) ...) - (map (λ (os ov tbs) - (define rename-bindings - (get-member-bindings def-table os #'(quote-module-name))) - (map (λ (tb i v c) - (if c - (with-syntax ([ctc-stx - (syntax-property - #`(letrec-syntax #,rename-bindings #,c) - 'inferred-name v)]) - #`(let ([v/c (#,tb)]) - (contract ctc-stx (car v/c) (cdr v/c) - (current-contract-region) - (quote #,v) (quote-srcloc #,v)))) - #`(#,tb))) - tbs - (iota (length (car os))) - (map car (car os)) - (cadddr os))) - out-sigs - out-vec - tmp-bindings))) - (quasisyntax/loc stx - (begin - (define-values (tmp-binding ... ...) - #,(syntax/loc #'unit-expr - (let ((unit-tmp unit-expr)) - (check-unit unit-tmp 'define-values/invoke-unit) - (check-sigs unit-tmp - (vector-immutable) - (vector-immutable (cons 'out-names - (vector-immutable key1 key ...)) ...) - 'define-values/invoke-unit) - (let-values (((unit-fn export-table) - ((unit-go unit-tmp)))) - (let ([out-vec (hash-ref export-table key1)] ...) - (unit-fn #f) - (values out-code ... ...)))))) - (define-values (int-binding ... ...) - (values wrap-code ... ...)) - (define-syntaxes . renames) ... - (define-syntaxes (mac-name ...) mac-body) ... ... - (define-values (val-name ...) val-body) ... ...))))) - ((_) - (raise-stx-err "missing unit expression")))) - -;; build-unit-from-context : syntax-object -> -;; (values syntax-object (listof identifier) (listof identifier)) -;; constructs the code for a unit-from-context expression. stx must be -;; such that it passes check-ufc-syntax. -;; The two additional values are the identifiers of the unit's import and export -;; signatures -(define-for-syntax (build-unit-from-context stx) - (syntax-case stx () - ((export-spec) - (let* ((tagged-export-sig (process-tagged-export #'export-spec)) - (export-sig (caddr tagged-export-sig))) - (with-syntax ((((int-id . ext-id) ...) (car export-sig)) - ((def-name ...) (generate-temporaries (map car (car export-sig))))) - (values - #'(:unit (import) (export (rename export-spec (def-name int-id) ...)) - (define def-name int-id) - ...) - null - (list (cadr tagged-export-sig)) - '())))))) - -(define-for-syntax (check-ufc-syntax stx) - (syntax-case stx () - ((export-spec) (void)) - (() - (raise-stx-err "missing export-spec")) - (_ - (raise-stx-err "nothing is permitted after export-spec")))) - -(define-syntax/err-param (unit-from-context stx) - (syntax-case stx () - ((_ . x) - (begin - (check-ufc-syntax #'x) - (let-values (((u x y z) (build-unit-from-context #'x))) - u))))) - - - -(define-for-syntax (build-define-unit-helper contracted?) - (lambda (stx build err-msg) - (syntax-case stx () - ((_ name . rest) - (begin - (check-id #'name) - (let-values (((exp i e d) (parameterize ([error-syntax (syntax-property (error-syntax) 'inferred-name (syntax-e #'name))]) - (build #'rest )))) - (with-syntax ((((itag . isig) ...) i) - (((etag . esig) ...) e) - (((deptag . depsig) ...) d) - (contracted? contracted?)) - (quasisyntax/loc (error-syntax) - (begin - (define u #,exp) - (define-syntax name - (make-set!-transformer - (make-unit-info (quote-syntax u) - (list (cons 'itag (quote-syntax isig)) ...) - (list (cons 'etag (quote-syntax esig)) ...) - (list (cons 'deptag (quote-syntax deptag)) ...) - (quote-syntax name) - contracted?))))))))) - ((_) - (raise-stx-err err-msg))))) - -;; build-define-unit : syntax-object -;; (syntax-object -> (values syntax-object (listof identifier) (listof identifier)) -;; string -> -;; syntax-object -(define-for-syntax build-define-unit (build-define-unit-helper #f)) -(define-for-syntax build-define-unit/contracted (build-define-unit-helper #t)) - -(define-for-syntax (build-define-unit-binding stx) - - (define (check-helper tagged-info) - (cons (car (siginfo-names (cdr tagged-info))) - (tagged-info->keys tagged-info))) - - (syntax-case stx (import export init-depend) - ((unit-exp (import i ...) (export e ...) (init-depend idep ...)) - (let* ([ti (syntax->list #'(i ...))] - [te (syntax->list #'(e ...))] - [tidep (syntax->list #'(idep ...))] - [tagged-import-sigids (map check-tagged-id ti)] - [tagged-export-sigids (map check-tagged-id te)] - [tagged-dep-sigids (map check-tagged-id tidep)] - [tagged-import-infos (map tagged-sigid->tagged-siginfo tagged-import-sigids)] - [tagged-export-infos (map tagged-sigid->tagged-siginfo tagged-export-sigids)] - [tagged-dep-siginfos (map tagged-sigid->tagged-siginfo tagged-dep-sigids)]) - (check-duplicate-sigs tagged-import-infos ti tagged-dep-siginfos tidep) - (check-duplicate-subs tagged-export-infos te) - (with-syntax ((((import-name . (import-keys ...)) ...) - (map check-helper tagged-import-infos)) - (((export-name . (export-keys ...)) ...) - (map check-helper tagged-export-infos)) - (form (stx-car (error-syntax)))) - (values - #`(let ([unit-tmp unit-exp]) - #,(syntax/loc #'unit-exp - (check-unit unit-tmp 'form)) - #,(syntax/loc #'unit-exp - (check-sigs unit-tmp - (vector-immutable - (cons 'import-name - (vector-immutable import-keys ...)) - ...) - (vector-immutable - (cons 'export-name - (vector-immutable export-keys ...)) - ...) - 'form)) - unit-tmp) - tagged-import-sigids - tagged-export-sigids - tagged-dep-sigids)))))) - -(define-syntax/err-param (define-unit-binding stx) - (build-define-unit stx (lambda (unit) - (build-define-unit-binding (check-unit-body-syntax unit))) - "missing unit name, unit expression, import clause, and export clause")) - -(define-syntax/err-param (define-unit stx) - (build-define-unit stx (lambda (unit) - (build-unit (check-unit-syntax unit))) - "missing unit name, import clause, and export clause")) - -(define-syntax/err-param (define-unit/new-import-export stx) - (build-define-unit stx (lambda (unit) - (build-unit/new-import-export (check-unit-syntax unit))) - "missing unit name, import clause, and export clause")) - -(define-syntax/err-param (define-compound-unit stx) - (build-define-unit stx (lambda (clauses) - (build-compound-unit (check-compound-syntax clauses))) - "missing unit name")) - -(define-syntax/err-param (define-unit-from-context stx) - (build-define-unit stx (lambda (sig) - (check-ufc-syntax sig) - (build-unit-from-context sig)) - "missing unit name and signature")) - -(define-for-syntax (build-unit/contract stx) - (syntax-parse stx - [(:import-clause/contract :export-clause/contract dep:dep-clause . body) - (let-values ([(exp isigs esigs deps) - (build-unit - (check-unit-syntax - (syntax/loc stx - ((import i.s ...) (export e.s ...) dep . body))))]) - (with-syntax ([name (syntax-local-infer-name (error-syntax))] - [(import-tagged-sig-id ...) - (map (λ (i s) - (if (identifier? i) #`(tag #,i #,s) s)) - (syntax->list #'(i.s.i ...)) - (syntax->list #'(i.s.s.name ...)))] - [(export-tagged-sig-id ...) - (map (λ (i s) - (if (identifier? i) #`(tag #,i #,s) s)) - (syntax->list #'(e.s.i ...)) - (syntax->list #'(e.s.s.name ...)))]) - (with-syntax ([new-unit exp] - [unit-contract - (unit/c/core - #'name - (syntax/loc stx - ((import (import-tagged-sig-id [i.x i.c] ...) ...) - (export (export-tagged-sig-id [e.x e.c] ...) ...))))]) - (values - (syntax/loc stx - (contract unit-contract new-unit '(unit name) (current-contract-region) (quote name) (quote-srcloc name))) - isigs esigs deps))))] - [(ic:import-clause/contract ec:export-clause/contract . body) - (build-unit/contract - (syntax/loc stx - (ic ec (init-depend) . body)))])) - -(define-syntax/err-param (define-unit/contract stx) - (build-define-unit/contracted stx (λ (stx) - (build-unit/contract stx)) - "missing unit name")) - -(define-for-syntax (unprocess-tagged-id ti) - (if (car ti) - #`(tag #,(car ti) #,(cdr ti)) - (cdr ti))) - -(define-for-syntax (temp-id-with-tags id i) - (syntax-case i (tag) - [(tag t sig) - (list id #`(tag t #,id) #'sig)] - [_else - (list id id i)])) - -(define-syntax/err-param (define-values/invoke-unit stx) - (syntax-case stx (import export) - ((_ u (import) (export e ...)) - (quasisyntax/loc stx - (define-values/invoke-unit/core u e ...))) - ((_ u (import i ...) (export e ...)) - (with-syntax (((EU ...) (generate-temporaries #'(e ...))) - (((IU IUl i) ...) (map temp-id-with-tags - (generate-temporaries #'(i ...)) - (syntax->list #'(i ...)))) - ((iu ...) (generate-temporaries #'(i ...))) - ((i-id ...) (map cdadr - (map process-tagged-import - (syntax->list #'(i ...))))) - ((e-id ...) (map cdadr - (map process-tagged-export - (syntax->list #'(e ...)))))) - (quasisyntax/loc stx - (begin - (define-unit-from-context iu i) - ... - (define-compound-unit u2 (import) - (export EU ...) - (link [((IU : i-id)) iu] ... [((EU : e-id) ...) u IUl ...])) - (define-values/invoke-unit/core u2 e ...))))) - ((_) - (raise-stx-err "missing unit" stx)) - ((_ . b) - (raise-stx-err - (format "expected syntax matching (~a (import ...) (export ...))" - (syntax-e (stx-car stx))))))) - -;; build-compound-unit/infer : syntax-object -> -;; (values syntax-object (listof identifier) (listof identifier)) -;; constructs the code for a compound-unit/infer expression. stx match the return of -;; check-compound-syntax -;; The two additional values are the identifiers of the compound-unit's import and export -;; signatures -(define-for-syntax (build-compound-unit/infer stx) - - (define (lookup-tagged tid) - (cons (car tid) (lookup-signature (cdr tid)))) - - (define (process-signature s) - (define l - ((check-tagged - (lambda (b) - (syntax-case* b (:) (lambda (x y) (eq? (syntax-e x) (syntax-e y))) - ((x : y) - (and (identifier? #'x) (identifier? #'y)) - (list #'x #'y (signature-siginfo (lookup-signature #'y)))) - (x - (identifier? #'x) - (list (car (generate-temporaries (list #'x))) - #'x - (signature-siginfo (lookup-signature #'x)))) - (_ - (raise-stx-err "expected syntax matching or ( : )" - b))))) - s)) - (apply make-link-record l)) - - (define ((process-tagged-sigid introducer) sid) - (make-link-record (car sid) #f (introducer (cdr sid)) (signature-siginfo (lookup-signature (cdr sid))))) - - (syntax-case stx () - (((import ...) - (export ...) - (((out ...) u l ...) ...)) - (let* ([us (syntax->list #'(u ...))] - [units (map lookup-def-unit us)] - [import-sigs (map process-signature - (syntax->list #'(import ...)))] - [sig-introducers (map (lambda (unit u) - (make-syntax-delta-introducer u (unit-info-orig-binder unit))) - units us)] - [sub-outs - (map - (lambda (outs unit sig-introducer) - (define o - (map - (lambda (clause) - (define c (check-tagged-:-clause clause)) - (make-link-record (car c) (cadr c) (cddr c) - (signature-siginfo (lookup-signature (cddr c))))) - (syntax->list outs))) - (complete-exports (map (process-tagged-sigid sig-introducer) (unit-info-export-sig-ids unit)) - o)) - (syntax->list #'((out ...) ...)) - units - sig-introducers)] - [link-defs (append import-sigs (apply append sub-outs))]) - - (define lnk-table (make-bound-identifier-mapping)) - (define sig-table (make-hasheq)) - - (let ([dup (check-duplicate-identifier (map link-record-linkid link-defs))]) - (when dup - (raise-stx-err "duplicate identifier" dup))) - - (for-each - (lambda (b) - (bound-identifier-mapping-put! lnk-table (link-record-linkid b) b)) - link-defs) - - (for-each - (lambda (b) - (for-each - (lambda (cid) - (define there? (hash-ref sig-table cid #f)) - (hash-set! sig-table cid (if there? 'duplicate (link-record-linkid b)))) - (siginfo-ctime-ids (link-record-siginfo b)))) - link-defs) - - (let ([sub-ins - (map - (lambda (ins unit sig-introducer unit-stx) - (define is (syntax->list ins)) - (define lrs - (map - (lambda (i) - (define tagged-lnkid (check-tagged-id i)) - (define sig - (bound-identifier-mapping-get lnk-table - (cdr tagged-lnkid) - (lambda () #f))) - (unless sig - (raise-stx-err "unknown linking identifier" i)) - (make-link-record (car tagged-lnkid) - (cdr tagged-lnkid) - (link-record-sigid sig) - (link-record-siginfo sig))) - is)) - (check-duplicate-subs - (map - (lambda (lr) (cons (link-record-tag lr) (link-record-siginfo lr))) - lrs) - is) - (complete-imports sig-table - lrs - (map (process-tagged-sigid sig-introducer) - (unit-info-import-sig-ids unit)) - unit-stx)) - (syntax->list #'((l ...) ...)) - units - sig-introducers - us)] - [exports - (map - (lambda (e) - (define tid (check-tagged-id e)) - (define lookup (bound-identifier-mapping-get - lnk-table - (cdr tid) - (lambda () #f))) - (cond - [lookup (unprocess-tagged-id tid)] - [else - (let ([lnkid (hash-ref - sig-table - (car (siginfo-ctime-ids (signature-siginfo (lookup-signature (cdr tid))))) - #f)]) - (cond - [(not lnkid) - (raise-stx-err "no sub unit exports this signature" (cdr tid))] - [(eq? lnkid 'duplicate) - (raise-stx-err "multiple sub units export this signature" (cdr tid))] - [else - (unprocess-tagged-id - (cons (car tid) lnkid))]))])) - (syntax->list #'(export ...)))]) - (with-syntax (((import ...) - (map unprocess-link-record-bind import-sigs)) - (((out ...) ...) - (map - (lambda (out) - (map unprocess-link-record-bind out)) - sub-outs)) - (((in ...) ...) - (map - (lambda (ins) - (map unprocess-link-record-use ins)) - sub-ins)) - ((unit-id ...) (map - (lambda (u stx) - (quasisyntax/loc stx #,(unit-info-unit-id u))) - units (syntax->list #'(u ...))))) - (build-compound-unit #`((import ...) - #,exports - (((out ...) unit-id in ...) ...))))))) - (((i ...) (e ...) (l ...)) - (for-each check-link-line-syntax (syntax->list #'(l ...)))))) - - -(define-for-syntax (check-compound/infer-syntax stx) - (syntax-case (check-compound-syntax stx) () - ((i e (b ...)) - (with-syntax (((b ...) - (map - (lambda (b) - (if (identifier? b) - #`(() #,b) - b)) - (syntax->list #'(b ...))))) - #'(i e (b ...)))))) - -(define-syntax/err-param (compound-unit/infer stx) - (let-values (((u i e d) - (build-compound-unit/infer - (check-compound/infer-syntax - (syntax-case stx () ((_ . x) #'x)))))) - u)) - -(define-for-syntax (do-define-compound-unit/infer stx) - (build-define-unit stx - (lambda (clause) - (build-compound-unit/infer (check-compound/infer-syntax clause))) - "missing unit name")) - -(define-syntax/err-param (define-compound-unit/infer stx) - (do-define-compound-unit/infer stx)) - -;; (syntax or listof[syntax]) boolean (boolean or listof[syntax]) -> syntax -(define-for-syntax (build-invoke-unit/infer units define? exports) - (define (imps/exps-from-unit u) - (let* ([ui (lookup-def-unit u)] - [unprocess (let ([i (make-syntax-delta-introducer u (unit-info-orig-binder ui))]) - (lambda (p) - (unprocess-tagged-id (cons (car p) (i (cdr p))))))] - [isigs (map unprocess (unit-info-import-sig-ids ui))] - [esigs (map unprocess (unit-info-export-sig-ids ui))]) - (values isigs esigs))) - (define (drop-from-other-list exp-tagged imp-tagged imp-sources) - (let loop ([ts imp-tagged] [ss imp-sources]) - (cond - [(null? ts) null] - [(ormap (lambda (tinfo2) - (and (eq? (car (car ts)) (car tinfo2)) - (siginfo-subtype (cdr tinfo2) (cdr (car ts))))) - exp-tagged) - (loop (cdr ts) (cdr ss))] - [else (cons (car ss) (loop (cdr ts) (cdr ss)))]))) - - (define (drop-duplicates tagged-siginfos sources) - (let loop ([ts tagged-siginfos] [ss sources] [res-t null] [res-s null]) - (cond - [(null? ts) (values res-t res-s)] - [(ormap (lambda (tinfo2) - (and (eq? (car (car ts)) (car tinfo2)) - (siginfo-subtype (cdr tinfo2) (cdr (car ts))))) - (cdr ts)) - (loop (cdr ts) (cdr ss) res-t res-s)] - [else (loop (cdr ts) (cdr ss) (cons (car ts) res-t) (cons (car ss) res-s))]))) - - (define (imps/exps-from-units units exports) - (define-values (isigs esigs) - (let loop ([units units] [imps null] [exps null]) - (if (null? units) - (values imps exps) - (let-values ([(i e) (imps/exps-from-unit (car units))]) - (loop (cdr units) (append i imps) (append e exps)))))) - (define-values (isig tagged-import-sigs import-tagged-infos - import-tagged-sigids import-sigs) - (process-unit-import (datum->syntax #f isigs))) - - (define-values (esig tagged-export-sigs export-tagged-infos - export-tagged-sigids export-sigs) - (process-unit-export (datum->syntax #f esigs))) - (check-duplicate-subs export-tagged-infos esig) - (let-values ([(itagged isources) (drop-duplicates import-tagged-infos isig)]) - (values (drop-from-other-list export-tagged-infos itagged isources) - (cond - [(list? exports) - (let-values ([(spec-esig spec-tagged-export-sigs spec-export-tagged-infos - spec-export-tagged-sigids spec-export-sigs) - (process-unit-export (datum->syntax #f exports))]) - (restrict-exports export-tagged-infos - spec-esig spec-export-tagged-infos))] - [else esig])))) - - (define (restrict-exports unit-tagged-exports spec-exports spec-tagged-exports) - (for-each (lambda (se ste) - (unless (ormap (lambda (ute) - (and (eq? (car ute) (car ste)) - (siginfo-subtype (cdr ute) (cdr ste)))) - unit-tagged-exports) - (raise-stx-err (format "no subunit exports signature ~a" - (syntax->datum se)) - se))) - spec-exports - spec-tagged-exports) - spec-exports) - (when (and (not define?) exports) - (error 'build-invoke-unit/infer - "internal error: exports for invoke-unit/infer")) - (when (null? units) - (raise-stx-err "no units in link clause")) - (cond [(identifier? units) - (let-values ([(isig esig) (imps/exps-from-units (list units) exports)]) - (with-syntax ([u units] - [(esig ...) esig] - [(isig ...) isig]) - (if define? - (syntax/loc (error-syntax) (define-values/invoke-unit u (import isig ...) (export esig ...))) - (syntax/loc (error-syntax) (invoke-unit u (import isig ...))))))] - [(list? units) - (let-values ([(isig esig) (imps/exps-from-units units exports)]) - (with-syntax ([(new-unit) (generate-temporaries '(new-unit))] - [(unit ...) units] - [(esig ...) esig] - [(isig ...) isig]) - (with-syntax ([u (let-values ([(u i e d) - (build-compound-unit/infer - (check-compound/infer-syntax - #'((import isig ...) - (export esig ...) - (link unit ...))))]) u)]) - (if define? - (syntax/loc (error-syntax) - (define-values/invoke-unit u - (import isig ...) (export esig ...))) - (syntax/loc (error-syntax) - (invoke-unit u - (import isig ...)))))))] - ;; just for error handling - [else (lookup-def-unit units)])) - -(define-syntax/err-param (define-values/invoke-unit/infer stx) - (syntax-case stx (export link) - [(_ (link unit ...)) - (build-invoke-unit/infer (syntax->list #'(unit ...)) #t #f)] - [(_ (export e ...) (link unit ...)) - (build-invoke-unit/infer (syntax->list #'(unit ...)) #t (syntax->list #'(e ...)))] - [(_ (export e ...) u) - (build-invoke-unit/infer #'u #t (syntax->list #'(e ...)))] - [(_ u) - (build-invoke-unit/infer #'u #t #f)] - [(_) - (raise-stx-err "missing unit" stx)] - [(_ . b) - (raise-stx-err - (format "expected syntax matching (~a [(export )] ) or (~a [(export )] (link ...))" - (syntax-e (stx-car stx)) (syntax-e (stx-car stx))))])) - -(define-syntax/err-param (invoke-unit stx) - (syntax-case stx (import) - ((_ unit) - (syntax/loc stx - (invoke-unit/core unit))) - ((_ unit (import isig ...)) - (with-syntax (((u ...) (generate-temporaries (syntax->list #'(isig ...)))) - (((U Ul isig) ...) (map temp-id-with-tags - (generate-temporaries #'(isig ...)) - (syntax->list #'(isig ...)))) - ((isig-id ...) (map cdadr - (map process-tagged-import - (syntax->list #'(isig ...)))))) - (syntax/loc stx - (let () - (define-unit-from-context u isig) - ... - (define-compound-unit u2 (import) (export) - (link [((U : isig-id)) u] ... [() unit Ul ...])) - (invoke-unit/core u2))))) - (_ (raise-stx-err (format - "expected (~a ) or (~a (import ...))" - (syntax-e (stx-car stx)) - (syntax-e (stx-car stx))))))) - -(define-syntax/err-param (invoke-unit/infer stx) - (syntax-case stx () - [(_ (link unit ...)) - (build-invoke-unit/infer (syntax->list #'(unit ...)) #f #f)] - [(_ u) (build-invoke-unit/infer #'u #f #f)] - [(_) - (raise-stx-err "missing unit" stx)] - [(_ . b) - (raise-stx-err - (format "expected syntax matching (~a ) or (~a (link ...))" - (syntax-e (stx-car stx)) (syntax-e (stx-car stx))))])) - -(define-for-syntax (build-unit/s stx) - (syntax-case stx (import export init-depend) - [((import i ...) (export e ...) (init-depend d ...) u) - (let* ([ui (lookup-def-unit #'u)] - [unprocess (let ([i (make-syntax-delta-introducer #'u (unit-info-orig-binder ui))]) - (lambda (p) - (unprocess-tagged-id (cons (car p) (i (cdr p))))))]) - (with-syntax ([(isig ...) (map unprocess (unit-info-import-sig-ids ui))] - [(esig ...) (map unprocess (unit-info-export-sig-ids ui))]) - (build-unit/new-import-export - (syntax/loc stx - ((import i ...) (export e ...) (init-depend d ...) ((esig ...) u isig ...))))))])) - -(define-syntax/err-param (define-unit/s stx) - (build-define-unit stx (λ (stx) (build-unit/s (check-unit-syntax stx))) - "missing unit name")) - -(define-syntax/err-param (unit/s stx) - (syntax-case stx () - [(_ . stx) - (let-values ([(u x y z) (build-unit/s (check-unit-syntax #'stx))]) - u)])) +(module unit racket/base + (require mzlib/unit) + (provide (except-out (all-from-out mzlib/unit) + struct struct/ctc + struct~r struct~r/ctc + struct~s struct~s/ctc) + (rename-out [struct~r/ctc struct/ctc]))) diff --git a/collects/scheme/unit.rkt b/collects/scheme/unit.rkt index 567fcd0dbb..b615375163 100644 --- a/collects/scheme/unit.rkt +++ b/collects/scheme/unit.rkt @@ -1,7 +1,9 @@ -#lang racket/base -(require racket/unit - (submod racket/unit compat)) -(provide (except-out (all-from-out racket/unit) struct/ctc) - (rename-out [struct~s struct] - [struct~s/ctc struct/ctc])) +(module unit racket/base + (require mzlib/unit) + (provide (except-out (all-from-out mzlib/unit) + struct struct/ctc + struct~s struct~s/ctc + struct~r struct~r/ctc) + (rename-out [struct~s struct] + [struct~s/ctc struct/ctc]))) diff --git a/collects/scribblings/reference/units.scrbl b/collects/scribblings/reference/units.scrbl index 878d520549..9a372cf38a 100644 --- a/collects/scribblings/reference/units.scrbl +++ b/collects/scribblings/reference/units.scrbl @@ -28,7 +28,7 @@ Units with suitably matching signatures can be @deftech{linked} together to form a larger unit, and a unit with no imports can be @deftech{invoked} to execute its body. -@note-lib[racket/unit #:use-sources (racket/unit)]{ The +@note-lib[racket/unit #:use-sources (mzlib/unit)]{ The @racketmodname[racket/unit] module name can be used as a language name with @racketfont{#lang}; see @secref["single-unit"].} @@ -783,7 +783,7 @@ name before @racketidfont{-sig}. Otherwise, the module name serves as @section{Transformer Helpers} -@defmodule[racket/unit-exptime #:use-sources (racket/unit-exptime)] +@defmodule[racket/unit-exptime #:use-sources (mzlib/unit-exptime)] The @racketmodname[racket/unit-exptime] library provides procedures that are intended for use by macro transformers. In particular, the diff --git a/collects/tests/units/test-unit.rktl b/collects/tests/units/test-unit.rktl index ab53689a06..4c29936e35 100644 --- a/collects/tests/units/test-unit.rktl +++ b/collects/tests/units/test-unit.rktl @@ -1,5 +1,5 @@ -(require (for-syntax racket/private/unit-compiletime - racket/private/unit-syntax)) +(require (for-syntax mzlib/private/unit-compiletime + mzlib/private/unit-syntax)) (require "test-harness.rkt" ;unit scheme/unit) From 4d15bcbaca0b6308683ac0de49906a7f06718ea2 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 17 Jul 2012 18:44:56 -0500 Subject: [PATCH 547/746] bring the language test up to date with the latest error messages include in the release branch, please (cherry picked from commit 8744cd781122379bf61cdc83a0c2620e3058fee5) --- collects/tests/drracket/language-test.rkt | 70 +++++++++++------------ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/collects/tests/drracket/language-test.rkt b/collects/tests/drracket/language-test.rkt index 5fbd697e1d..7bf0be20d1 100644 --- a/collects/tests/drracket/language-test.rkt +++ b/collects/tests/drracket/language-test.rkt @@ -62,19 +62,19 @@ the settings above should match r5rs (test-expression "(define-struct spider (legs))(make-spider 4)" "#" - #rx"define-values: cannot re-define a constant.*struct:spider") + #rx"define-values: assignment disallowed.*struct:spider") (test-expression "(sqrt -1)" "0+1i") (test-expression "class" (regexp "class: bad syntax in: class")) (test-expression "shared" (regexp "shared: bad syntax in: shared")) - (test-expression "(define (. x y) (* x y))" #rx"read: illegal use of \"\\.\"" "") + (test-expression "(define (. x y) (* x y))" #rx"read: illegal use of `\\.'" "") (test-expression "'(1 . 2)" "'(1 . 2)") - (test-expression "(define (f define) 1)" "" #rx"define-values: cannot re-define a constant.*: f") - (test-expression "(define (f car) 1)" "" #rx"define-values: cannot re-define a constant.*: f") - (test-expression "(define (f empty) 1)" "" #rx"define-values: cannot re-define a constant.*: f") + (test-expression "(define (f define) 1)" "" #rx"define-values: assignment disallowed.*: f") + (test-expression "(define (f car) 1)" "" #rx"define-values: assignment disallowed.*: f") + (test-expression "(define (f empty) 1)" "" #rx"define-values: assignment disallowed.*: f") (test-expression "call/cc" "#") @@ -87,11 +87,11 @@ the settings above should match r5rs (test-expression "true" "#t") (test-expression "mred^" #rx"unbound identifier in module in: mred\\^" - #rx"reference to undefined identifier.*: mred\\^") + #rx"mred\\^.*cannot reference undefined identifier") (test-expression "(eq? 'a 'A)" "#f") (test-expression "(set! x 1)" #rx"set!: unbound identifier in module in: x" - #rx"set!: cannot set undefined.*: x") + #rx"set!:.*cannot set undefined.*: x") (test-expression "(define qqq 2) (set! qqq 1)" "") (test-expression "(cond [(= 1 2) 3])" "") (test-expression "(cons 1 2)" "'(1 . 2)") @@ -99,7 +99,7 @@ the settings above should match r5rs (test-expression "'(1)" "'(1)") (test-expression "(define shrd (box 1)) (list shrd shrd)" "'(#&1 #&1)" - #rx"define-values: cannot re-define a constant.*: shrd") + #rx"define-values: assignment disallowed.*: shrd") (test-expression "(local ((define x x)) 1)" "1") (test-expression "(letrec ([x x]) 1)" "1") (test-expression "(if 1 1 1)" "1") @@ -176,7 +176,7 @@ the settings above should match r5rs (test-expression "class" (regexp "class: bad syntax in: class")) (test-expression "shared" (regexp "shared: bad syntax in: shared")) - (test-expression "(define (. x y) (* x y))" #rx"read: illegal use of \"\\.\"") + (test-expression "(define (. x y) (* x y))" #rx"read: illegal use of `\\.'") (test-expression "'(1 . 2)" "(1 . 2)") (test-expression "(define (f define) 1)" "") @@ -192,9 +192,9 @@ the settings above should match r5rs #rx"cpu time: [0-9]+ real time: [0-9]+ gc time: [0-9]+\n1") (test-expression "true" "#t") - (test-expression "mred^" #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: mred\\^") + (test-expression "mred^" #rx"{stop-multi.png} {stop-22x22.png} mred\\^.*cannot reference undefined identifier") (test-expression "(eq? 'a 'A)" "#f") - (test-expression "(set! x 1)" #rx"{stop-multi.png} {stop-22x22.png} set!: cannot set undefined.*: x") + (test-expression "(set! x 1)" #rx"{stop-multi.png} {stop-22x22.png} set!:.*cannot set undefined.*: x") (test-expression "(define qqq 2) (set! qqq 1)" "") (test-expression "(cond [(= 1 2) 3])" "") (test-expression "(cons 1 2)" "(1 . 2)") @@ -274,32 +274,32 @@ the settings above should match r5rs (test-expression "(define-struct spider (legs))(make-spider 4)" - #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: define-struct") + #rx"{stop-multi.png} {stop-22x22.png} define-struct:.*cannot reference undefined identifier") (test-expression "(sqrt -1)" "0+1i") - (test-expression "class" #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: class") - (test-expression "shared" #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: shared") + (test-expression "class" #rx"{stop-multi.png} {stop-22x22.png} class:.*cannot reference undefined identifier") + (test-expression "shared" #rx"{stop-multi.png} {stop-22x22.png} shared:.*cannot reference undefined identifier") - (test-expression "(define (. x y) (* x y))" #rx"read: illegal use of \"\\.\"") + (test-expression "(define (. x y) (* x y))" #rx"read: illegal use of `\\.'") (test-expression "'(1 . 2)" "(1 . 2)") (test-expression "(define (f define) 1)" "") (test-expression "(define (f car) 1)" "") (test-expression "(define (f empty) 1)" "") - (test-expression "call/cc" #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: call/cc") + (test-expression "call/cc" #rx"{stop-multi.png} {stop-22x22.png} call/cc:.*cannot reference undefined identifier") - (test-expression "(error 'a \"~a\" 1)" #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: error") - (test-expression "(error \"a\" \"a\")" #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: error") + (test-expression "(error 'a \"~a\" 1)" #rx"{stop-multi.png} {stop-22x22.png} error:.*cannot reference undefined identifier") + (test-expression "(error \"a\" \"a\")" #rx"{stop-multi.png} {stop-22x22.png} error:.*cannot reference undefined identifier") (test-expression "(time 1)" - #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: time") + #rx"{stop-multi.png} {stop-22x22.png} time.*cannot reference undefined identifier") - (test-expression "true" #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: true") - (test-expression "mred^" #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: mred\\^") + (test-expression "true" #rx"{stop-multi.png} {stop-22x22.png} true.*cannot reference undefined identifier") + (test-expression "mred^" #rx"{stop-multi.png} {stop-22x22.png} mred\\^.*cannot reference undefined identifier") (test-expression "(eq? 'a 'A)" "#t") - (test-expression "(set! x 1)" #rx"{stop-multi.png} {stop-22x22.png} set!: cannot set undefined.*: x") + (test-expression "(set! x 1)" #rx"{stop-multi.png} {stop-22x22.png} set!:.*cannot set undefined.*: x") (test-expression "(define qqq 2) (set! qqq 1)" "") (test-expression "(cond ((= 1 2) 3))" "") (test-expression "(cons 1 2)" "(1 . 2)") @@ -328,7 +328,7 @@ the settings above should match r5rs (test-expression "+1/2i" "0+1/2i") (test-expression "779625/32258" "{number 779625/32258 \"24 5433/32258\" mixed}") (test-expression "(exact? 1.5)" "#f") - (test-expression "(print (floor (sqrt 2)))" #rx"reference to undefined identifier.*: print") + (test-expression "(print (floor (sqrt 2)))" #rx"print:.*cannot reference undefined identifier") (test-expression "(let ((f (lambda (x) x))) f)" "#") (test-expression ",1" "{stop-22x22.png} unquote: not in quasiquote in: (unquote 1)") @@ -337,7 +337,7 @@ the settings above should match r5rs (test-expression "(car (list))" #rx"{stop-multi.png} {stop-22x22.png} mcar: contract violation.*given: [(][)]") - (test-expression "argv" #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: argv") + (test-expression "argv" #rx"{stop-multi.png} {stop-22x22.png} argv:.*cannot reference undefined identifier") (test-expression "(define-syntax app syntax-case)" "{stop-22x22.png} macro-transformer: only a `syntax-rules' form is allowed in: syntax-case") @@ -345,7 +345,7 @@ the settings above should match r5rs (regexp (regexp-quote "#%module-begin: illegal use (not a module body) in: (#%module-begin)")) #rx"read: #lang not enabled in the current context") (test-expression "(define (f)\n(+ (raise-user-error 'a \"b\")))\n(if (zero? (random 1)) (void) (set! f void))\n(f)" - #rx"reference to undefined identifier"))) + #rx"cannot reference undefined identifier"))) ; @@ -396,8 +396,8 @@ the settings above should match r5rs (test-undefined-var "class") (test-undefined-var "shared") - (test-expression "(define (. x y) (* x y))" "read: illegal use of \".\"") - (test-expression "'(1 . 2)" "read: illegal use of \".\"") + (test-expression "(define (. x y) (* x y))" "read: illegal use of `.'") + (test-expression "'(1 . 2)" "read: illegal use of `.'") (test-undefined-var "call/cc") @@ -550,8 +550,8 @@ the settings above should match r5rs (test-undefined-var "class") (test-undefined-var "shared") - (test-expression "(define (. x y) (* x y))" "read: illegal use of \".\"") - (test-expression "'(1 . 2)" "read: illegal use of \".\"") + (test-expression "(define (. x y) (* x y))" "read: illegal use of `.'") + (test-expression "'(1 . 2)" "read: illegal use of `.'") (test-undefined-var "call/cc") @@ -699,8 +699,8 @@ the settings above should match r5rs (test-undefined-var "class") (test-undefined-var "shared") - (test-expression "(define (. x y) (* x y))" "read: illegal use of \".\"") - (test-expression "'(1 . 2)" "read: illegal use of \".\"") + (test-expression "(define (. x y) (* x y))" "read: illegal use of `.'") + (test-expression "'(1 . 2)" "read: illegal use of `.'") (test-undefined-var "call/cc") @@ -846,8 +846,8 @@ the settings above should match r5rs (test-undefined-var "class") (test-undefined-var "shared") - (test-expression "(define (. x y) (* x y))" "read: illegal use of \".\"") - (test-expression "'(1 . 2)" "read: illegal use of \".\"") + (test-expression "(define (. x y) (* x y))" "read: illegal use of `.'") + (test-expression "'(1 . 2)" "read: illegal use of `.'") (test-undefined-var "call/cc") @@ -989,8 +989,8 @@ the settings above should match r5rs (test-expression "shared" "shared: expected an open parenthesis before shared, but found none") - (test-expression "(define (. x y) (* x y))" "read: illegal use of \".\"") - (test-expression "'(1 . 2)" "read: illegal use of \".\"") + (test-expression "(define (. x y) (* x y))" "read: illegal use of `.'") + (test-expression "'(1 . 2)" "read: illegal use of `.'") (test-undefined-var "call/cc") From d53e53f837a429921ba68fb5c098ca816145471c Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 17 Jul 2012 21:58:12 -0500 Subject: [PATCH 548/746] adjusted the repl test suite for the new error messages and the change to the racket/gui load-handler (unfortunately, there is still another problem that keeps the test suite from passing) please merge to the release branch (cherry picked from commit d8204b1624b42ba5efec8a8923276f7bec6dd417) --- collects/tests/drracket/private/repl-test.rkt | 186 +++++++++--------- 1 file changed, 92 insertions(+), 94 deletions(-) diff --git a/collects/tests/drracket/private/repl-test.rkt b/collects/tests/drracket/private/repl-test.rkt index d0306cf4dd..b910be5ac2 100644 --- a/collects/tests/drracket/private/repl-test.rkt +++ b/collects/tests/drracket/private/repl-test.rkt @@ -135,20 +135,20 @@ This produces an ACK message "{stop-multi.png} {stop-22x22.png} read: expected a `)' to close `('" "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: read: expected a `)' to close `('" "{stop-22x22.png} read: expected a `)' to close `('" - "{stop-multi.png} {stop-22x22.png} read: expected a `)' to close `('" - "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: read: expected a `)' to close `('") + "{stop-22x22.png} read: expected a `)' to close `('" + "{stop-22x22.png} repl-test-tmp3.rkt:1:0: read: expected a `)' to close `('") 'definitions #f void void) (mktest "." - ("{stop-22x22.png} read: illegal use of \".\"" - "{stop-multi.png} {stop-22x22.png} read: illegal use of \".\"" - "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: read: illegal use of \".\"" - "{stop-22x22.png} read: illegal use of \".\"" - "{stop-multi.png} {stop-22x22.png} read: illegal use of \".\"" - "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: read: illegal use of \".\"") + ("{stop-22x22.png} read: illegal use of `.'" + "{stop-multi.png} {stop-22x22.png} read: illegal use of `.'" + "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: read: illegal use of `.'" + "{stop-22x22.png} read: illegal use of `.'" + "{stop-22x22.png} read: illegal use of `.'" + "{stop-22x22.png} repl-test-tmp3.rkt:1:0: read: illegal use of `.'") 'definitions #f void @@ -180,12 +180,12 @@ This produces an ACK message void) (mktest "xx" - (#rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*xx" - #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*xx" - #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: reference to undefined identifier.*xx" - #rx"reference to undefined identifier.*xx" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*xx" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*xx") + (#rx"{stop-multi.png} {stop-22x22.png} xx:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} xx:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier") 'definitions #f void @@ -253,12 +253,12 @@ This produces an ACK message ;; top-level semantics test (mktest "(define (f) (+ 1 1)) (define + -) (f)" - (#rx"define-values: cannot change constant.*: \\+" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: define-values: cannot change constant.*: \\+" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: define-values: cannot change constant.*: \\+" - #rx"define-values: cannot change constant.*: \\+" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: define-values: cannot change constant.*: \\+" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: define-values: cannot change constant.*: \\+") + (#rx"define-values:.*cannot change constant.*: \\+" + #rx"define-values:.*cannot change constant.*: \\+" + #rx"define-values:.*cannot change constant.*: \\+" + #rx"define-values:.*cannot change constant.*: \\+" + #rx"define-values:.*cannot change constant.*: \\+" + #rx"define-values:.*cannot change constant.*: \\+") 'interactions #f void @@ -289,12 +289,12 @@ This produces an ACK message void) (mktest "(begin xx (printf \"hi\\n\"))" - (#rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:7: reference to undefined identifier.*: xx" - #rx"reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: xx") + (#rx"{stop-multi.png} {stop-22x22.png} xx:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} xx:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:7: xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier") 'definitions #f void @@ -306,12 +306,12 @@ This produces an ACK message "(require 'n)\n" "s") - ("{stop-22x22.png} compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1" - "{stop-22x22.png} compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1" - "{stop-22x22.png} repl-test-tmp3.rkt:1:43: compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1" - "{stop-22x22.png} compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1" - "{stop-22x22.png} compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1" - "{stop-22x22.png} repl-test-tmp3.rkt:1:43: compile: bad syntax; literal data is not allowed, because no #%datum syntax transformer is bound in: 1") + (#rx"{stop-22x22.png} [?]: literal data is not allowed.*no #%datum syntax transformer is bound in: 1" + #rx"{stop-22x22.png} [?]: literal data is not allowed.*no #%datum syntax transformer is bound in: 1" + #rx"{stop-22x22.png} repl-test-tmp3.rkt:1:43: [?]: literal data is not allowed.*no #%datum syntax transformer is bound in: 1" + #rx"{stop-22x22.png} [?]: literal data is not allowed.*no #%datum syntax transformer is bound in: 1" + #rx"{stop-22x22.png} [?]: literal data is not allowed.*no #%datum syntax transformer is bound in: 1" + #rx"{stop-22x22.png} repl-test-tmp3.rkt:1:43: [?]: literal data is not allowed.*no #%datum syntax transformer is bound in: 1") 'definitions #f void @@ -332,12 +332,12 @@ This produces an ACK message void) (mktest "#!/bin/sh\nxx" - (#rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:2:0: reference to undefined identifier.*: xx" - #rx"reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: xx") + (#rx"{stop-multi.png} {stop-22x22.png} xx:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} xx:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:2:0: xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier") 'definitions #f void @@ -382,24 +382,24 @@ This produces an ACK message void) (mktest " (read (open-input-string \".\"))" - ("{stop-multi.png} read: illegal use of \".\"" - "{stop-multi.png} read: illegal use of \".\"" - "{stop-multi.png} read: illegal use of \".\"" - "read: illegal use of \".\"" - "{stop-multi.png} read: illegal use of \".\"" - "{stop-multi.png} read: illegal use of \".\"") + ("{stop-multi.png} read: illegal use of `.'" + "{stop-multi.png} read: illegal use of `.'" + "{stop-multi.png} read: illegal use of `.'" + "read: illegal use of `.'" + "read: illegal use of `.'" + "read: illegal use of `.'") 'interactions #f void void) (mktest " (eval 'x)" - (#rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: reference to undefined identifier.*: x" - #rx"reference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: x") + (#rx"{stop-multi.png} {stop-22x22.png} x:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} x:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: x:.*cannot reference undefined identifier" + #rx"x:.*cannot reference undefined identifier" + #rx"x:.*cannot reference undefined identifier" + #rx"x:.*cannot reference undefined identifier") 'definitions #f void @@ -435,8 +435,8 @@ This produces an ACK message #rx"{stop-multi.png} {stop-22x22.png} expt: contract violation.*given: #" #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: expt: contract violation.*given: #" #rx"expt: contract violation.*given: #" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: expt: contract violation.*given: #" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: expt: contract violation.*given: #") + #rx"expt: contract violation.*given: #" + #rx"expt: contract violation.*given: #") 'definitions #f void @@ -448,20 +448,20 @@ This produces an ACK message "{stop-multi.png} {stop-22x22.png} read: expected a `)' to close `('" "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: read: expected a `)' to close `('" "1\n2\n{stop-22x22.png} read: expected a `)' to close `('" - "{stop-multi.png} {stop-22x22.png} read: expected a `)' to close `('" - "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: read: expected a `)' to close `('") + "{stop-22x22.png} read: expected a `)' to close `('" + "{stop-22x22.png} repl-test-tmp3.rkt:1:4: read: expected a `)' to close `('") 'definitions #f void void) (mktest "1 2 . 3 4" - ("1\n2\n{stop-22x22.png} read: illegal use of \".\"" - "{stop-multi.png} {stop-22x22.png} read: illegal use of \".\"" - "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: read: illegal use of \".\"" - "1\n2\n{stop-22x22.png} read: illegal use of \".\"" - "{stop-multi.png} {stop-22x22.png} read: illegal use of \".\"" - "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: read: illegal use of \".\"") + ("1\n2\n{stop-22x22.png} read: illegal use of `.'" + "{stop-multi.png} {stop-22x22.png} read: illegal use of `.'" + "{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: read: illegal use of `.'" + "1\n2\n{stop-22x22.png} read: illegal use of `.'" + "{stop-22x22.png} read: illegal use of `.'" + "{stop-22x22.png} repl-test-tmp3.rkt:1:4: read: illegal use of `.'") 'definitions #f void @@ -480,12 +480,12 @@ This produces an ACK message void) (mktest "1 2 x 3 4" - (#rx"1\n2\n{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: reference to undefined identifier.*: x" - #rx"1\n2\nreference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: x") + (#rx"1\n2\n{stop-multi.png} {stop-22x22.png} x:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} x:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:4: x:.*cannot reference undefined identifier" + #rx"1\n2\nx:.*cannot reference undefined identifier" + #rx".*cannot reference undefined identifier" + #rx".*cannot reference undefined identifier") 'definitions #f void @@ -548,7 +548,6 @@ This produces an ACK message ;; new namespace test (mktest "(current-namespace (make-namespace))\nif" - ("{stop-22x22.png} if: bad syntax in: if" "{stop-22x22.png} if: bad syntax in: if" "{stop-22x22.png} repl-test-tmp3.rkt:2:0: if: bad syntax in: if" @@ -561,13 +560,12 @@ This produces an ACK message void) (mktest "(current-namespace (make-namespace 'empty))\nif" - - ("{stop-22x22.png} compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction" - "{stop-22x22.png} compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction" - "{stop-22x22.png} repl-test-tmp3.rkt:2:0: compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction" - "{stop-22x22.png} compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction" - "{stop-22x22.png} compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction" - "{stop-22x22.png} repl-test-tmp3.rkt:2:0: compile: unbound identifier (and no #%app syntax transformer is bound) in: #%top-interaction") + ("{stop-22x22.png} #%top-interaction: unbound identifier;\n also, no #%app syntax transformer is bound in: #%top-interaction" + "{stop-22x22.png} #%top-interaction: unbound identifier;\n also, no #%app syntax transformer is bound in: #%top-interaction" + "{stop-22x22.png} repl-test-tmp3.rkt:2:0: #%top-interaction: unbound identifier;\n also, no #%app syntax transformer is bound in: #%top-interaction" + "{stop-22x22.png} #%top-interaction: unbound identifier;\n also, no #%app syntax transformer is bound in: #%top-interaction" + "{stop-22x22.png} #%top-interaction: unbound identifier;\n also, no #%app syntax transformer is bound in: #%top-interaction" + "{stop-22x22.png} repl-test-tmp3.rkt:2:0: #%top-interaction: unbound identifier;\n also, no #%app syntax transformer is bound in: #%top-interaction") 'definitions #f void @@ -593,8 +591,8 @@ This produces an ACK message #rx"{stop-multi.png} {stop-22x22.png} expt: contract violation.*given: #f\n15" #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:5:19: expt: contract violation.*given: #f\n15" #rx"expt: contract violation.*given: #f\n15" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: expt: contract violation.*given: #f\n15" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: expt: contract violation.*given: #f\n15") + #rx"expt: contract violation.*given: #f\n15" + #rx"expt: contract violation.*given: #f\n15") 'definitions #f void @@ -758,12 +756,12 @@ This produces an ACK message void) (mktest "(define x 1)\n((λ (x y) y) (set! x (call/cc (lambda (x) x)))\n(x 3))" - (#rx"{stop-multi.png} {stop-22x22.png} application: expected procedure.*given: 3" - #rx"{stop-multi.png} {stop-22x22.png} application: expected procedure.*given: 3" - #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:3:13: application: expected procedure.*given: 3" - #rx"application: expected procedure.*given: 3" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: application: expected procedure.*given: 3" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: application: expected procedure.*given: 3") + (#rx"{stop-multi.png} {stop-22x22.png} application:.*given: 3" + #rx"{stop-multi.png} {stop-22x22.png} application:.*given: 3" + #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:3:13: application:.*given: 3" + #rx"application:.*given: 3" + #rx"application:.*given: 3" + #rx"application:.*given: 3") 'definitions #f void @@ -842,12 +840,12 @@ This produces an ACK message ;; thread tests (mktest "(begin (thread (lambda () x)) (sleep 1/10))" - (#rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: x" - #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:26: reference to undefined identifier.*: x" - #rx"reference to undefined identifier.*: x" - #rx"reference to undefined identifier.*: x" - #rx"reference to undefined identifier.*: x") + (#rx"{stop-multi.png} {stop-22x22.png} x:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} x:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:26: x:.*cannot reference undefined identifier" + #rx"x:.*cannot reference undefined identifier" + #rx"x:.*cannot reference undefined identifier" + #rx"x:.*cannot reference undefined identifier") 'definitions #f void @@ -855,12 +853,12 @@ This produces an ACK message ;; brought down from above for comparison (mktest "xx" - (#rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: reference to undefined identifier.*: xx" - #rx"reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: xx" - #rx"{stop-multi.png} {stop-22x22.png} .*rkt:[0-9]+:[0-9]+: reference to undefined identifier.*: xx") + (#rx"{stop-multi.png} {stop-22x22.png} xx:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} xx:.*cannot reference undefined identifier" + #rx"{stop-multi.png} {stop-22x22.png} repl-test-tmp3.rkt:1:0: xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier" + #rx"xx:.*cannot reference undefined identifier") 'definitions #f void From 7f96a5c228a57ce8a32d6578561da6cbed536435 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Tue, 17 Jul 2012 22:33:56 -0500 Subject: [PATCH 549/746] module lang test now up to date with error message changes please include in release branch (cherry picked from commit 17594ec804a84cec786d00da8de579696a723828) --- collects/tests/drracket/module-lang-test.rkt | 27 +++++++++----------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/collects/tests/drracket/module-lang-test.rkt b/collects/tests/drracket/module-lang-test.rkt index 7e708a4395..34d10dc4c7 100644 --- a/collects/tests/drracket/module-lang-test.rkt +++ b/collects/tests/drracket/module-lang-test.rkt @@ -85,7 +85,7 @@ #rx"first>") (test @t{(module m mzscheme (require (all-except mzlib/list foldl)))} @t{foldl} - #rx"[.] [.] reference to an identifier before its definition.*foldl") + #rx"[.] [.] foldl:.*cannot reference an identifier before its definition") (test @t{(module m mzscheme (require (prefix mz: mzscheme)))} @t{mz:+} #rx"procedure:[+]") @@ -106,7 +106,7 @@ ;; + shouldn't be bound in the REPL because it isn't bound in the module. (test @t{(module m (file @in-here{module-lang-test-tmp1.rkt}) x)} @t{+} - #rx"[.] [.] reference to an identifier before its definition.*[+]") + #rx"[.] [.] [+]:.*cannot reference an identifier before its definition") (test @t{(module m mzscheme (provide lambda))} @t{(lambda (x) x)} #rx" Date: Tue, 17 Jul 2012 16:12:33 -0600 Subject: [PATCH 550/746] typo (cherry picked from commit a3b316c02f44809d0dda5b76e587149403493714) --- collects/scribblings/reference/module-reflect.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/reference/module-reflect.scrbl b/collects/scribblings/reference/module-reflect.scrbl index 0645da7c99..d878946dd8 100644 --- a/collects/scribblings/reference/module-reflect.scrbl +++ b/collects/scribblings/reference/module-reflect.scrbl @@ -82,7 +82,7 @@ module, the @deftech{module path resolver} is also given the name of the enclosing module, so that a relative reference can be converted to an absolute symbol or @tech{resolved module path}. -A @tech{module name resolver} takes one and four arguments: +A @tech{module name resolver} takes two and four arguments: @itemize[ @item{When given two arguments, the first is a name for a module that From a0f7f72780624c37dfea2ce7d56dc1e23d0d469e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 18 Jul 2012 03:51:55 -0600 Subject: [PATCH 551/746] racket/gui/init: fix load handler (cherry picked from commit b111241afebefe801280c6633474d96e88a6cf68) --- collects/mred/private/snipfile.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/mred/private/snipfile.rkt b/collects/mred/private/snipfile.rkt index f763ea6099..d75c43de2b 100644 --- a/collects/mred/private/snipfile.rkt +++ b/collects/mred/private/snipfile.rkt @@ -327,8 +327,8 @@ (values (open-input-text-editor t 0 'end values filename) #t))] [else (values p #f)])) (when changed? - (port-count-lines! p)) ; in case it's new - (values p filename changed?))) + (port-count-lines! new-p)) ; in case it's new + (values new-p filename changed?))) (define (open-input-graphical-file filename) (let-values ([(p name wxme?) (build-input-port filename)]) From 9ba9ffb957da50fc6a8f70cb46ffc295cd4f449f Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 18 Jul 2012 22:15:40 -0400 Subject: [PATCH 552/746] Add missing meta information for the new "future-visualizer" collection. (cherry picked from commit 1635ac1bc524fa4eff1379624cd7826e7a0684e9) --- collects/meta/dist-specs.rkt | 5 ++++- collects/meta/props | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/collects/meta/dist-specs.rkt b/collects/meta/dist-specs.rkt index 3165704534..44beb41e4f 100644 --- a/collects/meta/dist-specs.rkt +++ b/collects/meta/dist-specs.rkt @@ -627,7 +627,7 @@ plt-extras :+= (- (+ (package: "games/" #:executable "plt-games") "paint-by-numbers/{hattori|solution-sets|raw-problems}") ;; -------------------- texpict & slideshow -plt-extras :+= (collects: "texpict/") +plt-extras :+= (collects: "texpict/") (package: "slideshow") ;; -------------------- frtime @@ -694,6 +694,9 @@ plt-extras :+= (package: "datalog/") ;; -------------------- db mz-extras :+= (package: "db/") (lib: "sqlite*") +;; -------------------- future-visualizer +plt-extras :+= (package: "future-visualizer/") + ;; ============================================================================ ;; Readme header diff --git a/collects/meta/props b/collects/meta/props index 577568a6b9..2d80eb7891 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -749,6 +749,7 @@ path/s is either such a string or a list of them. "collects/frtime/demos/ufo.rkt" drdr:command-line (mzc *) "collects/frtime/gui/demo" drdr:command-line (mzc *) "collects/frtime/gui.rkt" drdr:command-line (mzc *) +"collects/future-visualizer" responsible (jamesswaine) "collects/games" responsible (mflatt robby) "collects/games/chat-noir" responsible (robby matthias) "collects/games/gobblet/check.rkt" drdr:command-line (mzc "-k" *) From 601c90541d05eb5e49f8d049a01779669b7423b3 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 18 Jul 2012 22:25:02 -0400 Subject: [PATCH 553/746] Make it possible to use "~" or "~user" in the installer. I've looked for a while, and it seems that there is no easy way to do this, not even in bash, and worse with /bin/sh. So this is kind of resorting to a simple parsing of the input, and using `eval' if it starts with a tilde. Note the hack of not doing that when there is a space, otherwise the `eval' thing will silently ignore it. This hack means that it's easy to get into a mess if quotes are used after a tilde, but that was already the case with the use of `eval' to handle environment variables. It's not a real security issue, however, since we're talking about a user who can just run any command anyway. Also including a test file for the expansion functionality. If anyone wants to improve this code, making the tests pass would reveal the tricky issues. [FWIW, I've asked on the #bash channel, and the only serious suggestion was getting the paths as command-line arguments. This will, however, defeat the point of being newbie friendly...] Closes PR 12893. (cherry picked from commit 0814fd5fb5f660bc9698f21445976902317291d1) --- .../build/unix-installer/installer-header | 21 +++++++-- .../build/unix-installer/test-expand-path-var | 47 +++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100755 collects/meta/build/unix-installer/test-expand-path-var diff --git a/collects/meta/build/unix-installer/installer-header b/collects/meta/build/unix-installer/installer-header index 3edd4f7c4d..621321515f 100644 --- a/collects/meta/build/unix-installer/installer-header +++ b/collects/meta/build/unix-installer/installer-header @@ -54,6 +54,22 @@ lookfor mkdir lookfor basename lookfor dirname +# substitute env vars and tildes +expand_path_var() { + eval "expanded_val=\"\$$1\"" + first_part="${expanded_val%%/*}" + if [ "x$first_part" = "x$expanded_val" ]; then + rest_parts="" + else + rest_parts="/${expanded_val#*/}" + fi + case "x$first_part" in + x*" "* ) ;; + x~* ) expanded_val="`eval \"echo $first_part\"`$rest_parts" ;; + esac + eval "$1=\"$expanded_val\"" +} + # Need this to make new `tail' respect old-style command-line arguments. Can't # use `tail -n #' because some old tails won't know what to do with that. _POSIX2_VERSION=199209 @@ -133,11 +149,9 @@ case "x$where" in x2 ) where="/usr/local${TARGET1}" ;; x3 ) where="${HOME}${TARGET1}" ;; x4 | x. | x./ ) where="`pwd`${TARGET1}" ;; + * ) expand_path_var where ;; esac -# substitute env vars and tildes -where="`eval \"echo \\\"$where\\\"\"`" - ############################################################################### ## Default system directories prefixed by $1, mimic configure behavior ## used for unixstyle targets and for wholedir links @@ -332,6 +346,7 @@ unixstyle_install() { echon "> "; read change_what read_dir() { echon "New directory (absolute or relative to $where): "; read new_dir + expand_path_var new_dir case "$new_dir" in "/"* ) eval "$1=\"$new_dir\"" ;; * ) eval "$1=\"$where/$new_dir\"" ;; diff --git a/collects/meta/build/unix-installer/test-expand-path-var b/collects/meta/build/unix-installer/test-expand-path-var new file mode 100755 index 0000000000..f698aa132e --- /dev/null +++ b/collects/meta/build/unix-installer/test-expand-path-var @@ -0,0 +1,47 @@ +#!/bin/sh + +awk -- ' + /^expand_path_var()/ { showing = 1; } + { if (showing) print; } + /^}/ { showing = 0; } +' "`dirname \"$0\"/`/installer-header" > "/tmp/test-$$" +. "/tmp/test-$$" +rm "/tmp/test-$$" + +test() { + foo="$1" + expand_path_var foo + if [ ! "x$foo" = "x$2" ]; then + echo "fail: $1 -> $foo; expected $2" 1>&2 + exit 1 + fi +} + +test 'blah' "blah" +test 'blah blah' "blah blah" +test 'blah blah' "blah blah" +test 'blah=blah' "blah=blah" +test 'x=1 y=2 z=3' "x=1 y=2 z=3" +test '$HOME' "$HOME" +test '$HOME/foo' "$HOME/foo" +test '$HOME/ foo' "$HOME/ foo" +test '$HOME / foo' "$HOME / foo" +test '~' "$HOME" +test '~/' "$HOME/" +test '~/x' "$HOME/x" +test '~/x/y' "$HOME/x/y" +test '~/x /y' "$HOME/x /y" +test '~/ x / y ' "$HOME/ x / y " +test '~/ ' "$HOME/ " +test '~ ' "~ " +test '~eli' "$HOME" +test '~eli ' "~eli " +test '~e li' "~e li" +test '~ eli' "~ eli" +test '~eli /x' "~eli /x" +test '~root/x' "/root/x" +test '~bleh' "~bleh" +test '~bleh ' "~bleh " +test '~/x y' "$HOME/x y" +test '~/x;pwd' "$HOME/x;pwd" +echo "All tests passed." From 6e878f99fd27d06f7ce5d8c59a146d30fec6758c Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 18 Jul 2012 22:28:41 -0400 Subject: [PATCH 554/746] Disable the `#:before-first' and `#:after-last' functionality in `add-between'. Leave it working in splicing mode. I prefer doing that over always splicing them, since that would make a less uniform interface, so I rather keep all options open. There is no longer a `#:nothing' keyword, which is the main point of this downgrade. (See mailing list discussion on "no-argument" for the reason.) (cherry picked from commit 6565538b092ee082af1e2effa22c4b0ceb1b9f1a) --- collects/racket/list.rkt | 96 +++++++++++----------- collects/scribblings/reference/pairs.scrbl | 27 ++---- collects/tests/racket/list.rktl | 23 +++--- 3 files changed, 68 insertions(+), 78 deletions(-) diff --git a/collects/racket/list.rkt b/collects/racket/list.rkt index eef34514b5..fe32f68ba4 100644 --- a/collects/racket/list.rkt +++ b/collects/racket/list.rkt @@ -177,58 +177,58 @@ ;; General note: many non-tail recursive, which are just as fast in racket -(define default-nothing (gensym 'nothing)) -(define (add-between l x +(define (add-between l x #:splice? [splice? #f] - #:nothing [nothing default-nothing] - #:before-first [before-first nothing] + #:before-first [before-first '()] #:before-last [before-last x] - #:after-last [after-last nothing]) + #:after-last [after-last '()]) (unless (list? l) (raise-argument-error 'add-between "list?" 0 l x)) - (when splice? - (define (check-list x which) - (unless (list? x) - (raise-arguments-error 'add-between - (string-append "list needed in splicing mode" which) - "given" x - "given list..." l))) - (check-list x "") - (unless (eq? nothing before-first) (check-list before-first " for #:before-first")) - (check-list before-last " for #:before-last") - (unless (eq? nothing after-last) (check-list after-last " for #:after-last"))) - (if (or (null? l) (null? (cdr l))) - (let* ([r (cond [(eq? after-last nothing) '()] [splice? after-last] [else (list after-last)])] - [r (cond [(null? l) r] [(null? r) l] [(cons (car l) r)])] - [r (cond [(eq? before-first nothing) r] - [splice? (append before-first r)] - [else (cons before-first r)])]) - r) - (let* ([r ; main loop (two loops for efficiency, maybe not needed) - (if splice? - (let ([x (reverse x)] - [bl (and (not (eq? before-last x)) - (reverse before-last))]) - (let loop ([i (cadr l)] [l (cddr l)] [r '()]) - (cond [(pair? l) (loop (car l) (cdr l) (cons i (append x r)))] - [bl (cons i (append bl r))] - [else (cons i (append x r))]))) - (let loop ([i (cadr l)] [l (cddr l)] [r '()]) - (cond [(pair? l) (loop (car l) (cdr l) (cons i (cons x r)))] - [else (cons i (cons before-last r))])))] - ;; add `after-last' - [r (cond [(eq? after-last nothing) r] - [splice? (append (reverse after-last) r)] - [else (cons after-last r)])] - ;; reverse - [r (reverse r)] - ;; add first item - [r (cons (car l) r)] - ;; add `before-first' - [r (cond [(eq? before-first nothing) r] - [splice? (append before-first r)] - [else (cons before-first r)])]) - r))) + (cond + [splice? + (define (check-list x which) + (unless (list? x) + (raise-arguments-error + 'add-between + (string-append "list needed in splicing mode" which) + "given" x + "given list..." l))) + (check-list x "") + (check-list before-first " for #:before-first") + (check-list before-last " for #:before-last") + (check-list after-last " for #:after-last")] + [else + (define (check-not-given x which) + (unless (eq? '() x) + (raise-arguments-error + 'add-between + (string-append which " can only be used in splicing mode") + "given" x + "given list..." l))) + (check-not-given before-first "#:before-first") + (check-not-given after-last "#:after-last")]) + (cond + [(or (null? l) (null? (cdr l))) + (if splice? (append before-first l after-last) l)] + ;; two cases for efficiency, maybe not needed + [splice? + (let* ([x (reverse x)] + ;; main loop + [r (let loop ([i (cadr l)] [l (cddr l)] [r '()]) + (if (pair? l) + (loop (car l) (cdr l) (cons i (append x r))) + (cons i (append (reverse before-last) r))))] + ;; add `after-last' & reverse + [r (reverse (append (reverse after-last) r))] + ;; add first item and `before-first' + [r `(,@before-first ,(car l) ,@r)]) + r)] + [else + (cons (car l) + (reverse (let loop ([i (cadr l)] [l (cddr l)] [r '()]) ; main loop + (if (pair? l) + (loop (car l) (cdr l) (cons i (cons x r))) + (cons i (cons before-last r))))))])) (define (remove-duplicates l [=? equal?] #:key [key #f]) ;; `no-key' is used to optimize the case for long lists, it could be done for diff --git a/collects/scribblings/reference/pairs.scrbl b/collects/scribblings/reference/pairs.scrbl index 447e874aee..6078b74025 100644 --- a/collects/scribblings/reference/pairs.scrbl +++ b/collects/scribblings/reference/pairs.scrbl @@ -862,41 +862,30 @@ except that it can be faster. @defproc[(add-between [lst list?] [v any/c] - [#:nothing nothing any/c (gensym)] - [#:before-first before-first any/c nothing] + [#:before-first before-first list? '()] [#:before-last before-last any/c v] - [#:after-last after-last any/c nothing] + [#:after-last after-last list? '()] [#:splice? splice? any/c #f]) list?]{ Returns a list with the same elements as @racket[lst], but with @racket[v] between each pair of elements in @racket[lst]; the last pair of elements will have @racket[before-last] between them, instead -of @racket[v] (but @racket[before-last] defaults to @racket[v]). In -addition, if @racket[before-first] is supplied as a value other than -@racket[nothing], then @racket[before-first] is inserted before the first -element; if @racket[after-last] is supplied as a value other than -@racket[nothing], then @racket[after-last] is inserted after the last -element. +of @racket[v] (but @racket[before-last] defaults to @racket[v]). -If @racket[splice?] is true, then @racket[v], @racket[before-first], -@racket[before-last], and @racket[after-last] should be lists, and -the list elements are spliced into the result. +If @racket[splice?] is true, then @racket[v] and @racket[before-last] +should be lists, and the list elements are spliced into the result. In +addition, when @racket[splice?] is true, @racket[before-first] and +@racket[after-last] are inserted before the first element and after the +last element respectively. @mz-examples[#:eval list-eval (add-between '(x y z) 'and) (add-between '(x) 'and) (add-between '("a" "b" "c" "d") "," #:before-last "and") - (add-between #:before-first "Todo:" - '("a" "b" "c") "," #:before-last "and" - #:after-last ".") (add-between '(x y z) '(-) #:before-last '(- -) #:before-first '(begin) #:after-last '(end LF) #:splice? #t) - (add-between '("a" "b" "c" "d") "," - #:nothing #f #:before-first #f #:after-last "!") - (add-between '("a" "b" "c" "d") "," - #:before-first #f #:after-last "!") ]} diff --git a/collects/tests/racket/list.rktl b/collects/tests/racket/list.rktl index 8c14a3979b..4701146326 100644 --- a/collects/tests/racket/list.rktl +++ b/collects/tests/racket/list.rktl @@ -245,19 +245,20 @@ [r3 (in-list '(() (x) (x (5) y) (x (5) y (5) z) (x (5) y (5) z (5) w)))]) (test r1 add-between l 5) - (test `(0 ,@r1) add-between l 5 #:before-first 0) - (test `(,@r1 9) add-between l 5 #:after-last 9) - (test `(0 ,@r1 9) add-between l 5 #:before-first 0 #:after-last 9) + ;; (test `(0 ,@r1) add-between l 5 #:before-first 0) + ;; (test `(,@r1 9) add-between l 5 #:after-last 9) + ;; (test `(0 ,@r1 9) add-between l 5 #:before-first 0 #:after-last 9) (test r2 add-between l 5 #:before-last 7) - (test `(0 ,@r2) add-between l 5 #:before-first 0 #:before-last 7) - (test `(,@r2 9) add-between l 5 #:after-last 9 #:before-last 7) - (test `(0 ,@r2 9) add-between l 5 #:before-first 0 #:after-last 9 #:before-last 7) + ;; (test `(0 ,@r2) add-between l 5 #:before-first 0 #:before-last 7) + ;; (test `(,@r2 9) add-between l 5 #:after-last 9 #:before-last 7) + ;; (test `(0 ,@r2 9) add-between l 5 #:before-first 0 #:after-last 9 #:before-last 7) (test r3 add-between l '(5)) - (test `(0 ,@r3) add-between l '(5) #:before-first 0) - (test `(,@r3 9) add-between l '(5) #:after-last 9) - (test `(0 ,@r3 9) add-between l '(5) #:before-first 0 #:after-last 9) - (test r1 add-between l 5 #:nothing #f #:before-first #f) - (test r1 add-between l 5 #:nothing #f #:after-last #f)) + ;; (test `(0 ,@r3) add-between l '(5) #:before-first 0) + ;; (test `(,@r3 9) add-between l '(5) #:after-last 9) + ;; (test `(0 ,@r3 9) add-between l '(5) #:before-first 0 #:after-last 9) + ;; (test r1 add-between l 5 #:nothing #f #:before-first #f) + ;; (test r1 add-between l 5 #:nothing #f #:after-last #f) + ) ;; spliced cases (for* ([x (in-list '(() (4) (4 5)))] [y (in-list '(() (6) (6 7)))]) From 828452045af613d85711e89dfa953b82813b399f Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 18 Jul 2012 22:52:41 -0400 Subject: [PATCH 555/746] Fix typo from commit 12a4ee8. (cherry picked from commit 36ee9f9bbd2ccf05c17329e7414ba54a9e0d9aab) --- src/foreign/foreign.c | 50 ++++++++++++++++++++-------------------- src/foreign/foreign.rktc | 4 ++-- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/foreign/foreign.c b/src/foreign/foreign.c index eeed73bec2..230f0d0909 100644 --- a/src/foreign/foreign.c +++ b/src/foreign/foreign.c @@ -1720,7 +1720,7 @@ static void* SCHEME2C(const char *who, # ifdef SCHEME_BIG_ENDIAN if (sizeof(Tsint8) Date: Wed, 18 Jul 2012 11:59:33 -0500 Subject: [PATCH 556/746] fixed repl-test-misc.rkt for the error message changes please include on the release branch (cherry picked from commit ef5c2b825fd029d2f6a9033623233b820842dfbf) --- collects/tests/drracket/private/repl-test.rkt | 2 +- collects/tests/drracket/repl-test-misc.rkt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/collects/tests/drracket/private/repl-test.rkt b/collects/tests/drracket/private/repl-test.rkt index b910be5ac2..34a48be157 100644 --- a/collects/tests/drracket/private/repl-test.rkt +++ b/collects/tests/drracket/private/repl-test.rkt @@ -1399,7 +1399,7 @@ This produces an ACK message (let* ([end (- (get-int-pos) 1)] [output (fetch-output drscheme-frame start end)] - [expected #rx"reference to undefined identifier.*: x"]) + [expected #rx"x:.*cannot reference undefined identifier"]) (unless (regexp-match expected output) (failure) (eprintf "callcc-test: expected something matching ~s, got ~s\n" expected output))))) diff --git a/collects/tests/drracket/repl-test-misc.rkt b/collects/tests/drracket/repl-test-misc.rkt index adbed0007b..8e6f552b22 100644 --- a/collects/tests/drracket/repl-test-misc.rkt +++ b/collects/tests/drracket/repl-test-misc.rkt @@ -1,4 +1,3 @@ #lang racket/base (require "private/repl-test.rkt" "private/drracket-test-util.rkt") (fire-up-drracket-and-run-tests (λ () (run-test '(misc)))) - From f5ff23c00cef179e80acc85b38c1b852eb5136ae Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Wed, 18 Jul 2012 12:20:39 -0500 Subject: [PATCH 557/746] bring back drscheme/private/number-snip.ss since it may appear in saved wxme format files also, improve the testing support for testing snip loading (before this, the testing infrastructure could let one test "leak" into another one in a way that could mask failures) please include in release branch (cherry picked from commit b342009e7186f6a3d535670d9b5164e83b7a6940) --- collects/drscheme/private/number-snip.rkt | 9 + collects/tests/drracket/snip/number-snip.rkt | 236 +++++++++++++++++++ collects/tests/drracket/snip/run-all.rkt | 29 ++- 3 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 collects/drscheme/private/number-snip.rkt create mode 100644 collects/tests/drracket/snip/number-snip.rkt diff --git a/collects/drscheme/private/number-snip.rkt b/collects/drscheme/private/number-snip.rkt new file mode 100644 index 0000000000..bb14f3c873 --- /dev/null +++ b/collects/drscheme/private/number-snip.rkt @@ -0,0 +1,9 @@ +#lang racket/base +(require framework + racket/class + racket/snip) +(define snip-class (send (get-the-snip-class-list) find + (format "~s" `(lib "number-snip.ss" "drscheme" "private")))) +(provide snip-class) +;; this is here because there may be old number snips +;; out there that still point to this file diff --git a/collects/tests/drracket/snip/number-snip.rkt b/collects/tests/drracket/snip/number-snip.rkt new file mode 100644 index 0000000000..07043ae760 --- /dev/null +++ b/collects/tests/drracket/snip/number-snip.rkt @@ -0,0 +1,236 @@ +#reader(lib"read.ss""wxme")WXME0108 ## +#| + This file uses the GRacket editor format. + Open this file in DrRacket version 5.3.0.16 or later to read it. + + Most likely, it was created by saving a program in DrRacket, + and it probably contains a program with non-text elements + (such as images or comment boxes). + + http://racket-lang.org/ +|# + 29 7 #"wxtext\0" +3 1 6 #"wxtab\0" +1 1 8 #"wximage\0" +2 0 8 #"wxmedia\0" +4 1 34 #"(lib \"syntax-browser.ss\" \"mrlib\")\0" +1 0 16 #"drscheme:number\0" +3 0 44 #"(lib \"number-snip.ss\" \"drscheme\" \"private\")\0" +1 0 36 #"(lib \"comment-snip.ss\" \"framework\")\0" +1 0 93 +( + #"((lib \"collapsed-snipclass.ss\" \"framework\") (lib \"collapsed-sni" + #"pclass-wxme.ss\" \"framework\"))\0" +) 0 0 43 #"(lib \"collapsed-snipclass.ss\" \"framework\")\0" +0 0 19 #"drscheme:sexp-snip\0" +0 0 36 #"(lib \"cache-image-snip.ss\" \"mrlib\")\0" +1 0 68 +( + #"((lib \"image-core.ss\" \"mrlib\") (lib \"image-core-wxme.rkt\" \"mr" + #"lib\"))\0" +) 1 0 29 #"drscheme:bindings-snipclass%\0" +1 0 88 +( + #"((lib \"pict-snip.rkt\" \"drracket\" \"private\") (lib \"pict-snip.r" + #"kt\" \"drracket\" \"private\"))\0" +) 0 0 33 #"(lib \"bullet-snip.ss\" \"browser\")\0" +0 0 25 #"(lib \"matrix.ss\" \"htdp\")\0" +1 0 22 #"drscheme:lambda-snip%\0" +1 0 57 +#"(lib \"hrule-snip.rkt\" \"macro-debugger\" \"syntax-browser\")\0" +1 0 26 #"drscheme:pict-value-snip%\0" +0 0 45 #"(lib \"image-snipr.ss\" \"slideshow\" \"private\")\0" +1 0 38 #"(lib \"pict-snipclass.ss\" \"slideshow\")\0" +2 0 55 #"(lib \"vertical-separator-snip.ss\" \"stepper\" \"private\")\0" +1 0 18 #"drscheme:xml-snip\0" +1 0 31 #"(lib \"xml-snipclass.ss\" \"xml\")\0" +1 0 21 #"drscheme:scheme-snip\0" +2 0 34 #"(lib \"scheme-snipclass.ss\" \"xml\")\0" +1 0 10 #"text-box%\0" +1 0 32 #"(lib \"text-snipclass.ss\" \"xml\")\0" +1 0 1 6 #"wxloc\0" + 0 0 60 0 1 #"\0" +0 75 1 #"\0" +0 12 90 -1 90 -1 3 -1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 255 255 255 1 -1 0 9 +#"Standard\0" +0 75 7 #"Monaco\0" +0 12 90 -1 90 -1 3 -1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 255 255 255 1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 -1 -1 2 24 +#"framework:default-color\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 150 0 150 0 0 0 -1 -1 2 15 +#"text:ports out\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 150 0 150 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1.0 0 -1 -1 93 -1 -1 -1 0 0 0 0 0 0 0 0 0 1.0 1.0 1.0 255 0 0 0 0 0 -1 +-1 2 15 #"text:ports err\0" +0 -1 1 #"\0" +1.0 0 -1 -1 93 -1 -1 -1 0 0 0 0 0 0 0 0 0 1.0 1.0 1.0 255 0 0 0 0 0 -1 +-1 2 1 #"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 175 0 0 0 -1 -1 2 17 +#"text:ports value\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 175 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1.0 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1.0 1.0 1.0 34 139 34 0 0 0 -1 +-1 2 27 #"Matching Parenthesis Style\0" +0 -1 1 #"\0" +1.0 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1.0 1.0 1.0 34 139 34 0 0 0 -1 +-1 2 1 #"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 38 38 128 0 0 0 -1 -1 2 37 +#"framework:syntax-color:scheme:symbol\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 38 38 128 0 0 0 -1 -1 2 38 +#"framework:syntax-color:scheme:keyword\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 38 38 128 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 194 116 31 0 0 0 -1 -1 2 +38 #"framework:syntax-color:scheme:comment\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 194 116 31 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 41 128 38 0 0 0 -1 -1 2 37 +#"framework:syntax-color:scheme:string\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 41 128 38 0 0 0 -1 -1 2 39 +#"framework:syntax-color:scheme:constant\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 41 128 38 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 132 60 36 0 0 0 -1 -1 2 42 +#"framework:syntax-color:scheme:parenthesis\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 132 60 36 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 36 +#"framework:syntax-color:scheme:error\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 36 +#"framework:syntax-color:scheme:other\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 81 112 203 0 0 0 -1 -1 2 +38 #"drracket:check-syntax:lexically-bound\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 81 112 203 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 178 34 34 0 0 0 -1 -1 2 28 +#"drracket:check-syntax:set!d\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 178 34 34 0 0 0 -1 -1 2 37 +#"drracket:check-syntax:unused-require\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 36 +#"drracket:check-syntax:free-variable\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 68 0 203 0 0 0 -1 -1 2 31 +#"drracket:check-syntax:imported\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 68 0 203 0 0 0 -1 -1 2 47 +#"drracket:check-syntax:my-obligation-style-pref\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 178 34 34 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 116 0 0 0 0 -1 -1 2 50 +#"drracket:check-syntax:their-obligation-style-pref\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 116 0 0 0 0 -1 -1 2 48 +#"drracket:check-syntax:unk-obligation-style-pref\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 139 142 28 0 0 0 -1 -1 2 +49 #"drracket:check-syntax:both-obligation-style-pref\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 139 142 28 0 0 0 -1 -1 2 +26 #"plt:htdp:test-coverage-on\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 255 165 0 0 0 0 -1 -1 2 27 +#"plt:htdp:test-coverage-off\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 255 165 0 0 0 0 -1 -1 4 1 +#"\0" +0 70 1 #"\0" +1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1.0 1.0 1.0 1.0 1.0 1.0 0 0 0 0 0 0 +-1 -1 4 4 #"XML\0" +0 70 1 #"\0" +1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1.0 1.0 1.0 1.0 1.0 1.0 0 0 0 0 0 0 +-1 -1 2 1 #"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 34 139 34 0 0 0 -1 -1 2 37 +#"plt:module-language:test-coverage-on\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 34 139 34 0 0 0 -1 -1 2 1 +#"\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 176 48 96 0 0 0 -1 -1 2 38 +#"plt:module-language:test-coverage-off\0" +0 -1 1 #"\0" +1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 176 48 96 0 0 0 -1 -1 4 1 +#"\0" +0 71 1 #"\0" +1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1.0 1.0 1.0 1.0 1.0 1.0 0 0 0 0 0 0 +-1 -1 4 1 #"\0" +0 -1 1 #"\0" +1.0 0 -1 -1 -1 -1 -1 -1 1 0 0 0 0 0 0 0 0 1.0 1.0 1.0 0 0 255 0 0 0 -1 +-1 4 1 #"\0" +0 71 1 #"\0" +1.0 0 -1 -1 -1 -1 -1 -1 1 0 0 0 0 0 0 0 0 1.0 1.0 1.0 0 0 255 0 0 0 -1 +-1 4 1 #"\0" +0 71 1 #"\0" +1.0 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1.0 1.0 1.0 0 100 0 0 0 0 -1 +-1 0 1 #"\0" +0 75 7 #"Monaco\0" +0.0 12 90 -1 90 -1 3 -1 0 1 0 1 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0 255 +255 255 1 -1 0 1 #"\0" +0 -1 1 #"\0" +0.0 13 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1.0 1.0 1.0 1.0 1.0 1.0 0 0 0 0 0 0 +-1 -1 2 1 #"\0" +0 -1 1 #"\0" +0.0 13 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1.0 1.0 1.0 1.0 1.0 1.0 0 0 0 0 0 0 +-1 -1 4 1 #"\0" +0 71 1 #"\0" +1.0 0 -1 -1 93 -1 -1 -1 0 0 0 0 0 0 0 0 0 1.0 1.0 1.0 255 0 0 0 0 0 -1 +-1 2 1 #"\0" +0 70 1 #"\0" +1.0 0 -1 -1 93 -1 -1 -1 0 0 0 0 0 0 0 0 0 1.0 1.0 1.0 148 0 211 0 0 0 -1 +-1 2 1 #"\0" +0 70 1 #"\0" +1.0 0 -1 -1 -1 -1 -1 -1 1 0 0 0 0 0 0 0 0 1.0 1.0 1.0 0 0 255 0 0 0 -1 +-1 0 4 0 4 3 12 #"#lang racket" +0 0 4 29 1 #"\n" +0 6 10 4 4 #"5/6\0" +3 #"#e\0" +9 #"improper\0" +2 #"1\0" +0 0 4 29 1 #"\n" +0 0 diff --git a/collects/tests/drracket/snip/run-all.rkt b/collects/tests/drracket/snip/run-all.rkt index 82a4b8d186..13764d7fba 100644 --- a/collects/tests/drracket/snip/run-all.rkt +++ b/collects/tests/drracket/snip/run-all.rkt @@ -5,34 +5,45 @@ (define known-wxme-failures '("collapsed.rkt")) -(define ((record-failure f gui?) exn) - (eprintf "failed to load ~a in ~a mode\n" f (if gui? "gui" "wxme")) - ((error-display-handler) (exn-message exn) exn)) +(define (record-failure exn) + (parameterize ([current-error-port (current-output-port)]) + (set! failures (+ failures 1)) + ((error-display-handler) (exn-message exn) exn))) +(define failures 0) (define tried 0) -(define gui-namespace (make-gui-namespace)) -(define base-namespace (make-base-namespace)) +(define on (current-namespace)) (parameterize ([use-compiled-file-paths '()]) ;; setting the use-compiled-file-paths here is important ;; so we don't "cheat" by using the wxme version to compile ;; the file and then just avoid using the GUI version at all. - (for ([f (in-list (directory-list here))]) + (for ([f (in-list (sort (directory-list here) string<=? + #:key path->string))]) + + (define gui-namespace (make-gui-namespace)) + (define base-namespace (make-base-namespace)) + (define f-str (path->string f)) (unless (member f-str '("info.rkt" "run-all.rkt")) (when (regexp-match #rx"[.]rkt$" f-str) - (parameterize ([current-namespace gui-namespace]) (set! tried (+ tried 1)) - (with-handlers ((exn:fail? (record-failure f #t))) + (printf "=== trying ~a with gui-namespace\n" f) + (with-handlers ((exn:fail? record-failure)) (dynamic-require (build-path here f) #f))) (unless (member f-str known-wxme-failures) (parameterize ([current-namespace base-namespace]) (set! tried (+ tried 1)) - (with-handlers ((exn:fail? (record-failure f #f))) + (printf "=== trying ~a with base-namespace\n" f) + (with-handlers ((exn:fail? record-failure)) (dynamic-require (build-path here f) #f)))))))) (printf "tried ~a files\n" tried) +(unless (zero? failures) + (eprintf "~a attempt~a failed\n" + failures + (if (= failures 1) "" "s"))) \ No newline at end of file From 8c010ee190c60b3e40802d257052dde07c4f118c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 18 Jul 2012 08:19:49 -0500 Subject: [PATCH 558/746] collapse Racket history for v5.3 release Merge to v5.3 (cherry picked from commit 27d729c3ff418a0b82e580b5b5b4cc3bce043bc4) --- doc/release-notes/racket/HISTORY.txt | 170 +++++++++++---------------- 1 file changed, 66 insertions(+), 104 deletions(-) diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index e4dc80c1e8..c6e1679fbd 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -1,120 +1,82 @@ -Version 5.3.0.15 -Changed module name resolver notification mode to supply - a source namespace for attaches - -Version 5.3.0.12 -racket/base: added impersonate-continuation-mark-key, - chaperone-continuation-mark-key, make-continuation-mark-key, - continuation-mark-key? -racket/contract: added prompt-tag/c and continuation-mark-key/c - -Version 5.3.0.11 -Changed contract on date second field to disallow 61, since - leap seconds never appear more than once per minute -racket/base: added impersonate-prompt-tag & chaperone-prompt-tag -racket/control: added call/prompt, call/comp, abort/cc and - allow #:tag argument for % and f-control -racket/future: handling of internal stack overflow without - necessarily blocking on process 0; added 'overflow and - 'start-overflow-work log events -racket/base: guarantee portable results for current-seconds - and file-or-directory-modify-seconds -compiler/zo-structs: added a context field to all-from-module -racket/list: added optional arguments to add-between, including - #:splice?, #:before-first, #:before-last, and #:after-last - -Version 5.3.0.10 -racket/base: add progress-evt?, thread-cell-values?, prefab-key?, - semaphore-peek-evt?, channel-put-evt? -Changed #lang for most languages so that it cannot be nested; - this change is within syntax/module-reader and applies to - racket, racket/base, and more -racket/com: don't always infer 'any for the element type of a - multidimensional array -Changed local-expand to not add core forms if the stop list has - just module* -racket/math: added degrees->radians, radians->degrees, nan?, - infinite?, exact-round, exact-floor, exact-ceiling, exact-truncate; - fixed sinh and tanh to return correct answers given extreme and non- - rational values like -inf.0, -0.0, -min.0 (see unstable/flonum for - definition); fixed handling of single flonums in sinh, cosh, tanh - and sgn - -Version 5.3.0.9 +Version 5.3, August 2012 +Added submodules, including module* Changed the format of error messages Added raise-argument-error, raise-result-error, raise-arguments-error, raise-range-error -racket/contract: added procedure-arity-includes/c -racket/sandbox: added sandbox-propagate-exceptions -racket/cmdline: add #:ps for command-line -slideshow/start: run a `slideshow' or `main' submodule, if any -Changed impersonate-struct so that accessor impersonation requires - work only if the field is accessible via the current impersonator - or a mutator for the same field is also impersonated - -Version 5.3.0.8 -Required modules are instantiated in the order that they are required +Added impersonate-continuation-mark-key, + chaperone-continuation-mark-key, make-continuation-mark-key, + continuation-mark-key?, impersonate-prompt-tag, and + chaperone-prompt-tag +Added progress-evt?, thread-cell-values?, prefab-key?, + semaphore-peek-evt?, channel-put-evt? +Fixed handle-evt to disallow a handle-evt Added variable-reference->module-path-index -Added syntax-local-submodules -Added relative-in - -Version 5.3.0.7 -compiler/zo-struct: added cancel-id field to phase-shift - -Version 5.3.0.6 -racket/flonum: added flexpt -racket/unsafe/ops: added unsafe-flexpt -scribble/eval: added eval:result and eval:results - -Version 5.3.0.5 -Added box-cas! -racket/gui: changed open-output-text-editor to by default deliver - content via the current eventspace's handler thread; also - added an #:eventspace optional argument - -Version 5.3.0.4 -racket/draw: added make-color, make-brush, make-pen - -Version 5.3.0.3 -Added module-path-index-submodule +Added syntax-local-submodules, module-path-index-submodule, + and module-compiled-submodules Changed module-path-index-join to support a submodule argument - -Version 5.3.0.1 -ffi/unsafe: integer-type bounds consistently checked - -Version 5.2.900.1 -Add submodules, including module*, module-compiled-submodules Changed module-path? to report #t for paths Changed resolved module paths to allow lists that represent submodule paths; see the revised contract on resolve-module-path-name Changed the module name resolver protocol so that a module declaration - always triggers a notifification + always triggers a notifification, and a notification supplies + a source namespace (i.e., an extra argument) for attaches Changed the load/use-compiled handler protocol to subpport a submodule module -compiler/zo-struct: added pre-submodules and post-submodules field to - mod, changed name field to allow a list of symbols - -Version 5.2.1.7 -racket/sandbox: added sandbox-gui-enabled and sandbox-make-namespace; - deprecated gui?, which is no long used internally; changed the default - for sandbox-namespace-specs to sandbox-make-namespsace - -Version 5.2.1.6 -Added prop:cpointer -Fixed handle-evt to disallow a handle-evt -mysterx: removed ActiveX support plus com-add-ref and - com-ref-count -racket/draw: treat a face as a Pango font description - only when it contains a comma -racket/draw: add record-dc% - -Version 5.2.1.5 -Added racket/future to re-exports of racket Changed current-write-relative-directory to support a pair of paths: relative-to and base - -Version 5.2.1.4 -Changed ffi-lib to open libraries in local mode by default +Changed local-expand to not add core forms if the stop list has + just module* +Changed modules instantiation so that requires are instantiated + in the order that they are required +Changed #lang for most languages so that it cannot be nested; + this change is within syntax/module-reader and applies to + racket, racket/base, and more +Added relative-in +Added box-cas! +Changed contract on date second field to disallow 61, since + leap seconds never appear more than once per minute +Changed guarantee of portability of current-seconds + and file-or-directory-modify-seconds +Changed impersonate-struct so that accessor impersonation + works only if the field is accessible via the current impersonator + or a mutator for the same field is also impersonated +Added racket/future to re-exports of racket +racket/contract: added procedure-arity-includes/c, prompt-tag/c, + and continuation-mark-key/c +racket/control: added call/prompt, call/comp, abort/cc and + allow #:tag argument for % and f-control +racket/future: handle internal stack overflow without + necessarily blocking on process 0; added 'overflow and + 'start-overflow-work log events +racket/list: added optional arguments to add-between, including + #:splice?, #:before-first, #:before-last, and #:after-last +racket/math: added degrees->radians, radians->degrees, nan?, + infinite?, exact-round, exact-floor, exact-ceiling, exact-truncate +racket/flonum: added flexpt +racket/unsafe/ops: added unsafe-flexpt +ffi/unsafe: changed ffi-lib to open libraries in local mode by + default; integer-type bounds are now consistently checked; + added prop:cpointer +racket/draw: added record-dc%, make-color, make-brush, and + make-pen; treat a face as a Pango font description + only when it contains a comma +racket/gui: changed open-output-text-editor to by default deliver + content via the current eventspace's handler thread; also + added an #:eventspace optional argument +ffi/com: added +mysterx: removed ActiveX support plus com-add-ref and + com-ref-count; use ffi/com, instead +compiler/zo-structs: added a context field to all-from-module, + added a cancel-id field to phase-shift, added pre-submodules + and post-submodules field to mod, changed name field to allow + a list of symbols +racket/sandbox: added sandbox-propagate-exceptions; added + sandbox-gui-enabled and sandbox-make-namespace; deprecated gui?, + which is no long used internally; changed the default for + sandbox-namespace-specs to sandbox-make-namespsace +racket/cmdline: add #:ps for command-line +slideshow/start: run a `slideshow' or `main' submodule, if any +scribble/eval: added eval:result and eval:results Version 5.2.1, January 2012 Changed I/O scheduling to use epoll()/kqueue() when available From 5bd2ce24d99a0f070054b0a54a91e5c0f1898367 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jul 2012 07:46:34 -0500 Subject: [PATCH 559/746] fix related to module name resolver change (cherry picked from commit 9413b30599be8aa3c990a67448833f643bcd1f4a) --- src/racket/src/module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/racket/src/module.c b/src/racket/src/module.c index c88f73c745..ab25f42cee 100644 --- a/src/racket/src/module.c +++ b/src/racket/src/module.c @@ -6240,7 +6240,7 @@ static Scheme_Object *do_module_execute(Scheme_Object *data, Scheme_Env *genv, } if (!set_in_pre) { - Scheme_Object *resolver, *a[1]; + Scheme_Object *resolver, *a[2]; resolver = scheme_get_param(config, MZCONFIG_CURRENT_MODULE_RESOLVER); a[0] = m->modname; a[1] = scheme_false; From 7468ae4e3ceb8095e2884e1b7f699327a35c6088 Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Thu, 19 Jul 2012 09:46:28 -0400 Subject: [PATCH 560/746] Document `Struct`. Merge to release. (cherry picked from commit a589d027511c3a609ffbda2efaaf394c2734c1bc) --- collects/typed-racket/scribblings/reference/types.scrbl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/collects/typed-racket/scribblings/reference/types.scrbl b/collects/typed-racket/scribblings/reference/types.scrbl index 1638bcf2f3..3c02ec5a7c 100644 --- a/collects/typed-racket/scribblings/reference/types.scrbl +++ b/collects/typed-racket/scribblings/reference/types.scrbl @@ -444,6 +444,11 @@ recursive type in the body @racket[t] (define-type (List A) (Rec List (Pair A (U List Null))))]} +@defform[(Struct st)]{is a type which is a supertype of all instances of the +potentially-polymorphic structure type @racket[_st]. Note that structure +accessors for @racket[_st] will @emph{not} accept @racket[(Struct st)] as an +argument.} + @defalias[→ ->] @defalias[case→ case->] @defalias[∀ All] From c3fb6d75480641c1e68ffccb641ba4766aaf4ae3 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Thu, 19 Jul 2012 13:55:31 -0400 Subject: [PATCH 561/746] New Racket version 5.2.900. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 12 ++++++------ src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index 8dfdc8d0c7..efeb78edf6 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index abd6c0075f..59aaf51261 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,14 - PRODUCTVERSION 5,3,0,14 + FILEVERSION 5,2,900,0 + PRODUCTVERSION 5,2,900,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 3, 0, 14\0" + VALUE "FileVersion", "5, 2, 900, 0\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 3, 0, 14\0" + VALUE "ProductVersion", "5, 2, 900, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 1fb2fe0ef9..4e14eea934 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,14 - PRODUCTVERSION 5,3,0,14 + FILEVERSION 5,2,900,0 + PRODUCTVERSION 5,2,900,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 3, 0, 14" + VALUE "FileVersion", "5, 2, 900, 0" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2012 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 3, 0, 14" + VALUE "ProductVersion", "5, 2, 900, 0" END END BLOCK "VarFileInfo" @@ -105,10 +105,10 @@ CAPTION "MzCOM" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,76,69,50,14,BS_CENTER - CTEXT "MzCOM v. 5.3",IDC_STATIC,71,8,61,8 + CTEXT "MzCOM v. 5.2",IDC_STATIC,71,8,61,8 CTEXT "Copyright (c) 2000-2012 PLT (Paul Steckler)",IDC_STATIC, 41,20,146,9 - CTEXT "Racket v. 5.3",IDC_STATIC,64,35,75,8 + CTEXT "Racket v. 5.2",IDC_STATIC,64,35,75,8 CTEXT "Copyright (c) 1995-2012 PLT Inc.",IDC_STATIC, 30,47,143,8 ICON MZICON,IDC_STATIC,11,16,20,20 diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index b2ccb80d78..6c82508015 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.3.0.14 = s 'MzObj Class' + MzCOM.MzObj.5.2.900.0 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.3.0.14' + CurVer = s 'MzCOM.MzObj.5.2.900.0' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.3.0.14' + ProgID = s 'MzCOM.MzObj.5.2.900.0' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index 392ee1a9ac..f8dda35b87 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 2646d57632..45a57f90e9 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,14 - PRODUCTVERSION 5,3,0,14 + FILEVERSION 5,2,900,0 + PRODUCTVERSION 5,2,900,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 3, 0, 14\0" + VALUE "FileVersion", "5, 2, 900, 0\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 3, 0, 14\0" + VALUE "ProductVersion", "5, 2, 900, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index df67db8c04..8ca5006336 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,3,0,14 - PRODUCTVERSION 5,3,0,14 + FILEVERSION 5,2,900,0 + PRODUCTVERSION 5,2,900,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 3, 0, 14\0" + VALUE "FileVersion", "5, 2, 900, 0\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 3, 0, 14\0" + VALUE "ProductVersion", "5, 2, 900, 0\0" END END BLOCK "VarFileInfo" From 1394f0eb7db188b5726540b0bfb660467d586604 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jul 2012 10:57:12 -0500 Subject: [PATCH 562/746] macro-expander fix The "simpliciation" of a syntax object's lexical context was dropping module contexts that have no bindings, but those contexts now contribute to the identifty of some bindings. Fix simplification to replace the full rename rename with a simplified one, instead of just dropping it. Merge to v5.3 (cherry picked from commit 73e07f576b682c7c418df414f1a7e92f7c2b132d) --- src/racket/src/module.c | 5 +- src/racket/src/schpriv.h | 3 +- src/racket/src/syntax.c | 280 ++++++++++++++++++++++++++------------- 3 files changed, 195 insertions(+), 93 deletions(-) diff --git a/src/racket/src/module.c b/src/racket/src/module.c index ab25f42cee..f4a078519a 100644 --- a/src/racket/src/module.c +++ b/src/racket/src/module.c @@ -576,7 +576,7 @@ void scheme_finish_kernel(Scheme_Env *env) /* Since this is the first module rename, it's registered as the kernel module rename: */ - rn = scheme_make_module_rename(scheme_make_integer(0), mzMOD_RENAME_NORMAL, NULL, NULL); + rn = scheme_make_module_rename(scheme_make_integer(0), mzMOD_RENAME_NORMAL, NULL, NULL, NULL); for (i = kernel->me->rt->num_provides; i--; ) { scheme_extend_module_rename(rn, kernel_modidx, exs[i], exs[i], kernel_modidx, exs[i], 0, scheme_make_integer(0), NULL, 0); @@ -760,7 +760,7 @@ static Scheme_Object *scheme_sys_wraps_phase_worker(intptr_t p) { Scheme_Object *rn, *w; - rn = scheme_make_module_rename(scheme_make_integer(p), mzMOD_RENAME_NORMAL, NULL, NULL); + rn = scheme_make_module_rename(scheme_make_integer(p), mzMOD_RENAME_NORMAL, NULL, NULL, NULL); /* Add a module mapping for all kernel provides: */ scheme_extend_module_rename_with_shared(rn, kernel_modidx, @@ -835,6 +835,7 @@ void scheme_save_initial_module_set(Scheme_Env *env) initial_renames = scheme_make_module_rename(scheme_make_integer(0), mzMOD_RENAME_NORMAL, NULL, + NULL, NULL); scheme_prepare_env_renames(env, mzMOD_RENAME_TOPLEVEL); scheme_append_module_rename(scheme_get_module_rename_from_set(env->rename_set, diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index a9945f6125..12524ae011 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -1013,7 +1013,8 @@ void scheme_seal_module_rename_set(Scheme_Object *rns, int level); #define STX_SEAL_BOUND 1 #define STX_SEAL_ALL 2 -Scheme_Object *scheme_make_module_rename(Scheme_Object *phase, int kind, Scheme_Hash_Table *mns, Scheme_Object *insp); +Scheme_Object *scheme_make_module_rename(Scheme_Object *phase, int kind, Scheme_Hash_Table *mns, + Scheme_Object *insp, Scheme_Object *set_identity); Scheme_Object* scheme_extend_module_rename(Scheme_Object *rn, Scheme_Object *modname, Scheme_Object *locname, Scheme_Object *exname, Scheme_Object *nominal_src, Scheme_Object *nominal_ex, diff --git a/src/racket/src/syntax.c b/src/racket/src/syntax.c index 30ec85e160..67a1b55d84 100644 --- a/src/racket/src/syntax.c +++ b/src/racket/src/syntax.c @@ -1253,7 +1253,8 @@ Scheme_Object *scheme_get_module_rename_from_set(Scheme_Object *set, Scheme_Obje else marked_names = NULL; - mrn = (Module_Renames *)scheme_make_module_rename(phase, mrns->kind, marked_names, mrns->insp); + mrn = (Module_Renames *)scheme_make_module_rename(phase, mrns->kind, marked_names, mrns->insp, + mrns->set_identity); scheme_add_module_rename_to_set(set, (Scheme_Object *)mrn); } @@ -1283,13 +1284,13 @@ Scheme_Hash_Table *scheme_get_module_rename_marked_names(Scheme_Object *set, Sch } Scheme_Object *scheme_make_module_rename(Scheme_Object *phase, int kind, Scheme_Hash_Table *marked_names, - Scheme_Object *insp) + Scheme_Object *insp, Scheme_Object *set_identity) { Module_Renames *mr; Scheme_Hash_Table *ht; - Scheme_Object *mk; - mk = scheme_new_mark(); + if (!set_identity) + set_identity = scheme_new_mark(); mr = MALLOC_ONE_TAGGED(Module_Renames); mr->so.type = scheme_rename_table_type; @@ -1299,7 +1300,7 @@ Scheme_Object *scheme_make_module_rename(Scheme_Object *phase, int kind, Scheme_ mr->ht = ht; mr->phase = phase; mr->kind = kind; - mr->set_identity = mk; + mr->set_identity = set_identity; mr->marked_names = marked_names; mr->shared_pes = scheme_null; mr->unmarshal_info = scheme_null; @@ -1316,7 +1317,7 @@ void scheme_seal_module_rename(Scheme_Object *rn, int level) void scheme_seal_module_rename_set(Scheme_Object *_rns, int level) { Module_Renames_Set *rns = (Module_Renames_Set *)_rns; - + rns->sealed = level; if (rns->rt) rns->rt->sealed = level; @@ -1711,8 +1712,10 @@ Scheme_Object *scheme_stx_to_rename(Scheme_Object *stx) scheme_signal_error("can't convert syntax to rename (two sets)"); rns = v; } else if (SCHEME_RENAMESP(v)) { - if (!rns) + if (!rns) { rns = scheme_make_module_rename_set(((Module_Renames *)v)->kind, NULL, NULL); + ((Module_Renames_Set *)rns)->set_identity = ((Module_Renames *)v)->set_identity; + } scheme_add_module_rename_to_set(rns, v); } else { scheme_signal_error("can't convert syntax to rename (non-rename in wrap)"); @@ -1734,7 +1737,8 @@ Scheme_Object *scheme_stx_shift_rename(Scheme_Object *mrn, nmrn = scheme_make_module_rename(((Module_Renames *)mrn)->phase, mzMOD_RENAME_NORMAL, - NULL, new_insp); + NULL, new_insp, + ((Module_Renames *)mrn)->set_identity); /* use "append" to copy most info: */ do_append_module_rename(mrn, nmrn, old_midx, new_midx, 0, 0); @@ -3060,11 +3064,11 @@ static Scheme_Object *get_old_module_env(Scheme_Object *stx) Scheme_Object *result_id = scheme_false, *last_pr = NULL, *pr; WRAP_POS_INIT(awl, ((Scheme_Stx *)stx)->wraps); - + while (!WRAP_POS_END_P(awl)) { a = WRAP_POS_FIRST(awl); - + if (SCHEME_RENAMESP(a) || SCHEME_RENAMES_SETP(a)) { int kind; @@ -3119,8 +3123,9 @@ static Scheme_Object *get_old_module_env(Scheme_Object *stx) #define EXPLAIN_RESOLVE 0 #if EXPLAIN_RESOLVE -int scheme_explain_resolves = 1; +int scheme_explain_resolves = 0; # define EXPLAIN(x) if (scheme_explain_resolves) { x; } +# define EXPLAIN_FOR_ID "..." #else # define EXPLAIN(x) /* empty */ #endif @@ -3737,6 +3742,11 @@ static Scheme_Object *resolve_env(Scheme_Object *a, Scheme_Object *orig_phase, int mresult_skipped = -1; int depends_on_unsealed_rib = 0, mresult_depends_unsealed = 0; +#ifdef EXPLAIN_FOR_ID + if (!strcmp(EXPLAIN_FOR_ID, SCHEME_SYM_VAL(SCHEME_STX_VAL(a)))) + scheme_explain_resolves++; +#endif + EXPLAIN(fprintf(stderr, "%d Resolving %s@%d [skips: %s]: -------------\n", depth, SCHEME_SYM_VAL(SCHEME_STX_VAL(a)), SCHEME_INT_VAL(orig_phase), scheme_write_to_string(skip_ribs ? skip_ribs : scheme_false, NULL))); @@ -3877,6 +3887,10 @@ static Scheme_Object *resolve_env(Scheme_Object *a, Scheme_Object *orig_phase, EXPLAIN(fprintf(stderr, "%d phase %s\n", depth, scheme_write_to_string(get_names[3], NULL))); } +#ifdef EXPLAIN_FOR_ID + if (!strcmp(EXPLAIN_FOR_ID, SCHEME_SYM_VAL(SCHEME_STX_VAL(a)))) + --scheme_explain_resolves; +#endif return result; } else if ((SCHEME_RENAMESP(WRAP_POS_FIRST(wraps)) @@ -4355,6 +4369,10 @@ static Scheme_Object *resolve_env(Scheme_Object *a, Scheme_Object *orig_phase, /* Doesn't match pruned-to sym; already produce #f */ if (_depends_on_unsealed_rib) *_depends_on_unsealed_rib = depends_on_unsealed_rib; +#ifdef EXPLAIN_FOR_ID + if (!strcmp(EXPLAIN_FOR_ID, SCHEME_SYM_VAL(SCHEME_STX_VAL(a)))) + --scheme_explain_resolves; +#endif return scheme_false; } } @@ -5941,6 +5959,86 @@ static Scheme_Object *simplify_lex_renames(Scheme_Object *wraps, Scheme_Hash_Tab return v2l; } +static Scheme_Object *add_rename_to_stack(Module_Renames* mrn, Scheme_Object *stack, + Scheme_Marshal_Tables *mt, + Scheme_Object *a) +{ + Scheme_Object *local_key; + + local_key = scheme_marshal_lookup(mt, (Scheme_Object *)mrn); + if (!local_key) { + /* Convert hash table to vector, etc.: */ + int i, j, count = 0; + Scheme_Hash_Table *ht; + Scheme_Object *l, *fil; + + ht = mrn->ht; + count = ht->count; + l = scheme_make_vector(count * 2, NULL); + for (i = ht->size, j = 0; i--; ) { + if (ht->vals[i]) { + SCHEME_VEC_ELS(l)[j++] = ht->keys[i]; + fil = ht->vals[i]; + SCHEME_VEC_ELS(l)[j++] = fil; + } + } + + ht = mrn->free_id_renames; + if (ht && ht->count) { + count = ht->count; + fil = scheme_make_vector(count * 2, NULL); + for (i = ht->size, j = 0; i--; ) { + if (ht->vals[i]) { + SCHEME_VEC_ELS(fil)[j++] = ht->keys[i]; + SCHEME_VEC_ELS(fil)[j++] = ht->vals[i]; + } + } + } else + fil = NULL; + + if (mrn->marked_names && mrn->marked_names->count) { + Scheme_Object *d = scheme_null, *p; + + for (i = mrn->marked_names->size; i--; ) { + if (mrn->marked_names->vals[i] + /* #f mapping used to store reverse-map cache: */ + && !SCHEME_FALSEP(mrn->marked_names->keys[i])) { + p = CONS(mrn->marked_names->keys[i], + mrn->marked_names->vals[i]); + d = CONS(p, d); + } + } + + if (fil) + fil = CONS(fil, d); + else + fil = d; + } else if (fil) + fil = CONS(fil, scheme_null); + else + fil = scheme_null; + + l = CONS(l, fil); + + if (SCHEME_PAIRP(mrn->unmarshal_info)) + l = CONS(mrn->unmarshal_info, l); + + l = CONS(mrn->set_identity, l); + l = CONS((mrn->kind == mzMOD_RENAME_MARKED) ? scheme_true : scheme_false, l); + l = CONS(mrn->phase, l); + + local_key = scheme_marshal_lookup(mt, a); + if (local_key) + scheme_marshal_using_key(mt, a); + else { + local_key = scheme_marshal_wrap_set(mt, a, l); + } + } else { + scheme_marshal_using_key(mt, (Scheme_Object *)mrn); + } + return CONS(local_key, stack); +} + static Scheme_Object *wraps_to_datum(Scheme_Object *stx_datum, Scheme_Object *w_in, Scheme_Marshal_Tables *mt, @@ -6049,13 +6147,13 @@ static Scheme_Object *wraps_to_datum(Scheme_Object *stx_datum, /* simpliciation eliminates the need for rib delimiters */ } else if (SCHEME_RENAMESP(a) || SCHEME_RENAMES_SETP(a)) { - int which = 0; + int which = 0, all_redundant = 1; while (1) { Module_Renames *mrn; int redundant = 0; - if (SCHEME_RENAMESP(a)) { + if (SCHEME_RENAMESP(a)) { if (!which) { mrn = (Module_Renames *)a; which++; @@ -6139,6 +6237,7 @@ static Scheme_Object *wraps_to_datum(Scheme_Object *stx_datum, } if (!redundant) { + all_redundant = 0; if (just_simplify) { stack = CONS((Scheme_Object *)mrn, stack); } else { @@ -6175,86 +6274,87 @@ static Scheme_Object *wraps_to_datum(Scheme_Object *stx_datum, else stack = CONS(scheme_false, stack); } else { - Scheme_Object *local_key; - - local_key = scheme_marshal_lookup(mt, (Scheme_Object *)mrn); - if (!local_key) { - /* Convert hash table to vector, etc.: */ - int i, j, count = 0; - Scheme_Hash_Table *ht; - Scheme_Object *l, *fil; - - ht = mrn->ht; - count = ht->count; - l = scheme_make_vector(count * 2, NULL); - for (i = ht->size, j = 0; i--; ) { - if (ht->vals[i]) { - SCHEME_VEC_ELS(l)[j++] = ht->keys[i]; - fil = ht->vals[i]; - SCHEME_VEC_ELS(l)[j++] = fil; - } - } - - ht = mrn->free_id_renames; - if (ht && ht->count) { - count = ht->count; - fil = scheme_make_vector(count * 2, NULL); - for (i = ht->size, j = 0; i--; ) { - if (ht->vals[i]) { - SCHEME_VEC_ELS(fil)[j++] = ht->keys[i]; - SCHEME_VEC_ELS(fil)[j++] = ht->vals[i]; - } - } - } else - fil = NULL; - - if (mrn->marked_names && mrn->marked_names->count) { - Scheme_Object *d = scheme_null, *p; - - for (i = mrn->marked_names->size; i--; ) { - if (mrn->marked_names->vals[i] - /* #f mapping used to store reverse-map cache: */ - && !SCHEME_FALSEP(mrn->marked_names->keys[i])) { - p = CONS(mrn->marked_names->keys[i], - mrn->marked_names->vals[i]); - d = CONS(p, d); - } - } - - if (fil) - fil = CONS(fil, d); - else - fil = d; - } else if (fil) - fil = CONS(fil, scheme_null); - else - fil = scheme_null; - - l = CONS(l, fil); - - if (SCHEME_PAIRP(mrn->unmarshal_info)) - l = CONS(mrn->unmarshal_info, l); - - l = CONS(mrn->set_identity, l); - l = CONS((mrn->kind == mzMOD_RENAME_MARKED) ? scheme_true : scheme_false, l); - l = CONS(mrn->phase, l); - - local_key = scheme_marshal_lookup(mt, a); - if (local_key) - scheme_marshal_using_key(mt, a); - else { - local_key = scheme_marshal_wrap_set(mt, a, l); - } - } else { - scheme_marshal_using_key(mt, (Scheme_Object *)mrn); - } - stack = CONS(local_key, stack); + stack = add_rename_to_stack(mrn, stack, mt, a); } } stack_size++; } } } + + if (all_redundant) { + /* The rename isn't actually redundant if we need to keep the + rename-set identity --- but we can simplify to just the + identity. */ + WRAP_POS l; + Scheme_Object *la, *this_set_identity, *set_identity; + int kind, sealed; + + if (SCHEME_RENAMESP(a)) { + this_set_identity = ((Module_Renames *)a)->set_identity; + kind = ((Module_Renames *)a)->kind; + sealed = ((Module_Renames *)a)->sealed; + } else { + this_set_identity = ((Module_Renames_Set *)a)->set_identity; + kind = ((Module_Renames_Set *)a)->kind; + sealed = ((Module_Renames_Set *)a)->sealed; + } + + if (kind != mzMOD_RENAME_TOPLEVEL) { + WRAP_POS_COPY(l,w); + + for (; !WRAP_POS_END_P(l); WRAP_POS_INC(l)) { + la = WRAP_POS_FIRST(l); + if (SCHEME_RENAMESP(la)) + set_identity = ((Module_Renames *)la)->set_identity; + else if (SCHEME_RENAMES_SETP(la)) + set_identity = ((Module_Renames_Set *)la)->set_identity; + else if (SCHEME_BOXP(la)) { + set_identity = SCHEME_VEC_ELS(SCHEME_BOX_VAL(la))[5]; + if (SAME_OBJ(set_identity, this_set_identity)) + set_identity = scheme_false; + else + set_identity = NULL; + } else + set_identity = NULL; + + if (set_identity) { + if (SAME_OBJ(set_identity, this_set_identity)) { + all_redundant = 0; + break; + } else + break; + } + } + + if (all_redundant) { + Scheme_Hash_Table *identity_map; + Scheme_Object *key; + + identity_map = (Scheme_Hash_Table *)scheme_hash_get(rns, scheme_eof); + if (!identity_map) { + identity_map = scheme_make_hash_table_equal(); + scheme_hash_set(rns, scheme_eof, (Scheme_Object *)identity_map); + } + + key = scheme_make_pair(scheme_make_integer(kind), + scheme_make_pair(scheme_make_integer(sealed), + this_set_identity)); + + la = scheme_hash_get(identity_map, key); + if (!la) { + la = scheme_make_module_rename(scheme_make_integer(0), kind, NULL, NULL, this_set_identity); + ((Module_Renames *)la)->sealed = sealed; + scheme_hash_set(identity_map, key, la); + } + + if (just_simplify) + stack = CONS(la, stack); + else + stack = add_rename_to_stack((Module_Renames *)la, stack, mt, a); + } + } + } } else if (SCHEME_SYMBOLP(a)) { /* mark barrier */ stack = CONS(a, stack); @@ -6975,9 +7075,9 @@ static Scheme_Object *datum_to_wraps(Scheme_Object *w, if (!set_identity) return_NULL; a = SCHEME_CDR(a); - mrn = (Module_Renames *)scheme_make_module_rename(phase, kind, NULL, NULL); - - mrn->set_identity = set_identity; + mrn = (Module_Renames *)scheme_make_module_rename(phase, kind, + NULL, NULL, + set_identity); if (!SCHEME_PAIRP(a)) return_NULL; mns = SCHEME_CDR(a); From c9f03f0648696f6ca9659fc5b99b161beb95e553 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jul 2012 13:23:12 -0500 Subject: [PATCH 563/746] fix *SL errortrace to support higher phases The new *SL implementations that refer to Scribble can lead to phase-2 code when running without ".zo"s. (cherry picked from commit 99dbc321f5c46eda554686771c79ed4d8005bfad) --- collects/lang/htdp-langs.rkt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/collects/lang/htdp-langs.rkt b/collects/lang/htdp-langs.rkt index dcfb005073..e8a9f23960 100644 --- a/collects/lang/htdp-langs.rkt +++ b/collects/lang/htdp-langs.rkt @@ -1049,11 +1049,16 @@ (number? span)) (with-syntax ([expr expr] [mark (list source line col start-position span)] - [teaching-languages-continuation-mark-key teaching-languages-continuation-mark-key]) - #`(with-continuation-mark 'teaching-languages-continuation-mark-key - 'mark + [teaching-languages-continuation-mark-key teaching-languages-continuation-mark-key] + [wcm (syntax-shift-phase-level #'with-continuation-mark (- phase base-phase))] + [quot (syntax-shift-phase-level #'quote (- phase base-phase))]) + #`(wcm (quot teaching-languages-continuation-mark-key) + (quot mark) expr)) expr))) + + (define base-phase + (variable-reference->module-base-phase (#%variable-reference))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; From 51712648c33917615eb0e686327da42fc94af4be Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jul 2012 16:49:54 -0500 Subject: [PATCH 564/746] another `namespace-attach-module' repair for submodules Merge to v5.3 (cherry picked from commit a45d13b52acbbac471e03f04f7e18ab045169145) --- collects/tests/racket/submodule.rktl | 61 ++++++++++++++++------------ src/racket/src/module.c | 35 +++++++++------- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/collects/tests/racket/submodule.rktl b/collects/tests/racket/submodule.rktl index 6818e84b96..662fb8a68a 100644 --- a/collects/tests/racket/submodule.rktl +++ b/collects/tests/racket/submodule.rktl @@ -675,34 +675,41 @@ ;; Module attach (let () - (define (test-attach decl-only? pre-check?) - (let ([ns1 (make-base-namespace)] - [ns2 (make-base-namespace)] - [ns3 (make-base-namespace)]) - (parameterize ([current-namespace ns1]) - (eval '(module m racket/base - (provide root) (define root 'm) - (module+ n (provide x) (define x 'x)))) - (unless decl-only? - (dynamic-require ''m #f) - (when pre-check? - (test 'x dynamic-require '(submod 'm n) 'x)))) - (parameterize ([current-namespace ns2]) - ((if decl-only? namespace-attach-module-declaration namespace-attach-module) - ns1 - ''m) - (test 'x dynamic-require '(submod 'm n) 'x)) - (unless decl-only? + (define (attach-tests use-path?) + (define (test-attach decl-only? pre-check?) + (define path (and use-path? + (build-path (find-system-path 'temp-dir) "mod.rkt"))) + (let ([ns1 (make-base-namespace)] + [ns2 (make-base-namespace)] + [ns3 (make-base-namespace)]) (parameterize ([current-namespace ns1]) - (test 'x dynamic-require '(submod 'm n) 'x))) - (parameterize ([current-namespace ns3]) - ((if decl-only? namespace-attach-module-declaration namespace-attach-module) - ns1 - '(submod 'm n)) - (test 'm dynamic-require ''m 'root)))) - (test-attach #f #f) - (test-attach #f #t) - (test-attach #t #f)) + (parameterize ([current-module-declare-name (and use-path? + (make-resolved-module-path path))]) + (eval '(module m racket/base + (provide root) (define root 'm) + (module+ n (provide x) (define x 'x))))) + (unless decl-only? + (dynamic-require (or path ''m) #f) + (when pre-check? + (test 'x dynamic-require `(submod ,(or path ''m) n) 'x)))) + (parameterize ([current-namespace ns2]) + ((if decl-only? namespace-attach-module-declaration namespace-attach-module) + ns1 + (or path ''m)) + (test 'x dynamic-require `(submod ,(or path ''m) n) 'x)) + (unless decl-only? + (parameterize ([current-namespace ns1]) + (test 'x dynamic-require `(submod ,(or path ''m) n) 'x))) + (parameterize ([current-namespace ns3]) + ((if decl-only? namespace-attach-module-declaration namespace-attach-module) + ns1 + `(submod ,(or path ''m) n)) + (test 'm dynamic-require (or path ''m) 'root)))) + (test-attach #f #f) + (test-attach #f #t) + (test-attach #t #f)) + (attach-tests #f) + (attach-tests #t)) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/racket/src/module.c b/src/racket/src/module.c index f4a078519a..2ec54d5787 100644 --- a/src/racket/src/module.c +++ b/src/racket/src/module.c @@ -1453,8 +1453,10 @@ void ensure_instantiate_for_label(const char *who, Scheme_Env *from_env, Scheme_ } } -static Scheme_Object *make_sub_modidx(Scheme_Env *menv, Scheme_Object *name, int i) +static Scheme_Object *make_sub_modidx_pair(Scheme_Env *menv, Scheme_Object *name, int i) { + Scheme_Object *modidx; + if (i) { name = scheme_resolved_module_path_value(name); while (SCHEME_PAIRP(SCHEME_CDR(name))) { @@ -1465,12 +1467,15 @@ static Scheme_Object *make_sub_modidx(Scheme_Env *menv, Scheme_Object *name, int name = scheme_make_utf8_string(".."); } - return scheme_make_modidx(scheme_make_pair(submod_symbol, - scheme_make_pair(scheme_make_utf8_string("."), - scheme_make_pair(name, - scheme_null))), - menv->link_midx, - scheme_false); + modidx = scheme_make_modidx(scheme_make_pair(submod_symbol, + scheme_make_pair(scheme_make_utf8_string("."), + scheme_make_pair(name, + scheme_null))), + menv->link_midx, + scheme_false); + name = scheme_module_resolve(modidx, 0); + + return scheme_make_pair(name, modidx); } #if 0 @@ -1785,10 +1790,10 @@ static Scheme_Object *do_namespace_attach_module(const char *who, int argc, Sche name = ((Scheme_Module *)SCHEME_CAR(l))->modname; if (!scheme_hash_get(nophase_checked, name)) { - LOG_ATTACH(printf("Add s %s\n", scheme_write_to_string(name, NULL))); - nophase_todo = scheme_make_pair(scheme_make_pair(name, make_sub_modidx(menv, name, i)), - nophase_todo); - scheme_hash_set(nophase_checked, name, just_declare ? scheme_false : scheme_true); + name = make_sub_modidx_pair(menv, name, i); + LOG_ATTACH(printf("Add s %s\n", scheme_write_to_string(SCHEME_CAR(name), NULL))); + nophase_todo = scheme_make_pair(name, nophase_todo); + scheme_hash_set(nophase_checked, SCHEME_CAR(name), just_declare ? scheme_false : scheme_true); } l = SCHEME_CDR(l); } @@ -1970,10 +1975,10 @@ static Scheme_Object *do_namespace_attach_module(const char *who, int argc, Sche name = ((Scheme_Module *)SCHEME_CAR(l))->modname; if (!scheme_hash_get(nophase_checked, name)) { - LOG_ATTACH(printf("Add s %s\n", scheme_write_to_string(name, NULL))); - nophase_todo = scheme_make_pair(scheme_make_pair(name, make_sub_modidx(menv, name, i)), - nophase_todo); - scheme_hash_set(nophase_checked, name, just_declare ? scheme_false : scheme_true); + name = make_sub_modidx_pair(menv, name, i); + LOG_ATTACH(printf("Add s %s\n", scheme_write_to_string(SCHEME_CAR(name), NULL))); + nophase_todo = scheme_make_pair(name, nophase_todo); + scheme_hash_set(nophase_checked, SCHEME_CAR(name), just_declare ? scheme_false : scheme_true); } l = SCHEME_CDR(l); } From 61e890ba153ad013fc5a07c639840047b872a0d4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 19 Jul 2012 19:54:02 -0500 Subject: [PATCH 565/746] fixes the "not used in definition context" error in define/contract related to PR 12863, but doesn't solve the infinite loop problem (cherry picked from commit 774e254f3caba542841832fcf3003ce88d3befed) --- collects/racket/contract/private/provide.rkt | 4 ++-- collects/racket/contract/region.rkt | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/collects/racket/contract/private/provide.rkt b/collects/racket/contract/private/provide.rkt index b6280bc9ed..29716f90f8 100644 --- a/collects/racket/contract/private/provide.rkt +++ b/collects/racket/contract/private/provide.rkt @@ -799,8 +799,8 @@ (define-syntax (provide/contract stx) (define s-l-c (syntax-local-context)) (case s-l-c - [(module-begin) ;; the case under discussion - #`(begin (define-values () (values)) ;; force us into the 'module' local context + [(module-begin) + #`(begin ;; force us into the 'module' local context #,stx)] [(module) ;; the good case (true-provide/contract stx #f 'provide/contract)] diff --git a/collects/racket/contract/region.rkt b/collects/racket/contract/region.rkt index 15532dfbdb..85dcf52cb0 100644 --- a/collects/racket/contract/region.rkt +++ b/collects/racket/contract/region.rkt @@ -46,10 +46,18 @@ ; ; ; +(define-syntax (define/contract stx) + (define s-l-c (syntax-local-context)) + (case s-l-c + [(module-begin) + #`(begin #,stx)] + [else + (define/contract-expander stx)])) + ;; (define/contract id contract expr) ;; defines `id' with `contract'; initially binding ;; it to the result of `expr'. These variables may not be set!'d. -(define-syntax (define/contract define-stx) +(define-for-syntax (define/contract-expander define-stx) (define-splicing-syntax-class fv-clause #:description "a free variable clause" #:attributes ([var 1] [ctc 1]) From f04778f4d58995ccc5557abb418724e028f4ac49 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jul 2012 18:59:38 -0600 Subject: [PATCH 566/746] ffi/com: fix an internal cast Merge to v5.3 (cherry picked from commit c86ee5b6e20715d2172303ac2c313b16d0c79fdb) --- collects/ffi/unsafe/com.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index 53c02b2ba8..ed9eec278f 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -1779,7 +1779,7 @@ (define method-result (if (= inv-kind INVOKE_PROPERTYPUT) #f - (cast (malloc 'atomic _VARIANT) _pointer _VARIANT-pointer))) + (cast (malloc 'atomic _VARIANT) _pointer (_gcable _VARIANT-pointer)))) (when method-result (VariantInit method-result)) (define-values (hr exn-info error-index) From 5dc7368612b8af7daeed88477f2a8590f48ca148 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jul 2012 20:20:33 -0500 Subject: [PATCH 567/746] ffi/com: fix another instance of the `cast' bug Overlooked it during the previous repair; this repair merges the two formerly broken sites. (cherry picked from commit 94498465e614586ae9d53b79467abc0854619da2) --- collects/ffi/unsafe/com.rkt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index ed9eec278f..95911fb53e 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -1535,7 +1535,7 @@ (define (make-a-VARIANT [mode 'atomic-interior]) (define var (cast (malloc _VARIANT mode) _pointer - _VARIANT-pointer)) + (_gcable _VARIANT-pointer))) (VariantInit var) var) @@ -1779,9 +1779,7 @@ (define method-result (if (= inv-kind INVOKE_PROPERTYPUT) #f - (cast (malloc 'atomic _VARIANT) _pointer (_gcable _VARIANT-pointer)))) - (when method-result - (VariantInit method-result)) + (make-a-VARIANT 'atomic))) (define-values (hr exn-info error-index) (Invoke (com-object-get-dispatch obj) memid IID_NULL LOCALE_SYSTEM_DEFAULT From fd7c2ad407c392ed1e96dd2c1556a71f8010c319 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 19 Jul 2012 20:42:19 -0500 Subject: [PATCH 568/746] macro expander fix Relevant to PR 12863 Merge to v5.3 (cherry picked from commit d3677524b8f7429f9ef6a5145dbc245ea37b99ab) --- collects/tests/racket/macro.rktl | 27 +++++++++++++++++++++++++++ src/racket/src/compenv.c | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/collects/tests/racket/macro.rktl b/collects/tests/racket/macro.rktl index 44d070bcd9..fdc31c388b 100644 --- a/collects/tests/racket/macro.rktl +++ b/collects/tests/racket/macro.rktl @@ -638,6 +638,33 @@ #'#f) (two)) +;; ---------------------------------------- +;; Related: check that matching no marks is considered less +;; of a match than matching with marks: + +(module another-test-empty-marks-with-context racket/base + (require (for-syntax racket/base)) + + (define-for-syntax count 0) + (define-for-syntax (inc-count!) (set! count (add1 count))) + + (define-syntax (foo stx) + (syntax-case stx () + [(_ x e) + (let ([cid-marker (make-syntax-introducer)]) + (with-syntax ([y (cid-marker #'x)]) + #'(begin + (define y e) + (+ y 1) + (define-syntax x + (lambda (stx) + (inc-count!) + (when (= count 5) (error "stop")) + #'y)))))])) + + (module* test #f + (foo eX 3))) + ;; ---------------------------------------- ;; Check `free-identifier=?' propagation, ;; definition contexts, and `syntax-local-bind-syntaxes' diff --git a/src/racket/src/compenv.c b/src/racket/src/compenv.c index 08d1596998..d0585ee63d 100644 --- a/src/racket/src/compenv.c +++ b/src/racket/src/compenv.c @@ -1112,7 +1112,7 @@ Scheme_Object *scheme_tl_id_sym(Scheme_Env *env, Scheme_Object *id, Scheme_Objec if (SCHEME_NULLP(amarks)) { /* can always match empty marks */ best_match = SCHEME_CDR(a); - best_match_skipped = 0; + best_match_skipped = scheme_proper_list_length(marks); } else if (!SCHEME_PAIRP(marks)) { /* To be better than nothing, could only match exactly: */ if (scheme_equal(amarks, marks)) { From 913f6365f91fdf9722ea3e7be8b9b3c1dc12429c Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Fri, 20 Jul 2012 10:37:37 -0400 Subject: [PATCH 569/746] fixed a somewhat awkward error message that made 'system' look awkward (manually adapted) (cherry picked from commit f2b9cdaadd610e628a04e705710817619951d31d) --- collects/mzlib/process.rkt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/collects/mzlib/process.rkt b/collects/mzlib/process.rkt index 49f556232e..c527604bae 100644 --- a/collects/mzlib/process.rkt +++ b/collects/mzlib/process.rkt @@ -59,7 +59,7 @@ (raise-mismatch-error who "expected a single string argument after: " - (car args))) + (car args))) (unless (and (>= 2 (length args)) (string? (cadr args)) (path-or-ok-string? (cadr args))) @@ -78,17 +78,20 @@ (raise-argument-error who (string-append "(or/c path-string?\n" - " (and/c bytes? (lambda (bs) (not (memv 0 (bytes->list bs))))))") + " (and/c bytes? bytes-no-nuls?))") s)))]) args) +;; MF: fxing a somewhat awkward looking error message. Comment for Matthew in case he wants to improve on it. +(provide string-no-nuls? bytes-no-nuls?) + (define (check-command who str) (unless (or (string-no-nuls? str) (bytes-no-nuls? str)) (raise-argument-error who - (string-append "(or/c (and/c string? (lambda (s) (not (memv #\\nul (string->list s)))))\n" - " (and/c bytes? (lambda (bs) (not (memv 0 (bytes->list bs))))))") + (string-append "(or/c (and/c string? string-no-nuls?)\n" + " (and/c bytes? bytes-no-nuls?))") str))) ;; Old-style functions: ---------------------------------------- From d0c76a84a76917fd3295faf4e149c457a9e17482 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 20 Jul 2012 10:43:56 -0400 Subject: [PATCH 570/746] Drop attempt to verify when running plainly. Instead, require a "verify" verb, and adjust the props so drdr will use it. Also add some OS X & Windows patterns to be ignored. (cherry picked from commit a2f94b49d39d71e049b0e535867d89e775cc1f0c) --- collects/meta/props | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/collects/meta/props b/collects/meta/props index 2d80eb7891..3401f534c8 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -352,7 +352,9 @@ path/s is either such a string or a list of them. #rx"(?:^|/)[.]git" #rx"^(?:README|bin|lib|include|[.]mailmap)$" #rx"^collects/info-domain$" - #rx"^doc/[^/]*$")) + #rx"^doc/[^/]*$" + #rx"(?:^|/)[.]DS_Store$" + #rx"^[^/]*[.](?:app|exe)$")) (define (verify) (define errors 0) @@ -622,13 +624,6 @@ path/s is either such a string or a list of them. ;; read the arguments here, so just requiring this file verifies the data (read-props) -;; if we're running directly, do a verification -;; Use this only when supported -(require (for-syntax racket/base version/utils)) -(define-syntax (add-main stx) - (if ((version) . version<=? . "5.2.1") #'(begin) #'(module+ main (verify)))) -(add-main) - ;; ---------------------------------------------------------------------------- #| #:begin-props @@ -806,7 +801,7 @@ path/s is either such a string or a list of them. "collects/meta/drdr" responsible (jay) drdr:command-line #f "collects/meta/drdr2" responsible (jay) drdr:command-line #f "collects/meta/images/mkheart.rkt" drdr:command-line #f -"collects/meta/props" drdr:command-line (racket *) responsible (eli jay) +"collects/meta/props" drdr:command-line (racket * "verify") responsible (eli jay) "collects/meta/web" drdr:command-line #f "collects/mred" responsible (mflatt) "collects/mred/edit-main.rkt" drdr:command-line (mzc *) From 1d64b3a94f24c600ec91166d423f1e1addfbcab8 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Fri, 20 Jul 2012 11:56:16 -0400 Subject: [PATCH 571/746] docs for revised system error message completed (manually adapted) (cherry picked from commit 67681361445f09539c73aa807f4ec3f14ac5501a) --- collects/mzlib/process.rkt | 8 ++++---- collects/scribblings/reference/subprocess.scrbl | 14 ++++++++++++++ doc/release-notes/racket/HISTORY.txt | 1 + 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/collects/mzlib/process.rkt b/collects/mzlib/process.rkt index c527604bae..2374e82bec 100644 --- a/collects/mzlib/process.rkt +++ b/collects/mzlib/process.rkt @@ -6,7 +6,10 @@ system system* system/exit-code - system*/exit-code) + system*/exit-code + + string-no-nuls? + bytes-no-nuls?) (require "private/streams.rkt") @@ -82,9 +85,6 @@ s)))]) args) -;; MF: fxing a somewhat awkward looking error message. Comment for Matthew in case he wants to improve on it. -(provide string-no-nuls? bytes-no-nuls?) - (define (check-command who str) (unless (or (string-no-nuls? str) (bytes-no-nuls? str)) diff --git a/collects/scribblings/reference/subprocess.scrbl b/collects/scribblings/reference/subprocess.scrbl index 1154f6c8b9..6f06dd399c 100644 --- a/collects/scribblings/reference/subprocess.scrbl +++ b/collects/scribblings/reference/subprocess.scrbl @@ -482,3 +482,17 @@ returned list is @racket[#f].} Like @racket[process*], but with the port handling of @racket[process/ports].} +@; ---------------------------------------------------------------------- + +@;section{Contract Auxiliaries} + +@;note-lib[racket/system] + +The contracts of @racket[system] and related functions may signal a +contract error with references to the following functions. + +@defproc[(string-no-nuls? [x any/c]) boolean?]{ +Ensures that @racket[x] is a string and does not contain @racket["\0"].} + +@defproc[(bytes-no-nuls? [x any/c]) boolean?]{ +Ensures that @racket[x] is a byte-string and does not contain @racket["\0"].} diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index c6e1679fbd..d772e83cd5 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -77,6 +77,7 @@ racket/sandbox: added sandbox-propagate-exceptions; added racket/cmdline: add #:ps for command-line slideshow/start: run a `slideshow' or `main' submodule, if any scribble/eval: added eval:result and eval:results +racket/system: improved error messages by replacing memv expressions with string-no-nuls? and bytes-no-nuls? Version 5.2.1, January 2012 Changed I/O scheduling to use epoll()/kqueue() when available From ec319cb4677dddabaa523672d8c9e01be4c3c253 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 20 Jul 2012 12:34:59 -0400 Subject: [PATCH 572/746] More ignore patterns for props verification. (cherry picked from commit 2a075654d066c3628ac724533768bd1fe9800300) --- collects/meta/props | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/collects/meta/props b/collects/meta/props index 3401f534c8..73847addb3 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -348,9 +348,10 @@ path/s is either such a string or a list of them. ;; Verify this database (define no-props-needed - '(#rx"/compiled$" - #rx"(?:^|/)[.]git" - #rx"^(?:README|bin|lib|include|[.]mailmap)$" + '(#rx"(?:~|[.]bak)$" + #rx"(?:^|/)(?:#|[.]git)" + #rx"/compiled$" + #rx"^(?:README|bin|lib|include|[.]mailmap|add-on)$" #rx"^collects/info-domain$" #rx"^doc/[^/]*$" #rx"(?:^|/)[.]DS_Store$" From 298dd3e62c5ad7b3c821d6c20c12e07614b4ec93 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 20 Jul 2012 12:57:28 -0400 Subject: [PATCH 573/746] Some simplification of process error message contracts. (manually adapted) (cherry picked from commit 4bd42606bc43c094c597b90903f192bf63f0b4de) --- collects/mzlib/process.rkt | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/collects/mzlib/process.rkt b/collects/mzlib/process.rkt index 2374e82bec..ab51a0f5dc 100644 --- a/collects/mzlib/process.rkt +++ b/collects/mzlib/process.rkt @@ -44,15 +44,13 @@ (define (path-or-ok-string? s) ;; use `path-string?' t check for nul characters in a string, ;; but allow the empty string (which is not an ok path), too: - (or (path-string? s) - (equal? "" s))) + (or (path-string? s) (equal? "" s))) (define (string-no-nuls? s) (and (string? s) (path-or-ok-string? s))) (define (bytes-no-nuls? s) - (and (bytes? s) - (not (regexp-match? #rx#"\0" s)))) + (and (bytes? s) (not (regexp-match? #rx#"\0" s)))) (define (check-args who args) (cond @@ -76,23 +74,13 @@ (caddr args)))] [else (for ([s (in-list args)]) - (unless (or (path-or-ok-string? s) - (bytes-no-nuls? s)) - (raise-argument-error - who - (string-append "(or/c path-string?\n" - " (and/c bytes? bytes-no-nuls?))") - s)))]) + (unless (or (path-or-ok-string? s) (bytes-no-nuls? s)) + (raise-argument-error who "(or/c path-string? bytes-no-nuls?)" s)))]) args) (define (check-command who str) - (unless (or (string-no-nuls? str) - (bytes-no-nuls? str)) - (raise-argument-error - who - (string-append "(or/c (and/c string? string-no-nuls?)\n" - " (and/c bytes? bytes-no-nuls?))") - str))) + (unless (or (string-no-nuls? str) (bytes-no-nuls? str)) + (raise-argument-error who "(or/c string-no-nuls? bytes-no-nuls?)" str))) ;; Old-style functions: ---------------------------------------- From 1832c2b712553f0ad58b3817849e31e6de9aa61f Mon Sep 17 00:00:00 2001 From: Sam Tobin-Hochstadt Date: Fri, 20 Jul 2012 12:51:54 -0400 Subject: [PATCH 574/746] Ensure that structs don't overlap with simple values. Reported by Ray Racine. Please merge to release. (cherry picked from commit 4a90c6c1fea75fac3132de7df70e5e7e8207b311) --- collects/tests/typed-racket/succeed/poly-struct-pred.rkt | 9 +++++++++ collects/typed-racket/types/remove-intersect.rkt | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 collects/tests/typed-racket/succeed/poly-struct-pred.rkt diff --git a/collects/tests/typed-racket/succeed/poly-struct-pred.rkt b/collects/tests/typed-racket/succeed/poly-struct-pred.rkt new file mode 100644 index 0000000000..ee3fa951e1 --- /dev/null +++ b/collects/tests/typed-racket/succeed/poly-struct-pred.rkt @@ -0,0 +1,9 @@ +#lang typed/racket + +(struct: (X) s ([v : X])) + +(: f : (All (X) (U 'foo (s X)) -> (s X))) +(define (f t) + (match t + [(s value) (s value)] + [_ (error 'fail)])) \ No newline at end of file diff --git a/collects/typed-racket/types/remove-intersect.rkt b/collects/typed-racket/types/remove-intersect.rkt index 0cd68b852e..9e7a0f712b 100644 --- a/collects/typed-racket/types/remove-intersect.rkt +++ b/collects/typed-racket/types/remove-intersect.rkt @@ -66,8 +66,10 @@ [(or (list (Pair: _ _) _) (list _ (Pair: _ _))) #f] - [(or (list (Value: '()) (Struct: n _ flds _ _ _ _ _)) - (list (Struct: n _ flds _ _ _ _ _) (Value: '()))) + [(or (list (Value: (? (λ (e) (or (null? e) (symbol? e) (number? e) (boolean? e) (pair? e) (keyword? e))))) + (Struct: n _ flds _ _ _ _ _)) + (list (Struct: n _ flds _ _ _ _ _) + (Value: (? (λ (e) (or (null? e) (symbol? e) (number? e) (boolean? e) (pair? e) (keyword? e))))))) #f] [(list (Struct: n _ flds _ _ _ _ _) (Struct: n* _ flds* _ _ _ _ _)) (=> nevermind) From 89565734b9bca47895a4180c38c746008e3ed3ad Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Tue, 17 Jul 2012 17:18:19 -0400 Subject: [PATCH 575/746] Change Optimization Coach message. (cherry picked from commit 2e594d36068ab198662bbece0f79981779f23a0d) --- collects/typed-racket/optimizer/float.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/typed-racket/optimizer/float.rkt b/collects/typed-racket/optimizer/float.rkt index e1e1b8ec8b..4a2a3cad63 100644 --- a/collects/typed-racket/optimizer/float.rkt +++ b/collects/typed-racket/optimizer/float.rkt @@ -80,7 +80,7 @@ (log-missed-optimization "all args float-arg-expr, result not Float" (string-append - "This expression has a Real type. The optimizer could improve its performance if it had type Float." + "This expression has a Real type. The optimizer could optimize it if it had type Float." (if (null? irritants) "" "To fix, change the highlighted expression(s) to have Float type(s).")) From 497473c1ff5c748fba35fca7dc3761d52a436a0a Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 19 Jul 2012 12:17:42 -0400 Subject: [PATCH 576/746] Disable loop detection heuristic with too many false positives. (cherry picked from commit d396b34b2de69b02dbad54f1cf5f77b98017d695) --- collects/typed-racket/optimizer/tool/mzc.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/typed-racket/optimizer/tool/mzc.rkt b/collects/typed-racket/optimizer/tool/mzc.rkt index 3fdfdd47e9..f06e549a95 100644 --- a/collects/typed-racket/optimizer/tool/mzc.rkt +++ b/collects/typed-racket/optimizer/tool/mzc.rkt @@ -180,7 +180,8 @@ ;; body (as opposed to `g') may make unboxing possible. ;; Of course, we lose precision if `g' has multiple call sites to `f'. (define n-unrollings (length (filter unrolling? group))) - (define is-a-loop? (or any-self-o-o-f? (> n-unrollings 0))) + ;; TODO any-self-o-o-f? add too many false positives + (define is-a-loop? (or #;any-self-o-o-f? (> n-unrollings 0))) (define inlining-sites (group-by equal? #:key (lambda (x) (inlining-event-where-loc From 82a50d3eee6284a592c0d69606d858846c66b311 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Thu, 19 Jul 2012 15:57:03 -0400 Subject: [PATCH 577/746] Only enable Optimization Coach button in Typed Racket. Other languages can access it through the View menu. Please merge to release. (cherry picked from commit 24b314a40ade5c576912eea416a68d78e09ca01b) --- collects/typed-racket/optimizer/tool/tool.rkt | 20 ++++++++----------- collects/typed-scheme/lang/reader.rkt | 3 +++ collects/typed/racket/base/lang/reader.rkt | 3 +++ collects/typed/racket/lang/reader.rkt | 3 +++ collects/typed/scheme/base/lang/reader.rkt | 3 +++ collects/typed/scheme/lang/reader.rkt | 3 +++ 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/collects/typed-racket/optimizer/tool/tool.rkt b/collects/typed-racket/optimizer/tool/tool.rkt index 3c36a45ddb..4ca0654dc3 100644 --- a/collects/typed-racket/optimizer/tool/tool.rkt +++ b/collects/typed-racket/optimizer/tool/tool.rkt @@ -8,7 +8,7 @@ (require "report.rkt" "display.rkt") -(provide tool@) +(provide tool@ optimization-coach-drracket-button) ;; DrRacket tool for reporting missed optimizations in the editor. @@ -36,22 +36,18 @@ (define-local-member-name get-coach-menu-item) +(define optimization-coach-drracket-button + (list + "Optimization Coach" + optimization-coach-bitmap + optimization-coach-callback)) + (define-unit tool@ (import drracket:tool^) (export drracket:tool-exports^) - (define (phase1) - (drracket:module-language-tools:add-opt-out-toolbar-button - (lambda (frame parent) - (new switchable-button% - [label "Optimization Coach"] - [callback (lambda (btn) - (optimization-coach-callback frame))] - [parent parent] - [bitmap optimization-coach-bitmap])) - 'optimization-coach - #:number 75)) + (define (phase1) (void)) (define (phase2) (void)) (define highlights-mixin diff --git a/collects/typed-scheme/lang/reader.rkt b/collects/typed-scheme/lang/reader.rkt index 876f259f81..56eb29463b 100644 --- a/collects/typed-scheme/lang/reader.rkt +++ b/collects/typed-scheme/lang/reader.rkt @@ -10,4 +10,7 @@ typed-scheme (define (make-info key default use-default) (case key + [(drscheme:toolbar-buttons) + (list (dynamic-require 'typed-racket/optimizer/tool/tool + 'optimization-coach-drracket-button))] [else (use-default key default)])) diff --git a/collects/typed/racket/base/lang/reader.rkt b/collects/typed/racket/base/lang/reader.rkt index 849ff945b1..053ed28db3 100644 --- a/collects/typed/racket/base/lang/reader.rkt +++ b/collects/typed/racket/base/lang/reader.rkt @@ -9,6 +9,9 @@ typed/racket/base (define (make-info key default use-default) (case key + [(drscheme:toolbar-buttons) + (list (dynamic-require 'typed-racket/optimizer/tool/tool + 'optimization-coach-drracket-button))] [else (use-default key default)])) (define make-language-info diff --git a/collects/typed/racket/lang/reader.rkt b/collects/typed/racket/lang/reader.rkt index 257a2ae40c..1252857c29 100644 --- a/collects/typed/racket/lang/reader.rkt +++ b/collects/typed/racket/lang/reader.rkt @@ -9,6 +9,9 @@ typed/racket (define (make-info key default use-default) (case key + [(drscheme:toolbar-buttons) + (list (dynamic-require 'typed-racket/optimizer/tool/tool + 'optimization-coach-drracket-button))] [else (use-default key default)])) (define make-language-info diff --git a/collects/typed/scheme/base/lang/reader.rkt b/collects/typed/scheme/base/lang/reader.rkt index 6da86b0d5f..490d0faa2e 100644 --- a/collects/typed/scheme/base/lang/reader.rkt +++ b/collects/typed/scheme/base/lang/reader.rkt @@ -9,6 +9,9 @@ typed/scheme/base (define (make-info key default use-default) (case key + [(drscheme:toolbar-buttons) + (list (dynamic-require 'typed-racket/optimizer/tool/tool + 'optimization-coach-drracket-button))] [else (use-default key default)])) (define make-language-info diff --git a/collects/typed/scheme/lang/reader.rkt b/collects/typed/scheme/lang/reader.rkt index 2f51e90f83..a909f9f082 100644 --- a/collects/typed/scheme/lang/reader.rkt +++ b/collects/typed/scheme/lang/reader.rkt @@ -9,6 +9,9 @@ typed/scheme (define (make-info key default use-default) (case key + [(drscheme:toolbar-buttons) + (list (dynamic-require 'typed-racket/optimizer/tool/tool + 'optimization-coach-drracket-button))] [else (use-default key default)])) (define make-language-info From 4bfaae4d0bae7ff0b6b1d5ffd34f3d99b0accb29 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 10:38:50 -0400 Subject: [PATCH 578/746] Consistent capitalization with other menu items. (cherry picked from commit 7c0ef33bb71b6d5fd490fb9ea801c3cf5d4fb9a6) --- collects/typed-racket/optimizer/tool/tool.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/typed-racket/optimizer/tool/tool.rkt b/collects/typed-racket/optimizer/tool/tool.rkt index 4ca0654dc3..267199e5d5 100644 --- a/collects/typed-racket/optimizer/tool/tool.rkt +++ b/collects/typed-racket/optimizer/tool/tool.rkt @@ -153,7 +153,7 @@ (and (<= start pos end) (let ([menu (make-object popup-menu% #f)]) (new menu-item% - [label "Show optimization info"] + [label "Show Optimization Info"] [parent menu] [callback (lambda _ (popup-fun text start end))]) menu)))))) From 9d566a00f4311d14373f8722f19f837b470b8005 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 10:44:48 -0400 Subject: [PATCH 579/746] Rename Optimization Coach menu item. (cherry picked from commit def96496880578a79ceb4822486b0f1c05aaa29b) --- .../string-constants/private/english-string-constants.rkt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collects/string-constants/private/english-string-constants.rkt b/collects/string-constants/private/english-string-constants.rkt index e9915d96a0..9ed37dc177 100644 --- a/collects/string-constants/private/english-string-constants.rkt +++ b/collects/string-constants/private/english-string-constants.rkt @@ -1659,7 +1659,7 @@ please adhere to these guidelines: (always-use-platform-specific-linefeed-convention "Always use the platform-specific linefeed convention") ;; optimization coach - (hide-optimization-coach "Hide Optimization Coach Info") - (show-optimization-coach "Show Optimization Coach Info") + (hide-optimization-coach "Hide Optimization Coach") + (show-optimization-coach "Show Optimization Coach") ) From dc7d1eacd001ae8380097c1705fe8a6797c7b88f Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 10:45:06 -0400 Subject: [PATCH 580/746] Typo. (cherry picked from commit 031a2862d2683b590be7edf12f83e1698a5d2ad9) --- collects/string-constants/private/french-string-constants.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/string-constants/private/french-string-constants.rkt b/collects/string-constants/private/french-string-constants.rkt index 0f9508de1b..e1f7b716dc 100644 --- a/collects/string-constants/private/french-string-constants.rkt +++ b/collects/string-constants/private/french-string-constants.rkt @@ -89,7 +89,7 @@ (module french-string-constants "string-constant-lang.rkt" - ;;; when translating this constant, substitue name of actual language for `English' + ;;; when translating this constant, substitute name of actual language for `English' (is-this-your-native-language "Le Français est-il votre langue maternelle ?") (are-you-sure-you-want-to-switch-languages From 29557d55dd5afd015754877d6e939a023dca5299 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 10:51:26 -0400 Subject: [PATCH 581/746] Update Optimization Coach documentation. Please merge to release. (cherry picked from commit ea6ba36ccb505cd8d08ca1f88d9f9aed18209e8f) --- .../scribblings/guide/optimization.scrbl | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/collects/typed-racket/scribblings/guide/optimization.scrbl b/collects/typed-racket/scribblings/guide/optimization.scrbl index 43451d9fe4..d34ca0ac60 100644 --- a/collects/typed-racket/scribblings/guide/optimization.scrbl +++ b/collects/typed-racket/scribblings/guide/optimization.scrbl @@ -159,13 +159,13 @@ preferable to vectors. Typed Racket can optimize struct access in all cases. -@subsection{Performance Debugging} +@subsection{Optimization Coaching} -Typed Racket provides performance debugging support to help you get the +Typed Racket provides optimization coaching support to help you get the most of its optimizer. The @deftech{Optimization Coach} DrRacket plugin can be used when editing a -Typed Racket program in DrRacket. Clicking the Optimization Coach button +Typed Racket program in DrRacket. Clicking the @bold{Optimization Coach} button runs the optimizer and reports the results. All performed optimizations are highlighted in green in the editor. In addition, the optimizer also reports cases where an optimization was close to happening, but was not ultimately safe @@ -173,10 +173,17 @@ to perform. These cases are highlighted in shades of red in the editor. The redder the highlight, the higher the potential for optimization in the highlighted region is. -Additional information can be accessed by clicking on the highlighted -regions. A summary of the performed optimizations and advice on how to adjust +Additional information can be accessed by right-clicking on the highlighted +regions and picking the @bold{Show Optimization Info} menu entry. +A summary of the performed optimizations and advice on how to adjust code to make it more amenable to optimization is provided as appropriate, and -can as a starting point for performance debugging. +can serve as a starting point for further optimization. + +Optimization Coach is also available for other Racket languages through the +@bold{Show Optimization Coach} entry in the @bold{View} menu. +When running from unytped Racket languages, Optimization Coach does not report +information about Typed Racket optimizations, and only reports information from +the Racket inliner. Similar information (albeit without in-depth explanations or advice) is available from the command line. When compiling a Typed Racket program, setting From 89e06e802f0d850b9ba202ed63a2e33a91e3b7b7 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 11:03:27 -0400 Subject: [PATCH 582/746] Optimization Coach should not catch break exceptions. (cherry picked from commit f6feff3c51032f6ae0020e2f66ae0291ec3ca1bd) --- collects/typed-racket/optimizer/tool/tool.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/typed-racket/optimizer/tool/tool.rkt b/collects/typed-racket/optimizer/tool/tool.rkt index 267199e5d5..dfb1a242d0 100644 --- a/collects/typed-racket/optimizer/tool/tool.rkt +++ b/collects/typed-racket/optimizer/tool/tool.rkt @@ -18,7 +18,7 @@ ;; optimization-coach-callback : drracket:unit:frame<%> -> void (define (optimization-coach-callback drr-frame) (with-handlers - ([exn? + ([(lambda (e) (and (exn? e) (not (exn:break? e)))) ;; typechecking failed, report in the interactions window (lambda (e) (define interactions (send drr-frame get-interactions-text)) From 1975f596b6ce542f2efae2f09fe52d747723a8b0 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 11:19:42 -0400 Subject: [PATCH 583/746] Delete trailing whitespace. (cherry picked from commit 6af2e49db3ae4ae53d564e21a731a829895a4add) --- collects/typed-racket/optimizer/tool/tool.rkt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/collects/typed-racket/optimizer/tool/tool.rkt b/collects/typed-racket/optimizer/tool/tool.rkt index dfb1a242d0..740d1896c1 100644 --- a/collects/typed-racket/optimizer/tool/tool.rkt +++ b/collects/typed-racket/optimizer/tool/tool.rkt @@ -95,7 +95,7 @@ (define on? #f) (define/public (highlighting-shown?) on?) - + (define report-cache #f) (define/public (add-highlights #:use-cache? [use-cache? #f]) (clear-highlights) @@ -123,7 +123,7 @@ (set! highlights '()) (send (get-tab) hide-optimization-coach-panel) (set! on? #f)) - + (define/augment (on-insert start len) (clear-highlights)) (define/augment (on-delete start len) @@ -206,13 +206,13 @@ (define tab-switch-mixin (mixin (drracket:unit:frame<%>) () (inherit set-show-menu-sort-key get-current-tab) - + (define/public (get-coach-menu-item) coach-menu-item) - + (define/override (add-show-menu-items show-menu) (super add-show-menu-items show-menu) (set! coach-menu-item - (new menu-item% + (new menu-item% [label (string-constant show-optimization-coach)] [parent show-menu] [demand-callback @@ -221,21 +221,21 @@ (if (get-field panel (get-current-tab)) (string-constant hide-optimization-coach) (string-constant show-optimization-coach))))] - [callback + [callback (λ (a b) (define tab (get-current-tab)) (if (get-field panel tab) (send (send tab get-defs) clear-highlights) (optimization-coach-callback this)))])) (set-show-menu-sort-key coach-menu-item 403)) - + (define/augment (on-tab-change old-tab new-tab) (send old-tab hide-optimization-coach-panel #f) ; don't close it (when (get-field panel new-tab) ; if it was open before (send new-tab show-optimization-coach-panel))) - + (define coach-menu-item #f) - + (super-new))) (drracket:get/extend:extend-unit-frame tab-switch-mixin)) From f0006b6535b70965ec44469b73102cae2b112446 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 11:21:41 -0400 Subject: [PATCH 584/746] Refactoring. (cherry picked from commit fceb3db69ca13c672253f68cc9ecb1d7bb2ebf5f) --- collects/typed-racket/optimizer/tool/tool.rkt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/collects/typed-racket/optimizer/tool/tool.rkt b/collects/typed-racket/optimizer/tool/tool.rkt index 740d1896c1..8dde16ee46 100644 --- a/collects/typed-racket/optimizer/tool/tool.rkt +++ b/collects/typed-racket/optimizer/tool/tool.rkt @@ -34,7 +34,7 @@ ,(match-lambda [(sub-report-entry s m 'mzc) #t] [_ #f])))) -(define-local-member-name get-coach-menu-item) +(define-local-member-name get-optimization-coach-menu-item) (define optimization-coach-drracket-button (list @@ -207,11 +207,12 @@ (mixin (drracket:unit:frame<%>) () (inherit set-show-menu-sort-key get-current-tab) - (define/public (get-coach-menu-item) coach-menu-item) + (define/public (get-optimization-coach-menu-item) + optimization-coach-menu-item) (define/override (add-show-menu-items show-menu) (super add-show-menu-items show-menu) - (set! coach-menu-item + (set! optimization-coach-menu-item (new menu-item% [label (string-constant show-optimization-coach)] [parent show-menu] @@ -227,14 +228,14 @@ (if (get-field panel tab) (send (send tab get-defs) clear-highlights) (optimization-coach-callback this)))])) - (set-show-menu-sort-key coach-menu-item 403)) + (set-show-menu-sort-key optimization-coach-menu-item 403)) (define/augment (on-tab-change old-tab new-tab) (send old-tab hide-optimization-coach-panel #f) ; don't close it (when (get-field panel new-tab) ; if it was open before (send new-tab show-optimization-coach-panel))) - (define coach-menu-item #f) + (define optimization-coach-menu-item #f) (super-new))) From 8d59ea5580b1163b5a8b473c12f3fa9c3c31d758 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 11:24:07 -0400 Subject: [PATCH 585/746] Use local member names for Optimization Coach public methods. (cherry picked from commit eda3e706708bbe564b65e977857405373fac0ece) --- collects/typed-racket/optimizer/tool/tool.rkt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/collects/typed-racket/optimizer/tool/tool.rkt b/collects/typed-racket/optimizer/tool/tool.rkt index 8dde16ee46..6cab8eec38 100644 --- a/collects/typed-racket/optimizer/tool/tool.rkt +++ b/collects/typed-racket/optimizer/tool/tool.rkt @@ -35,6 +35,11 @@ [_ #f])))) (define-local-member-name get-optimization-coach-menu-item) +(define-local-member-name highlighting-shown?) +(define-local-member-name add-highlights) +(define-local-member-name clear-highlights) +(define-local-member-name show-optimization-coach-panel) +(define-local-member-name hide-optimization-coach-panel) (define optimization-coach-drracket-button (list From 4351c010388fb4783009bca6be2202b088a90091 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 11:28:12 -0400 Subject: [PATCH 586/746] Rename undo-thunks to clear-thunks. They don't have anything to do with editors' undo. (cherry picked from commit c237cee025c6fec9fa4b0175e714bb3bbe713eee) --- collects/typed-racket/optimizer/tool/tool.rkt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/collects/typed-racket/optimizer/tool/tool.rkt b/collects/typed-racket/optimizer/tool/tool.rkt index 6cab8eec38..6f5eb10789 100644 --- a/collects/typed-racket/optimizer/tool/tool.rkt +++ b/collects/typed-racket/optimizer/tool/tool.rkt @@ -61,8 +61,8 @@ get-tab get-canvas get-pos/text position-line line-end-position) - (define highlights '()) ; (listof `(,start ,end ,popup-fun)) - (define undo-thunks '()) ; list of thunks that undo highlights + (define highlights '()) ; (listof `(,start ,end ,popup-fun)) + (define clear-thunks '()) ; list of thunks that clear highlights (define color-table #f) ;; filters : Listof (sub-report-entry -> Bool) @@ -118,13 +118,13 @@ (apply max (cons 0 (map report-entry-badness report)))) (unless (= max-badness 0) ; no missed opts, color table code would error (set! color-table (make-color-table max-badness))) - (set! undo-thunks (for/fold ([res '()]) - ([r (in-list report)]) - (append (highlight-entry r) res))) + (set! clear-thunks (for/fold ([res '()]) + ([r (in-list report)]) + (append (highlight-entry r) res))) (set! on? #t)) (define/public (clear-highlights) - (for ([h (in-list undo-thunks)]) (h)) + (for ([h (in-list clear-thunks)]) (h)) (set! highlights '()) (send (get-tab) hide-optimization-coach-panel) (set! on? #f)) From 4c889bc0bce20bb4962a91eafa569c83df67b6d0 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 11:32:48 -0400 Subject: [PATCH 587/746] Typo. (cherry picked from commit 95e117b7f5ecb6c193d882614331e7e0afadeaa0) --- collects/typed-racket/optimizer/tool/tool.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/typed-racket/optimizer/tool/tool.rkt b/collects/typed-racket/optimizer/tool/tool.rkt index 6f5eb10789..96b530850a 100644 --- a/collects/typed-racket/optimizer/tool/tool.rkt +++ b/collects/typed-racket/optimizer/tool/tool.rkt @@ -198,7 +198,7 @@ ;; redraw (send definitions add-highlights #:use-cache? #t))] [value (memq f filters)])) - panel) ; return panel, so that the other mixing can hide it + panel) ; return panel, so that the other mixin can hide it (define/public (hide-optimization-coach-panel [close #t]) (when panel From a53ff364ac74bb6dc0ff6c5323c963a2d0b8ecc3 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Fri, 20 Jul 2012 16:25:02 -0400 Subject: [PATCH 588/746] Replace fields with local-member-name accessors. (cherry picked from commit 848a28266c133a9b5dcedc8398eb4c8e597ab172) --- collects/typed-racket/optimizer/tool/tool.rkt | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/collects/typed-racket/optimizer/tool/tool.rkt b/collects/typed-racket/optimizer/tool/tool.rkt index 96b530850a..edd37b7662 100644 --- a/collects/typed-racket/optimizer/tool/tool.rkt +++ b/collects/typed-racket/optimizer/tool/tool.rkt @@ -34,12 +34,16 @@ ,(match-lambda [(sub-report-entry s m 'mzc) #t] [_ #f])))) -(define-local-member-name get-optimization-coach-menu-item) -(define-local-member-name highlighting-shown?) -(define-local-member-name add-highlights) -(define-local-member-name clear-highlights) -(define-local-member-name show-optimization-coach-panel) -(define-local-member-name hide-optimization-coach-panel) +(define-local-member-name + get-optimization-coach-menu-item + highlighting-shown? + add-highlights + clear-highlights + show-optimization-coach-panel + hide-optimization-coach-panel + get-filters + set-filters! + optimization-coach-visible?) (define optimization-coach-drracket-button (list @@ -70,7 +74,9 @@ ;; sub, show it. ;; Note: at the point where these are called, report entries have ;; a single sub. - (init-field [filters (map cdr check-boxes)]) ; all enabled by default + (define filters (map cdr check-boxes)) ; all enabled by default + (define/public (get-filters) filters) + (define/public (set-filters! fs) (set! filters fs)) ;; highlight-range, for ranges that span multiple lines, highlights ;; to the end of the first n-1 lines. Since the space at end of lines @@ -173,7 +179,8 @@ (inherit get-defs get-frame) - (init-field [panel #f]) + (define panel #f) + (define/public (optimization-coach-visible?) panel) (define/public (show-optimization-coach-panel) (set! panel @@ -185,16 +192,16 @@ [label "Clear"] [parent panel] [callback (lambda _ (send definitions clear-highlights))]) - (define filters (get-field filters definitions)) + (define filters (send definitions get-filters)) (for ([(l f) (in-pairs check-boxes)]) (new check-box% [label l] [parent panel] [callback (lambda _ - (set-field! filters definitions (if (memq f filters) - (remq f filters) - (cons f filters))) + (send definitions set-filters! (if (memq f filters) + (remq f filters) + (cons f filters))) ;; redraw (send definitions add-highlights #:use-cache? #t))] [value (memq f filters)])) @@ -224,20 +231,22 @@ [demand-callback (λ (item) (send item set-label - (if (get-field panel (get-current-tab)) + (if (send (get-current-tab) + optimization-coach-visible?) (string-constant hide-optimization-coach) (string-constant show-optimization-coach))))] [callback (λ (a b) (define tab (get-current-tab)) - (if (get-field panel tab) + (if (send tab optimization-coach-visible?) (send (send tab get-defs) clear-highlights) (optimization-coach-callback this)))])) (set-show-menu-sort-key optimization-coach-menu-item 403)) (define/augment (on-tab-change old-tab new-tab) (send old-tab hide-optimization-coach-panel #f) ; don't close it - (when (get-field panel new-tab) ; if it was open before + (when (send new-tab optimization-coach-visible?) + ;; if it was open before (send new-tab show-optimization-coach-panel))) (define optimization-coach-menu-item #f) From 80b209728372f38e1c179cf7d3db69363c7ac4b6 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 21 Jul 2012 06:57:50 -0500 Subject: [PATCH 589/746] fix a bug introduced by commit 05b88930c0a19b8e8d56433ca8273f635c50793b the symptom of the bug is that the red error highlighting never worked Please merge to the release branch (cherry picked from commit 5b96803273b0f2cd8f52cffd61d99a88c09f2d6f) --- collects/drracket/private/rep.rkt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/collects/drracket/private/rep.rkt b/collects/drracket/private/rep.rkt index 4b6d4948e1..534ee60137 100644 --- a/collects/drracket/private/rep.rkt +++ b/collects/drracket/private/rep.rkt @@ -766,9 +766,10 @@ TODO (define/augment (after-edit-sequence) (inner (void) after-edit-sequence) - (let ([to-clean had-an-insert]) - (set! had-an-insert '()) - (update-after-inserts to-clean))) + (unless (null? had-an-insert) + (let ([to-clean had-an-insert]) + (set! had-an-insert '()) + (update-after-inserts to-clean)))) (define/private (update-after-inserts starts) (unless inserting-prompt? From 2efef0949b5aac00231a754a8cab6a4d489ffe55 Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Sat, 21 Jul 2012 11:06:55 -0400 Subject: [PATCH 590/746] fixed minor typo (cherry picked from commit 30cb1ce4f33462b27ec138b39c9ef4ddcb594e88) --- collects/scribblings/draw/guide.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/draw/guide.scrbl b/collects/scribblings/draw/guide.scrbl index cda393a6a1..a2f8e2fd50 100644 --- a/collects/scribblings/draw/guide.scrbl +++ b/collects/scribblings/draw/guide.scrbl @@ -363,7 +363,7 @@ and a transparent brush produces Drawing a single path with three line segments is not the same as drawing three separate lines. When multiple line segments are drawn at -once, the corner frm one line to the next is shaped according to the +once, the corner from one line to the next is shaped according to the pen's join style. The image above uses the default @racket['round] join style. With @racket['miter], line lines are joined with sharp corners: From e1e9148d7832e4d072f858fc256cae1431fb3ac1 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 21 Jul 2012 11:33:53 -0500 Subject: [PATCH 591/746] adjust the interface reference in drracket for the new view menu (cherry picked from commit df4508573a32e3400bf209901fecd547ad078f1e) --- collects/scribblings/drracket/menus.scrbl | 92 +++++++++++-------- .../scribblings/guide/optimization.scrbl | 2 +- 2 files changed, 57 insertions(+), 37 deletions(-) diff --git a/collects/scribblings/drracket/menus.scrbl b/collects/scribblings/drracket/menus.scrbl index 136136c9e5..c2d37dbd2e 100644 --- a/collects/scribblings/drracket/menus.scrbl +++ b/collects/scribblings/drracket/menus.scrbl @@ -16,6 +16,8 @@ @item{@defmenuitem{New} Creates a new DrRacket window.} + @item{@defmenuitem{New Tab} Creates a new tab in the current DrRacket window.} + @item{@defmenuitem{Open...} Opens a find-file dialog for choosing a file to load into a @tech{definitions window}.} @@ -178,6 +180,22 @@ appears at any time. @itemize[ + @item{@defmenuitem{Toolbar} + @itemize[ + @item{@defmenuitem{Toolbar on Left} Moves the tool bar (on the top of DrRacket's window by default) to the left-hand side, organized vertically.} + @item{@defmenuitem{Toolbar on Top} Moves the toolbar to the top of the DrRacket window.} + @item{@defmenuitem{Toolbar on Right} Moves the tool bar to the right-hand side, organized vertically.} + @item{@defmenuitem{Toolbar Hidden} Hides the toolbar entirely.}]} + + @item{@defmenuitem{Split} Splits the current window in half to + allow for two different portions of the current window to + be visible simultaneously.} + + @item{@defmenuitem{Collapse} If the window has been split before, this + menu item becomes enabled, allowing you to collapse the split + window.} + + @item{@defmenuitem{Show Definitions} Shows the definitions window.} @item{@defmenuitem{Hide Definitions} Hides the definitions window.} @@ -186,12 +204,41 @@ appears at any time. @item{@defmenuitem{Hide Interactions} Hides interactions window.} + @item{@defmenuitem{Use Vertical Layout} and @defmenuitem{Use Horizontal Layout} + adjust the definitions and interactions window so they + are either beside each other or with the definitions above + the interactions window.} + + @item{@defmenuitem{Show Log} Shows the current log messages.} + @item{@defmenuitem{Hide Log} Hides the current log messages.} + + @item{@defmenuitem{Show Tracing} Shows a trace of functions called since + the last time @onscreen{Run} was clicked. This menu is useful only if + you have enabled tracing in the @onscreen{Choose Language...} dialog's + @onscreen{Details} section. Profiling does not apply to all languages.} + + @item{@defmenuitem{Hide Tracing} Hides the tracing display.} + + @item{@defmenuitem{Show Profile} Shows the current profiling + report. This menu is useful only if you have enabled profiling in + the @onscreen{Choose Language...} dialog's @onscreen{Details} + section. Profiling does not apply to all languages.} + + @item{@defmenuitem{Hide Profile} Hides any profiling + information currently displayed in the DrRacket window.} + @item{@defmenuitem{Show Program Contour} Shows a ``20,000 foot'' overview window along the edge of the DrRacket window. Each pixel in this window corresponds to a letter in the program text.} @item{@defmenuitem{Hide Program Contour} Hides the contour window.} + + @item{@defmenuitem{Show Line Numbers} Shows line numbers in the + definitions window.} + + @item{@defmenuitem{Hide Line Numbers} Hides the line numbers in the + definitions window.} @item{@defmenuitem{Show Module Browser} Shows the module DAG rooted at the currently opened file in DrRacket. @@ -201,46 +248,19 @@ appears at any time. @item{@defmenuitem{Hide Module Browser} Hides the module browser. See also @secref["module-browser"].} - - @item{@defmenuitem{Toolbar} -@itemize[ -@item{@defmenuitem{Toolbar on Left} Moves the tool bar (on the top of DrRacket's window by default) to the left-hand side, organized vertically.} -@item{@defmenuitem{Toolbar on Top} Moves the toolbar to the top of the DrRacket window.} -@item{@defmenuitem{Toolbar on Right} Moves the tool bar to the right-hand side, organized vertically.} -@item{@defmenuitem{Toolbar Hidden} Hides the toolbar entirely.}]} - - @item{@defmenuitem{Show Log} Shows the current log messages.} - @item{@defmenuitem{Hide Log} Hides the current log messages.} - - @item{@defmenuitem{Show Profile} Shows the current profiling - report. This menu is useful only if you have enabled profiling in - the @onscreen{Choose Language...} dialog's @onscreen{Details} - section. Profiling does not apply to all languages.} - - @item{@defmenuitem{Hide Profile} Hides any profiling - information currently displayed in the DrRacket window.} - - @item{@defmenuitem{Dock Test Report} Like the dock button on the test report - window, this causes all test report windows to merge with the appropriate - DrRacket window at the bottom of the frame.} - @item{@defmenuitem{Undock Test Report} Like the undock button on the test report - window, this causes the test reports attached to appropriate DrRacket tabs - to become separate windows.} - @item{@defmenuitem{Show Tracing} Shows a trace of functions called since - the last time @onscreen{Run} was clicked. This menu is useful only if - you have enabled tracing in the @onscreen{Choose Language...} dialog's - @onscreen{Details} section. Profiling does not apply to all languages.} + @item{@defmenuitem{Show Optimization Coach} + Shows information about opportunities for + optimizations. - @item{@defmenuitem{Hide Tracing} Hides the tracing display.} + See also @secref[#:doc '(lib "ts-guide.scrbl" "typed-racket" "scribblings") + "optimization-coach"].} - @item{@defmenuitem{Split} Splits the current window in half to - allow for two different portions of the current window to - be visible simultaneously.} + @item{@defmenuitem{Hide Optimization Coach} Hides the optimization coach. + + See also @secref[#:doc '(lib "ts-guide.scrbl" "typed-racket" "scribblings") + "optimization-coach"].} - @item{@defmenuitem{Collapse} If the window has been split before, this - menu item becomes enabled, allowing you to collapse the split - window.} ] diff --git a/collects/typed-racket/scribblings/guide/optimization.scrbl b/collects/typed-racket/scribblings/guide/optimization.scrbl index d34ca0ac60..8a4f6a8345 100644 --- a/collects/typed-racket/scribblings/guide/optimization.scrbl +++ b/collects/typed-racket/scribblings/guide/optimization.scrbl @@ -159,7 +159,7 @@ preferable to vectors. Typed Racket can optimize struct access in all cases. -@subsection{Optimization Coaching} +@subsection[#:tag "optimization-coach"]{Optimization Coaching} Typed Racket provides optimization coaching support to help you get the most of its optimizer. From a671407b769c639f30db1dae44b98ae1e968a43b Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sat, 21 Jul 2012 12:22:40 -0500 Subject: [PATCH 592/746] add a Copy menu to the error message from the online expansion stuff closes PR 12923 (cherry picked from commit c4a768af007a62a42ed908b5bbe6a36bdaf0d444) --- collects/drracket/private/module-language.rkt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/collects/drracket/private/module-language.rkt b/collects/drracket/private/module-language.rkt index 9ad601a3b1..fa9f054514 100644 --- a/collects/drracket/private/module-language.rkt +++ b/collects/drracket/private/module-language.rkt @@ -1151,11 +1151,28 @@ (define error-message% (class canvas% (init-field msg err?) - (inherit refresh get-dc get-client-size) + (inherit refresh get-dc get-client-size popup-menu) (define/public (set-msg _msg _err?) (set! msg _msg) (set! err? _err?) (refresh)) + (define/override (on-event evt) + (cond + [(and (send evt button-down?) err?) + (define m (new popup-menu%)) + (define itm (new menu-item% + [label (string-constant copy-menu-item)] + [parent m] + [callback + (λ (itm evt) + (send the-clipboard set-clipboard-string + msg + (send evt get-time-stamp)))])) + (popup-menu m + (+ (send evt get-x) 1) + (+ (send evt get-y) 1))] + [else + (super on-event evt)])) (define/override (on-paint) (define dc (get-dc)) (define-values (cw ch) (get-client-size)) From 4c2d03dde0fa45cd49cd30fa96af71d7ae855987 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 22 Jul 2012 10:11:37 -0400 Subject: [PATCH 593/746] Quick typo fix. (cherry picked from commit c2fe7c4e3578a72086fb99bd7ee3f4b96201dc43) --- collects/scribblings/reference/sequences.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/reference/sequences.scrbl b/collects/scribblings/reference/sequences.scrbl index 621dc29ae8..84ee0c679e 100644 --- a/collects/scribblings/reference/sequences.scrbl +++ b/collects/scribblings/reference/sequences.scrbl @@ -496,7 +496,7 @@ in the sequence. so that @racket[stream-first] produces the same result each time is applied to a stream. - In extracting an element from @racket[seq] involves a side-effect, + If extracting an element from @racket[seq] involves a side-effect, then the effect is performed each time that either @racket[stream-first] or @racket[stream-rest] is first used to access or skip an element.} From f9131630ceb58f7a9218ec5b6cfa79a706960c49 Mon Sep 17 00:00:00 2001 From: Mike Sperber Date: Sun, 22 Jul 2012 16:37:44 +0200 Subject: [PATCH 594/746] Synch German string constants with latest. (cherry picked from commit 0dd571ef53a8843b866b68d1c33afff0ef68aad9) --- .../private/german-string-constants.rkt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/collects/string-constants/private/german-string-constants.rkt b/collects/string-constants/private/german-string-constants.rkt index 6ef78e7870..96688044cd 100644 --- a/collects/string-constants/private/german-string-constants.rkt +++ b/collects/string-constants/private/german-string-constants.rkt @@ -117,6 +117,11 @@ (cs-unused-require "unbenutztes require") (cs-free-variable "freie Variable") + (cs-contract-my-obligation "Vertrag: Obliation dieses Moduls") + (cs-contract-their-obligation "Vertrag: Obligation des Klientenmoduls") + (cs-contract-both-obligation "Vertrag: Obligation sowohl dieses Moduls als auch des Klientenmoduls") + (cs-contract-unk-obligation "Vertrag: Oblikation unbekannt") + ;; mode sub-menu in the "view" menu (cs-check-syntax-mode "Syntax-Check-Modus") (cs-mode-menu-show-my-obligations "Meine Vertragsobligationen") @@ -1549,6 +1554,11 @@ (ask-about-normalizing-strings "Bei Normalisierung nachfragen") (always-use-platform-specific-linefeed-convention "Immer die plattformspezifische Linefeed-Konvention verwenden") + + + ;; optimization coach + (hide-optimization-coach "Optimierungs-Coach ausblenden") + (show-optimization-coach "Optimierungs-Coach einblenden") ) From ba09bf3541c25c5ed9d752ff3dd0fa35bb8b8f72 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 22 Jul 2012 11:32:21 -0500 Subject: [PATCH 595/746] fixes for submodules and `variable-reference->namespace' Closes PR 12925 Merge to 5.3 (cherry picked from commit d95ec4d454efc8a98bfbe2ad055c020ee7af880e) --- collects/compiler/zo-structs.rkt | 2 +- collects/scribblings/raco/zo-struct.scrbl | 2 +- collects/tests/racket/submodule.rktl | 51 +++++++++++++ src/racket/src/compenv.c | 2 +- src/racket/src/module.c | 92 ++++++++++++++++++----- src/racket/src/schpriv.h | 4 +- src/racket/src/syntax.c | 38 ++++++++++ 7 files changed, 168 insertions(+), 23 deletions(-) diff --git a/collects/compiler/zo-structs.rkt b/collects/compiler/zo-structs.rkt index a6c9749db9..d16b9fbd66 100644 --- a/collects/compiler/zo-structs.rkt +++ b/collects/compiler/zo-structs.rkt @@ -124,7 +124,7 @@ [max-let-depth exact-nonnegative-integer?] [dummy toplevel?] [lang-info (or/c #f (vector/c module-path? symbol? any/c))] - [internal-context (or/c #f #t stx?)] + [internal-context (or/c #f #t stx? (listof stx?))] [pre-submodules (listof mod?)] [post-submodules (listof mod?)])) diff --git a/collects/scribblings/raco/zo-struct.scrbl b/collects/scribblings/raco/zo-struct.scrbl index 3c9e06e95f..330fdd7438 100644 --- a/collects/scribblings/raco/zo-struct.scrbl +++ b/collects/scribblings/raco/zo-struct.scrbl @@ -173,7 +173,7 @@ structures that are produced by @racket[zo-parse] and consumed by [max-let-depth exact-nonnegative-integer?] [dummy toplevel?] [lang-info (or/c #f (vector/c module-path? symbol? any/c))] - [internal-context (or/c #f #t stx?)] + [internal-context (or/c #f #t stx? (listof stx?))] [pre-submodules (listof mod?)] [post-submodules (listof mod?)])]{ Represents a @racket[module] declaration. diff --git a/collects/tests/racket/submodule.rktl b/collects/tests/racket/submodule.rktl index 662fb8a68a..bce629630c 100644 --- a/collects/tests/racket/submodule.rktl +++ b/collects/tests/racket/submodule.rktl @@ -711,6 +711,57 @@ (attach-tests #f) (attach-tests #t)) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; module->namespace + +(module check-to-namespace-1 racket/base + (module* main #f + (define x 10) + (define v + (eval 'x (variable-reference->namespace (#%variable-reference)))) + (provide v))) + +(test 10 dynamic-require `(submod 'check-to-namespace-1 main) 'v) + +(module check-to-namespace-2 racket/base + (require racket/math) + (module* main #f + (define v + (eval 'pi (variable-reference->namespace (#%variable-reference)))) + (provide v))) + +(require racket/math) +(test pi dynamic-require `(submod 'check-to-namespace-2 main) 'v) + +(module check-to-namespace-3.0 racket/base + (define x 13) + (define v + (eval 'x (variable-reference->namespace (#%variable-reference)))) + (provide v)) + +(test 13 dynamic-require ''check-to-namespace-3.0 'v) + +(module check-to-namespace-3 racket/base + (define x 13) + (module* main #f + (define v + (eval 'x (variable-reference->namespace (#%variable-reference)))) + (provide v))) + +(test 13 dynamic-require `(submod 'check-to-namespace-3 main) 'v) + +(let ([path (build-path (current-directory) "ctn-no-such-file.rkt")]) + (parameterize ([current-module-declare-name (make-resolved-module-path path)]) + (eval + '(module check-to-namespace-3 racket/base + (define x 130) + (module* main #f + (define v + (eval 'x (variable-reference->namespace (#%variable-reference)))) + (provide v))))) + (test 130 dynamic-require `(submod ,path main) 'v)) + + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/src/racket/src/compenv.c b/src/racket/src/compenv.c index d0585ee63d..1fc21e42bb 100644 --- a/src/racket/src/compenv.c +++ b/src/racket/src/compenv.c @@ -1951,7 +1951,7 @@ scheme_lookup_binding(Scheme_Object *find_id, Scheme_Comp_Env *env, int flags, pos = 0; else pos = scheme_check_accessible_in_module(genv, env->insp, in_modidx, - find_id, src_find_id, NULL, NULL, rename_insp, -1, 1, + find_id, src_find_id, NULL, env->insp, rename_insp, -1, 1, _protected, NULL, env->genv, NULL, &mod_constant); modpos = (int)SCHEME_INT_VAL(pos); } else diff --git a/src/racket/src/module.c b/src/racket/src/module.c index 2ec54d5787..8f02fd1873 100644 --- a/src/racket/src/module.c +++ b/src/racket/src/module.c @@ -122,6 +122,7 @@ typedef struct Module_Begin_Expand_State { Scheme_Hash_Table *modidx_cache; Scheme_Object *redef_modname; Scheme_Object *end_statementss; /* list of lists */ + Scheme_Object *rn_stx; } Module_Begin_Expand_State; static Scheme_Object *do_module_begin_at_phase(Scheme_Object *form, Scheme_Comp_Env *env, @@ -2912,17 +2913,45 @@ void scheme_prep_namespace_rename(Scheme_Env *menv) m->rn_stx = rns; } else if (SCHEME_PAIRP(m->rn_stx)) { /* Delayed shift: */ - Scheme_Object *rn_stx, *midx; - rn_stx = SCHEME_CAR(m->rn_stx); + Scheme_Object *vec, *vec2, *rn_stx, *midx; + int i; + + vec = SCHEME_CAR(m->rn_stx); midx = SCHEME_CDR(m->rn_stx); - rns = scheme_stx_to_rename(rn_stx); - rns = scheme_stx_shift_rename_set(rns, midx, m->self_modidx, m->insp); - rn_stx = scheme_rename_to_stx(rns); - m->rn_stx = rn_stx; + + if (!SCHEME_VECTORP(vec)) + vec = scheme_make_vector(1, vec); + vec2 = scheme_make_vector(SCHEME_VEC_SIZE(vec), NULL); + + for (i = SCHEME_VEC_SIZE(vec); i--; ) { + rn_stx = SCHEME_VEC_ELS(vec)[i]; + rns = scheme_stx_to_rename(rn_stx); + rns = scheme_stx_shift_rename_set(rns, midx, m->self_modidx, m->insp); + rn_stx = scheme_rename_to_stx(rns); + SCHEME_VEC_ELS(vec2)[i] = rn_stx; + } + + m->rn_stx = vec2; + } + + /* add rename(s) to the environment's rename: */ + { + int i; + Scheme_Object *vec = m->rn_stx, *prior = NULL; + + if (!SCHEME_VECTORP(vec)) { + vec = scheme_make_vector(1, vec); + m->rn_stx = vec; + } + + for (i = SCHEME_VEC_SIZE(vec); i--; ) { + rns = scheme_stx_to_rename(SCHEME_VEC_ELS(vec)[i]); + scheme_append_rename_set_to_env(rns, menv); + prior = scheme_accum_prior_contexts(rns, prior); + } + scheme_install_prior_contexts_to_env(prior, menv); } - rns = scheme_stx_to_rename(m->rn_stx); - scheme_append_rename_set_to_env(rns, menv); menv->rename_set_ready = 1; } } @@ -6898,7 +6927,7 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, scheme_false); } else { void **super_bxs_info; - Scheme_Object *rn; + Scheme_Object *rn, *rnss, *rnss2, *rn2; iidx = scheme_make_modidx(scheme_make_pair(submod_symbol, scheme_make_pair(scheme_make_utf8_string(".."), @@ -6912,14 +6941,25 @@ static Scheme_Object *do_module(Scheme_Object *form, Scheme_Comp_Env *env, top_env->module->self_modidx, iidx, menv->module_registry->exports, env->insp, NULL); + + rnss2 = scheme_null; + for (rnss = super_bxs->rn_stx; SCHEME_PAIRP(rnss); rnss = SCHEME_CDR(rnss)) { + rn2 = scheme_stx_to_rename(SCHEME_CAR(rnss)); + rn2 = scheme_stx_shift_rename_set(rn2, + top_env->module->self_modidx, iidx, + env->insp); + rnss2 = scheme_make_pair(scheme_rename_to_stx(rn2), rnss2); + } + rnss2 = scheme_reverse(rnss2); - super_bxs_info = MALLOC_N(void*, 6); + super_bxs_info = MALLOC_N(void*, 7); super_bxs_info[0] = super_bxs; super_bxs_info[1] = rn; super_bxs_info[2] = top_env->module->self_modidx; super_bxs_info[3] = iidx; super_bxs_info[4] = top_env; super_bxs_info[5] = super_phase_shift; + super_bxs_info[6] = rnss2; m->super_bxs_info = super_bxs_info; } @@ -7639,7 +7679,7 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env Scheme_Module_Export_Info **exp_infos, *exp_info; Scheme_Module_Phase_Exports *pt; Scheme_Object *post_ex_rn_set; /* phase -> post_ex_rn-like rename */ - Scheme_Object *form, *redef_modname, *rn_set, *observer, **exis, *body_lists, *expanded_l; + Scheme_Object *form, *redef_modname, *rn_set, *observer, **exis, *body_lists, *expanded_l, *rn_stx; Scheme_Env *genv; Module_Begin_Expand_State *bxs; Scheme_Expand_Info crec; @@ -7664,18 +7704,12 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env modidx_cache = scheme_make_hash_table_equal(); - rn_set = env->genv->rename_set; - { - Scheme_Object *v; - v = scheme_rename_to_stx(rn_set); - env->genv->module->rn_stx = v; - } - all_provided = scheme_make_hash_table_equal(); all_reprovided = scheme_make_hash_table_equal(); all_defs = scheme_make_hash_tree(1); all_defs_out = scheme_make_hash_table_equal(); + rn_set = env->genv->rename_set; post_ex_rn_set = scheme_make_module_rename_set(mzMOD_RENAME_MARKED, rn_set, env->genv->module->insp); /* It's possible that #%module-begin expansion introduces @@ -7691,6 +7725,22 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env all_simple_renames = (int *)scheme_malloc_atomic(sizeof(int)); *all_simple_renames = 1; + if (env->genv->module->super_bxs_info) { + rn_stx = scheme_rename_to_stx(post_ex_rn_set); + *all_simple_renames = 0; + } else + rn_stx = scheme_rename_to_stx(rn_set); + if (env->genv->module->super_bxs_info && env->genv->module->super_bxs_info[6]) + rn_stx = scheme_make_pair(rn_stx, env->genv->module->super_bxs_info[6]); + { + Scheme_Object *v; + if (SCHEME_PAIRP(rn_stx)) + v = scheme_list_to_vector(rn_stx); + else + v = rn_stx; + env->genv->module->rn_stx = v; + } + bxs = scheme_malloc(sizeof(Module_Begin_Expand_State)); bxs->post_ex_rn_set = post_ex_rn_set; bxs->tables = tables; @@ -7974,6 +8024,10 @@ static Scheme_Object *do_module_begin(Scheme_Object *orig_form, Scheme_Comp_Env (void)do_module_execute(o, env->genv, 0, 1, root_module_name, NULL); } + if (!SCHEME_PAIRP(rn_stx)) + rn_stx = scheme_make_pair(rn_stx, scheme_null); + bxs->rn_stx = rn_stx; + if (!rec[drec].comp && (is_modulestar_stop(env))) { Scheme_Object *l = bxs->saved_submodules; expanded_modules = NULL; @@ -9059,7 +9113,7 @@ static Scheme_Object *expand_submodules(Scheme_Compile_Expand_Info *rec, int dre Scheme_Comp_Env *env, Scheme_Object *l, int post, Module_Begin_Expand_State *bxs, - int keep_expanded) + int keep_expanded) { Scheme_Object *mods = scheme_null, *mod, *ancestry; diff --git a/src/racket/src/schpriv.h b/src/racket/src/schpriv.h index 12524ae011..22f8932ca6 100644 --- a/src/racket/src/schpriv.h +++ b/src/racket/src/schpriv.h @@ -1007,6 +1007,8 @@ Scheme_Object *scheme_get_module_rename_from_set(Scheme_Object *set, Scheme_Obje Scheme_Hash_Table *scheme_get_module_rename_marked_names(Scheme_Object *set, Scheme_Object *phase, int create); void scheme_append_rename_set_to_env(Scheme_Object *rns, Scheme_Env *env); +void scheme_install_prior_contexts_to_env(Scheme_Object *prior, Scheme_Env *env); +Scheme_Object *scheme_accum_prior_contexts(Scheme_Object *rns, Scheme_Object *prior); void scheme_seal_module_rename(Scheme_Object *rn, int level); void scheme_seal_module_rename_set(Scheme_Object *rns, int level); @@ -3122,7 +3124,7 @@ typedef struct Scheme_Module Scheme_Env *primitive; - Scheme_Object *rn_stx; + Scheme_Object *rn_stx; /* NULL, #t, a stx for a rename, a vector of stxes, or a pair to delay shifts */ Scheme_Object *submodule_path; /* path to this module relative to enclosing top-level module */ Scheme_Object *pre_submodules, *post_submodules; /* list of modules (when compiled or loaded as a group) */ diff --git a/src/racket/src/syntax.c b/src/racket/src/syntax.c index 67a1b55d84..955ad50723 100644 --- a/src/racket/src/syntax.c +++ b/src/racket/src/syntax.c @@ -170,6 +170,7 @@ typedef struct Module_Renames_Set { Scheme_Object so; /* scheme_rename_table_set_type */ char kind, sealed; Scheme_Object *set_identity; + Scheme_Object *prior_contexts; /* for module->namespace */ Module_Renames *rt, *et; Scheme_Hash_Table *other_phases; Scheme_Object *share_marked_names; /* a Module_Renames_Set */ @@ -1634,6 +1635,23 @@ void scheme_append_rename_set_to_env(Scheme_Object *_mrns, Scheme_Env *env) } } +void scheme_install_prior_contexts_to_env(Scheme_Object *prior, Scheme_Env *env) +{ + if (prior) { + prior = SCHEME_CDR(prior); + if (!SCHEME_NULLP(prior)) { + ((Module_Renames_Set *)env->rename_set)->prior_contexts = prior; + } + } +} + +Scheme_Object *scheme_accum_prior_contexts(Scheme_Object *rns, Scheme_Object *prior) +{ + if (!prior) + prior = scheme_null; + return scheme_make_pair(((Module_Renames_Set *)rns)->set_identity, prior); +} + void scheme_remove_module_rename(Scheme_Object *mrn, Scheme_Object *localname) { @@ -1715,6 +1733,9 @@ Scheme_Object *scheme_stx_to_rename(Scheme_Object *stx) if (!rns) { rns = scheme_make_module_rename_set(((Module_Renames *)v)->kind, NULL, NULL); ((Module_Renames_Set *)rns)->set_identity = ((Module_Renames *)v)->set_identity; + } else if (!SAME_OBJ(((Module_Renames_Set *)rns)->set_identity, + ((Module_Renames *)v)->set_identity)) { + scheme_signal_error("can't convert syntax to rename (identity mismatch)"); } scheme_add_module_rename_to_set(rns, v); } else { @@ -1798,6 +1819,8 @@ Scheme_Object *scheme_stx_shift_rename_set(Scheme_Object *_mrns, mrns2 = scheme_make_module_rename_set(mrns->kind, NULL, new_insp); ((Module_Renames_Set *)mrns2)->sealed = mrns->sealed; + ((Module_Renames_Set *)mrns2)->set_identity = mrns->set_identity; + if (mrns->rt) { mrn = scheme_stx_shift_rename((Scheme_Object *)mrns->rt, old_midx, new_midx, new_insp); scheme_add_module_rename_to_set(mrns2, mrn); @@ -3084,6 +3107,21 @@ static Scheme_Object *get_old_module_env(Scheme_Object *stx) kind = mrns->kind; set_identity = mrns->set_identity; + + if (mrns->prior_contexts) { + /* A rename-set with a prior context should be last */ + if (SCHEME_FALSEP(result_id)) { + result_id = mrns->prior_contexts; + if (SCHEME_NULLP(SCHEME_CDR(result_id))) + result_id = SCHEME_CAR(result_id); + } else { + if (!SCHEME_PAIRP(result_id)) { + result_id = scheme_make_pair(result_id, scheme_null); + last_pr = result_id; + } + SCHEME_CDR(last_pr) = mrns->prior_contexts; + } + } } if ((kind != mzMOD_RENAME_TOPLEVEL) From 28a6a7b9221186140c23c96c430e28ec1ebbee30 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 23 Jul 2012 20:56:16 -0400 Subject: [PATCH 596/746] Re-bump the version to an alpha one. --- src/racket/src/schvers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/racket/src/schvers.h b/src/racket/src/schvers.h index e263c18428..5c5f3fb4c7 100644 --- a/src/racket/src/schvers.h +++ b/src/racket/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "5.2.900" +#define MZSCHEME_VERSION "5.2.900.1" #define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 900 -#define MZSCHEME_VERSION_W 0 +#define MZSCHEME_VERSION_W 1 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) From 020d056febb85562210c1892b49924e4f7364961 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 23 Jul 2012 22:15:31 -0400 Subject: [PATCH 597/746] New Racket version 5.2.900.1. --- src/worksp/gracket/gracket.manifest | 2 +- src/worksp/gracket/gracket.rc | 8 ++++---- src/worksp/mzcom/mzcom.rc | 8 ++++---- src/worksp/mzcom/mzobj.rgs | 6 +++--- src/worksp/racket/racket.manifest | 2 +- src/worksp/racket/racket.rc | 8 ++++---- src/worksp/starters/start.rc | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/worksp/gracket/gracket.manifest b/src/worksp/gracket/gracket.manifest index efeb78edf6..2341783e47 100644 --- a/src/worksp/gracket/gracket.manifest +++ b/src/worksp/gracket/gracket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/gracket/gracket.rc b/src/worksp/gracket/gracket.rc index 59aaf51261..33ffe2c13f 100644 --- a/src/worksp/gracket/gracket.rc +++ b/src/worksp/gracket/gracket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "gracket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,900,0 - PRODUCTVERSION 5,2,900,0 + FILEVERSION 5,2,900,1 + PRODUCTVERSION 5,2,900,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket GUI application\0" VALUE "InternalName", "GRacket\0" - VALUE "FileVersion", "5, 2, 900, 0\0" + VALUE "FileVersion", "5, 2, 900, 1\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "GRacket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 900, 0\0" + VALUE "ProductVersion", "5, 2, 900, 1\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzcom.rc b/src/worksp/mzcom/mzcom.rc index 4e14eea934..e617914037 100644 --- a/src/worksp/mzcom/mzcom.rc +++ b/src/worksp/mzcom/mzcom.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,900,0 - PRODUCTVERSION 5,2,900,0 + FILEVERSION 5,2,900,1 + PRODUCTVERSION 5,2,900,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -70,12 +70,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "MzCOM Module" - VALUE "FileVersion", "5, 2, 900, 0" + VALUE "FileVersion", "5, 2, 900, 1" VALUE "InternalName", "MzCOM" VALUE "LegalCopyright", "Copyright 2000-2012 PLT (Paul Steckler)" VALUE "OriginalFilename", "MzCOM.EXE" VALUE "ProductName", "MzCOM Module" - VALUE "ProductVersion", "5, 2, 900, 0" + VALUE "ProductVersion", "5, 2, 900, 1" END END BLOCK "VarFileInfo" diff --git a/src/worksp/mzcom/mzobj.rgs b/src/worksp/mzcom/mzobj.rgs index 6c82508015..465b7777ac 100644 --- a/src/worksp/mzcom/mzobj.rgs +++ b/src/worksp/mzcom/mzobj.rgs @@ -1,19 +1,19 @@ HKCR { - MzCOM.MzObj.5.2.900.0 = s 'MzObj Class' + MzCOM.MzObj.5.2.900.1 = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' } MzCOM.MzObj = s 'MzObj Class' { CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}' - CurVer = s 'MzCOM.MzObj.5.2.900.0' + CurVer = s 'MzCOM.MzObj.5.2.900.1' } NoRemove CLSID { ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class' { - ProgID = s 'MzCOM.MzObj.5.2.900.0' + ProgID = s 'MzCOM.MzObj.5.2.900.1' VersionIndependentProgID = s 'MzCOM.MzObj' ForceRemove 'Programmable' LocalServer32 = s '%MODULE%' diff --git a/src/worksp/racket/racket.manifest b/src/worksp/racket/racket.manifest index f8dda35b87..3bbf686517 100644 --- a/src/worksp/racket/racket.manifest +++ b/src/worksp/racket/racket.manifest @@ -1,6 +1,6 @@ - diff --git a/src/worksp/racket/racket.rc b/src/worksp/racket/racket.rc index 45a57f90e9..ece8c32489 100644 --- a/src/worksp/racket/racket.rc +++ b/src/worksp/racket/racket.rc @@ -11,8 +11,8 @@ APPLICATION ICON DISCARDABLE "racket.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,900,0 - PRODUCTVERSION 5,2,900,0 + FILEVERSION 5,2,900,1 + PRODUCTVERSION 5,2,900,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -30,11 +30,11 @@ BEGIN VALUE "CompanyName", "PLT Scheme Inc.\0" VALUE "FileDescription", "Racket application\0" VALUE "InternalName", "Racket\0" - VALUE "FileVersion", "5, 2, 900, 0\0" + VALUE "FileVersion", "5, 2, 900, 1\0" VALUE "LegalCopyright", "Copyright 1995-2012\0" VALUE "OriginalFilename", "racket.exe\0" VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 900, 0\0" + VALUE "ProductVersion", "5, 2, 900, 1\0" END END BLOCK "VarFileInfo" diff --git a/src/worksp/starters/start.rc b/src/worksp/starters/start.rc index 8ca5006336..8bd200a6d8 100644 --- a/src/worksp/starters/start.rc +++ b/src/worksp/starters/start.rc @@ -22,8 +22,8 @@ APPLICATION ICON DISCARDABLE "mzstart.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,2,900,0 - PRODUCTVERSION 5,2,900,0 + FILEVERSION 5,2,900,1 + PRODUCTVERSION 5,2,900,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,7 +45,7 @@ BEGIN #ifdef MZSTART VALUE "FileDescription", "Racket Launcher\0" #endif - VALUE "FileVersion", "5, 2, 900, 0\0" + VALUE "FileVersion", "5, 2, 900, 1\0" #ifdef MRSTART VALUE "InternalName", "mrstart\0" #endif @@ -60,7 +60,7 @@ BEGIN VALUE "OriginalFilename", "MzStart.exe\0" #endif VALUE "ProductName", "Racket\0" - VALUE "ProductVersion", "5, 2, 900, 0\0" + VALUE "ProductVersion", "5, 2, 900, 1\0" END END BLOCK "VarFileInfo" From cc998b9fe1305f4e0ad8d2df5bf0b0d800d6ab02 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sun, 22 Jul 2012 13:38:26 -0400 Subject: [PATCH 598/746] Use a new evaluaor in "for.scrbl", have it require `racket/base' for syntax. Also explicitly close the evaluator used in "block.scrbl". Closes PR 12931. (cherry picked from commit 476c270a66c594d1da8d778f299b2aa0fd682015) --- collects/scribblings/reference/block.scrbl | 1 + collects/scribblings/reference/for.scrbl | 16 +++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/collects/scribblings/reference/block.scrbl b/collects/scribblings/reference/block.scrbl index 7dacbf16a2..61a3aad2ad 100644 --- a/collects/scribblings/reference/block.scrbl +++ b/collects/scribblings/reference/block.scrbl @@ -33,3 +33,4 @@ an expression. (f 12) ]} +@close-eval[ev] diff --git a/collects/scribblings/reference/for.scrbl b/collects/scribblings/reference/for.scrbl index 1df1941944..87f64fbba8 100644 --- a/collects/scribblings/reference/for.scrbl +++ b/collects/scribblings/reference/for.scrbl @@ -5,10 +5,12 @@ @guideintro["for"]{iterations and comprehensions} +@(define for-eval (make-base-eval)) +@(for-eval '(require (for-syntax racket/base))) + The @racket[for] iteration forms are based on SRFI-42 @cite["SRFI-42"]. - @section{Iteration and Comprehension Forms} @defform/subs[(for (for-clause ...) body ...+) @@ -284,9 +286,11 @@ Like @racket[for/list], etc., but with the implicit nesting of @defform[(for/fold/derived orig-datum ([accum-id init-expr] ...) (for-clause ...) body ...+)]{ -Like @racket[for/fold], but the extra @racket[orig-datum] is used as the source for all syntax errors. -@mz-examples[ +Like @racket[for/fold], but the extra @racket[orig-datum] is used as the +source for all syntax errors. + +@mz-examples[#:eval for-eval (define-syntax (for/digits stx) (syntax-case stx () [(_ clauses . defs+exprs) @@ -314,7 +318,7 @@ Like @racket[for/fold], but the extra @racket[orig-datum] is used as the source ([accum-id init-expr] ...) (for-clause ...) body ...+)]{ Like @racket[for*/fold], but the extra @racket[orig-datum] is used as the source for all syntax errors. -@mz-examples[ +@mz-examples[#:eval for-eval (define-syntax (for*/digits stx) (syntax-case stx () [(_ clauses . defs+exprs) @@ -373,7 +377,7 @@ use @racket[:do-in]. To protect identifiers in the result of @racket[clause-transform-expr], use @racket[for-clause-syntax-protect] instead of @racket[syntax-protect]. -@mz-examples[ +@mz-examples[#:eval for-eval (define-sequence-syntax in-digits (lambda () #'in-digits/proc) (lambda (stx) @@ -482,3 +486,5 @@ When @racket[stop?-expr] produces a true value, then the evaluated in tail position to produce the overall value for the @racket[do] form. If no @racket[finish-expr] is provided, the value of the @racket[do] form is @|void-const|.} + +@close-eval[for-eval] From 02c6dbb3b135e76d12fb035dcbd0f4fccc62b867 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 22 Jul 2012 11:37:48 -0500 Subject: [PATCH 599/746] fix bug in inline code merge to the release branch, please (cherry picked from commit 519b69362f54522542b62bf6658360df62baef8f) --- collects/redex/scribblings/tut.scrbl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/redex/scribblings/tut.scrbl b/collects/redex/scribblings/tut.scrbl index 2a89c3e4a2..14a10b3d16 100644 --- a/collects/redex/scribblings/tut.scrbl +++ b/collects/redex/scribblings/tut.scrbl @@ -603,7 +603,7 @@ To define a reduction relation, we also have to define substitution. Generally speaking, substitution functions are tricky to get right and, since they generally are not shown in papers, we have defined a workhorse substitution function in Racket that runs in near linear -time. The source code is included with Redex, if you'd like to have a look; +time. The source code is included with Redex. If you'd like to have a look, evaluate the expression below in the REPL to find the precise path on your system: @@ -847,8 +847,8 @@ shape. Use this definition of @racket[subst]. subst : (x v) ... e -> e [(subst (x v) ... e) ,(subst/proc x? - (list (term (x ...))) - (list (term (v ...))) + (term (x ...)) + (term (v ...)) (term e))])] Also, adjust the typing rules (and do not forget that an ellipsis can be named, From 385fee5b9b444e34ce653a6d631bd30a91b2a7b4 Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 22 Jul 2012 19:50:44 -0500 Subject: [PATCH 600/746] increase timeout for the sharing modules drracket test case (cherry picked from commit d282843116664c32187f62527b5f3acb857347e2) Conflicts: collects/meta/props --- collects/meta/props | 1 + 1 file changed, 1 insertion(+) diff --git a/collects/meta/props b/collects/meta/props index 73847addb3..35edcd648c 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -1027,6 +1027,7 @@ path/s is either such a string or a list of them. "collects/tests/drracket/syncheck-test.rkt" drdr:command-line (gracket *) drdr:timeout 200 "collects/tests/drracket/teaching-lang-coverage.rkt" responsible (robby matthias) drdr:command-line (gracket *) "collects/tests/drracket/teaching-lang-save-file.rkt" responsible (robby matthias) drdr:command-line (gracket *) +"collects/tests/drracket/teaching-lang-sharing-modules.rkt" drdr:timeout 800 "collects/tests/drracket/teachpack.rkt" responsible (robby matthias) drdr:command-line (gracket *) "collects/tests/drracket/test-engine-test.rkt" responsible (sperber) drdr:command-line (gracket *) drdr:timeout 480 "collects/tests/eli-tester.rkt" responsible (eli) From 31b1f8a89952f4fca186db7e855b83d337394efb Mon Sep 17 00:00:00 2001 From: James Swaine Date: Wed, 18 Jul 2012 15:03:35 -0500 Subject: [PATCH 601/746] Fix future visualizer trace collection when running inside DrRacket (cherry picked from commit df54f8460b0d053227eca9475c7ee561afd99631) --- collects/future-visualizer/main.rkt | 4 +- .../private/visualizer-data.rkt | 129 ++++++++++++------ collects/future-visualizer/trace.rkt | 6 +- .../scribblings/reference/futures-trace.scrbl | 6 +- .../reference/futures-visualizer.scrbl | 4 +- src/racket/src/future.c | 4 +- 6 files changed, 99 insertions(+), 54 deletions(-) diff --git a/collects/future-visualizer/main.rkt b/collects/future-visualizer/main.rkt index 02945a269b..713f43b525 100644 --- a/collects/future-visualizer/main.rkt +++ b/collects/future-visualizer/main.rkt @@ -36,13 +36,13 @@ [p pict?])])) (define-syntax-rule (visualize-futures e ...) - (begin (start-performance-tracking!) + (begin (start-future-tracing!) (begin0 (begin e ...) (show-visualizer)))) ;;visualize-futures-thunk : (-> any/c) -> any/c (define (visualize-futures-thunk thunk) - (start-performance-tracking!) + (start-future-tracing!) (begin0 (thunk) (show-visualizer))) diff --git a/collects/future-visualizer/private/visualizer-data.rkt b/collects/future-visualizer/private/visualizer-data.rkt index f6c5103f62..4553f5d8fc 100644 --- a/collects/future-visualizer/private/visualizer-data.rkt +++ b/collects/future-visualizer/private/visualizer-data.rkt @@ -2,13 +2,13 @@ (require racket/bool racket/list racket/contract - racket/future + racket/future racket/set "constants.rkt" "graph-drawing.rkt" - (only-in '#%futures init-visualizer-tracking!)) + (only-in '#%futures init-visualizer-tracking!)) -(provide start-performance-tracking! +(provide start-future-tracing! (struct-out future-event) (struct-out indexed-future-event) (struct-out trace) @@ -19,22 +19,17 @@ timeline-events organize-output build-trace + missing-data? event-has-duration? + op-name touch-event? allocation-event? jitcompile-event? + synchronization-event? + runtime-synchronization-event? final-event? relative-time) -;Log message receiver -(define recv #f) - -;;start-performance-tracking! -> void -(define (start-performance-tracking!) - (when (not recv) - (init-visualizer-tracking!) - (set! recv (make-log-receiver (current-logger) 'debug)))) - (define-struct future-event (future-id process-id what time prim-name user-data) #:prefab) @@ -106,16 +101,53 @@ [(start-work start-0-work) #t] [else #f])) +(define (missing-data? log) + (if (findf (λ (e) (equal? (future-event-what (indexed-future-event-fevent e)) 'missing)) log) + #t + #f)) + +;;event-op-name : (or event indexed-future-event future-event) -> symbol +(define (op-name evt) + (cond + [(event? evt) (event-prim-name evt)] + [(indexed-future-event? evt) (future-event-prim-name (indexed-future-event-fevent evt))] + [(future-event? evt) (future-event-prim-name evt)])) + +;;event-what : (or event indexed-future-event future-event) -> symbol +(define (what evt) + (cond + [(event? evt) (event-type evt)] + [(indexed-future-event? evt) (future-event-what (indexed-future-event-fevent evt))] + [(future-event? evt) (future-event-what evt)])) + +;;process-id : (or event indexed-future-event future-event) -> exact-nonnegative-integer +(define (process-id evt) + (cond + [(event? evt) (event-proc-id evt)] + [(indexed-future-event? evt) (future-event-process-id (indexed-future-event-fevent evt))] + [(future-event? evt) (future-event-process-id evt)])) + +;;touch-event? : (or event indexed-future-event future-event) -> symbol (define (touch-event? evt) - (equal? (event-prim-name evt) 'touch)) + (equal? (what evt) 'touch)) -;;allocation-event? : event -> bool +;;allocation-event? : (or event indexed-future-event future-event) -> bool (define (allocation-event? evt) - (equal? (event-prim-name evt) '|[allocate memory]|)) + (equal? (op-name evt) '|[allocate memory]|)) -;;jitcompile-event : event -> bool +;;jitcompile-event : (or event indexed-future-event future-event) -> bool (define (jitcompile-event? evt) - (equal? (event-prim-name evt) '|[jit_on_demand]|)) + (equal? (op-name evt) '|[jit_on_demand]|)) + +;;synchronization-event? : (or event indexed-future-event future-event) -> bool +(define (synchronization-event? evt) + (case (what evt) + [(block sync) #t] + [else #f])) + +;;runtime-synchronization-event? : (or event indexed-future-event future-event) -> bool +(define (runtime-synchronization-event? evt) + (and (synchronization-event? evt) (= (process-id evt) RT-THREAD-ID))) ;;final-event? : event -> bool (define (final-event? evt) @@ -127,21 +159,32 @@ (define (relative-time trace abs-time) (- abs-time (trace-start-time trace))) -;;timeline-events/private : integer -> (listof indexed-future-event) -(define (timeline-events/private index) - (let ([index 0] - [info (sync/timeout 0 recv)]) +;Log message receiver +(define recv #f) + +;;start-future-tracing! -> void +(define (start-future-tracing!) + (when (not recv) + (set! recv (make-log-receiver (init-visualizer-tracking!) 'debug)))) + +(define (timeline-events/private) + (let ([info (sync/timeout 0 recv)]) (if info (let ([v (vector-ref info 2)]) (if (future-event? v) - (cons (indexed-future-event index v) (timeline-events/private (add1 index))) - (timeline-events/private index))) + (cons v (timeline-events/private)) + (timeline-events/private))) '()))) - + ;Gets log events for an execution timeline ;;timeline-events : (listof indexed-future-event) (define (timeline-events) - (timeline-events/private 0)) + (define sorted (sort (timeline-events/private) + #:key future-event-time + <)) + (for/list ([fe (in-list sorted)] + [i (in-naturals)]) + (indexed-future-event i fe))) ;Produces a vector of vectors, where each inner vector contains ;all the log output messages for a specific process @@ -156,23 +199,19 @@ ;;build-trace : (listof indexed-future-event) -> trace (define (build-trace log-output) + (when (empty? log-output) + (error 'build-trace "Empty timeline in log-output")) (define data (organize-output log-output)) - (define-values (start-time end-time unique-fids nblocks nsyncs) - (for/fold ([start-time #f] - [end-time #f] - [unique-fids (set)] + (define start-time (future-event-time (indexed-future-event-fevent (car log-output)))) + (define end-time (future-event-time (indexed-future-event-fevent (last log-output)))) + (define-values (unique-fids nblocks nsyncs) + (for/fold ([unique-fids (set)] [nblocks 0] [nsyncs 0]) ([ie (in-list log-output)]) (let* ([evt (indexed-future-event-fevent ie)] [fid (future-event-future-id evt)] [is-future-thread? (not (= (future-event-process-id evt) RT-THREAD-ID))]) (values - (if start-time - (min start-time (future-event-time evt)) - (future-event-time evt)) - (if end-time - (max end-time (future-event-time evt)) - (future-event-time evt)) (if fid (set-add unique-fids fid) unique-fids) @@ -225,10 +264,9 @@ #f #f #f))))))) - (define all-evts (sort (flatten (for/list ([tl (in-list tls)]) - (process-timeline-events tl))) - (λ (a b) - (< (event-index a) (event-index b))))) + (define all-evts (sort (flatten (for/list ([tl (in-list tls)]) (process-timeline-events tl))) + #:key event-index + <)) (define ftls (let ([h (make-hash)]) (for ([evt (in-list all-evts)]) (let* ([fid (event-future-id evt)] @@ -341,10 +379,15 @@ ;;buid-creation-graph/private : (uint -o-> (listof future-event)) -> (listof node) (define (build-creation-graph/private future-timelines evt) (let* ([fid (event-user-data evt)] - [fevents (filter creation-event? (hash-ref future-timelines fid))]) - (for/list ([cevt (in-list fevents)]) - (node cevt - (build-creation-graph/private future-timelines cevt))))) + [ftimeline (hash-ref future-timelines fid #f)]) + (if ftimeline + (let ([fevents (filter creation-event? (hash-ref future-timelines fid #f))]) + (for/list ([cevt (in-list fevents)]) + (node cevt + (build-creation-graph/private future-timelines cevt)))) + (begin + (eprintf "WARNING: Could not find timeline for future ~a. Creation tree may be truncated.\n" fid) + '())))) ;;build-creation-graph : (uint -o-> (listof future-event)) -> node (define (build-creation-graph future-timelines) diff --git a/collects/future-visualizer/trace.rkt b/collects/future-visualizer/trace.rkt index dfdf506900..57a1953d9e 100644 --- a/collects/future-visualizer/trace.rkt +++ b/collects/future-visualizer/trace.rkt @@ -5,18 +5,18 @@ (struct-out indexed-future-event) trace-futures (contract-out - [start-performance-tracking! (-> void?)] + [start-future-tracing! (-> void?)] [timeline-events (-> (listof indexed-future-event?))] [trace-futures-thunk ((-> any/c) . -> . (listof indexed-future-event?))])) (define-syntax-rule (trace-futures e ...) - (begin (start-performance-tracking!) + (begin (start-future-tracing!) (begin (begin e ...) (timeline-events)))) ;;trace-futures-thunk : (-> any) -> (listof indexed-future-event) (define (trace-futures-thunk thunk) - (start-performance-tracking!) + (start-future-tracing!) (begin (thunk) (timeline-events))) \ No newline at end of file diff --git a/collects/scribblings/reference/futures-trace.scrbl b/collects/scribblings/reference/futures-trace.scrbl index 7a900c1a00..8eddfd6c22 100644 --- a/collects/scribblings/reference/futures-trace.scrbl +++ b/collects/scribblings/reference/futures-trace.scrbl @@ -36,7 +36,7 @@ the execution of parallel programs written using @racket[future]. (require racket/future future-visualizer/trace) - (start-performance-tracking!) + (start-future-tracing!) (let ([f (future (lambda () ...))]) ... (touch f)) @@ -46,10 +46,10 @@ the execution of parallel programs written using @racket[future]. } @deftogether[( - @defproc[(start-performance-tracking!) void?] + @defproc[(start-future-tracing!) void?] @defproc[(timeline-events) (listof indexed-future-event?)] )]{ - The @racket[start-performance-tracking!] procedure enables the collection + The @racket[start-future-tracing!] procedure enables the collection of future-related execution data. This function should be called immediately prior to executing code the programmer wishes to profile. diff --git a/collects/scribblings/reference/futures-visualizer.scrbl b/collects/scribblings/reference/futures-visualizer.scrbl index 12849ccc44..84ab0c3c23 100644 --- a/collects/scribblings/reference/futures-visualizer.scrbl +++ b/collects/scribblings/reference/futures-visualizer.scrbl @@ -42,7 +42,7 @@ at any point during the program's lifetime. future-visualizer/trace future-visualizer) - (start-performance-tracking!) + (start-future-tracing!) (let ([f (future (lambda () ...))]) ... (touch f)) @@ -53,7 +53,7 @@ at any point during the program's lifetime. @defproc[(show-visualizer [#:timeline timeline (listof indexed-future-event?)]) void?]{ Displays the visualizer window. If the function is called with no arguments, - it must be preceded by a call to @racket[start-performance-tracking!] -- in which case + it must be preceded by a call to @racket[start-future-tracing!] -- in which case the visualizer will show data for all events logged in between (via @racket[timeline-events]). Note that @racket[visualize-futures] and @racket[visualize-futures-thunk] are simpler alternatives to using these primitives directly. diff --git a/src/racket/src/future.c b/src/racket/src/future.c index 994dbc3634..4e19817ce1 100644 --- a/src/racket/src/future.c +++ b/src/racket/src/future.c @@ -957,7 +957,9 @@ static Scheme_Object *reset_future_logs_for_tracking(int argc, Scheme_Object **a Scheme_Future_State *fs; Scheme_Future_Thread_State *fts; Scheme_Future_Thread_State *rt_fts; + Scheme_Logger *logger; + logger = scheme_main_logger; fs = scheme_future_state; rt_fts = scheme_future_thread_state; if (fs) { @@ -983,7 +985,7 @@ static Scheme_Object *reset_future_logs_for_tracking(int argc, Scheme_Object **a } - return scheme_void; + return logger; } static double get_future_timestamp() XFORM_SKIP_PROC { From 10628ef0b91c8589dcd5c707ff35d421357196b7 Mon Sep 17 00:00:00 2001 From: James Swaine Date: Wed, 18 Jul 2012 15:21:50 -0500 Subject: [PATCH 602/746] Add unit tests for future-visualizer/trace (cherry picked from commit 5214995967684595a628275ada33e41c4e2cd86e) --- collects/tests/future/trace.rkt | 94 +++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 collects/tests/future/trace.rkt diff --git a/collects/tests/future/trace.rkt b/collects/tests/future/trace.rkt new file mode 100644 index 0000000000..b1f809560e --- /dev/null +++ b/collects/tests/future/trace.rkt @@ -0,0 +1,94 @@ +#lang racket/base +(require rackunit + racket/future + future-visualizer/private/visualizer-data + (for-syntax racket/base + future-visualizer/private/visualizer-data) + (only-in future-visualizer/trace trace-futures)) + +#| + +Invariants: +-It is not possible for a future to have an empty timeline, even if it never + executes on anything other than the runtime thread. +-Cannot have two consecutive 'start-work events on the same future, same thread. +-For each future created there must exist exactly one 'create event. +-The number of events matching synchronization-event? must always match the + number of runtime-synchronization-event? events. + +|# + +;Stable sort by timestamp, then check +;index ordering +(define-syntax (check-ordering stx) + (syntax-case stx () + [(_ log) + (with-syntax ([line (syntax-line stx)]) + #'(let ([time-sorted (sort log + #:key (λ (e) (future-event-time (indexed-future-event-fevent e))) + <)]) + (let loop ([sorted time-sorted]) + (define cur (car sorted)) + (define rest (cdr sorted)) + (unless (null? rest) + (define next (car rest)) + (define curtime (future-event-time (indexed-future-event-fevent cur))) + (define curind (indexed-future-event-index cur)) + (define nextind (indexed-future-event-index next)) + (define nexttime (future-event-time (indexed-future-event-fevent cur))) + (check-true (< curind + nextind) + (format + "Incorrect event ordering at line ~a: event with (index=~a, time=~a) + occurs before event with (index=~a, time=~a)\n" + line + curind + curtime + nextind + nexttime)) + (loop rest)))))])) + + +(define log1 (parameterize ([current-output-port (open-output-string)]) + (trace-futures + (let ([fs (for/list ([i (in-range 0 1000)]) + (future (λ () + (printf "hello\n"))))]) + (sleep 0.1) + (map touch fs))))) +(check-true (> (length log1) 2000)) +;Event types +(check-equal? (length (filter (λ (e) (and (synchronization-event? e) + (equal? (op-name e) 'printf))) + log1)) + 1000) +(define syncs-len (length (filter synchronization-event? log1))) +(check-true (>= syncs-len 1000)) +(check-true (<= syncs-len 2000)) +(check-ordering log1) +(define tr1 (build-trace log1)) +;Keys should include all unique future id's, and one entry for #f +;(events logged on runtime thread outside scope of any future) +(check-equal? (length (hash-keys (trace-future-timelines tr1))) 1001) + + +(define log3 (trace-futures + (parameterize ([current-command-line-arguments #("2000")] + [current-output-port (open-output-string)]) + (void (dynamic-require 'tests/racket/benchmarks/shootout/mandelbrot-futures #f))))) +(check-true (> (length log3) 0)) +(define tr3 (build-trace log3)) +(check-equal? (length (hash-keys (trace-future-timelines tr3))) 2001) + + +(define log4 (trace-futures + (let ([f (future (λ () + (for/list ([i (in-range 0 10000)]) + (cons i (+ i 1)))))]) + (sleep 0.5) + (touch f)))) +(check-true (> (length log4) 0)) +(check-true (list? (memf allocation-event? log4)) "No allocation events found in log4") +(define ae (findf allocation-event? log4)) +(check-true (allocation-event? ae)) +(check-true (runtime-synchronization-event? ae)) \ No newline at end of file From 57a4f9f2f385dfc7fc500fa830a7ac79da1ed1b4 Mon Sep 17 00:00:00 2001 From: James Swaine Date: Wed, 18 Jul 2012 15:36:36 -0500 Subject: [PATCH 603/746] Minor changes to future-visualizer/trace tests (cherry picked from commit e4f50997ad9a0bbf2ee3c17c967ae76c09667cbc) --- collects/tests/future/trace.rkt | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/collects/tests/future/trace.rkt b/collects/tests/future/trace.rkt index b1f809560e..166ef8ab6c 100644 --- a/collects/tests/future/trace.rkt +++ b/collects/tests/future/trace.rkt @@ -27,26 +27,17 @@ Invariants: #'(let ([time-sorted (sort log #:key (λ (e) (future-event-time (indexed-future-event-fevent e))) <)]) - (let loop ([sorted time-sorted]) - (define cur (car sorted)) - (define rest (cdr sorted)) - (unless (null? rest) - (define next (car rest)) - (define curtime (future-event-time (indexed-future-event-fevent cur))) - (define curind (indexed-future-event-index cur)) - (define nextind (indexed-future-event-index next)) - (define nexttime (future-event-time (indexed-future-event-fevent cur))) - (check-true (< curind - nextind) + (for ([e (in-list time-sorted)] + [i (in-naturals)]) + (check-equal? (indexed-future-event-index e) + i (format "Incorrect event ordering at line ~a: event with (index=~a, time=~a) - occurs before event with (index=~a, time=~a)\n" + occurs at actual index ~a\n" line - curind - curtime - nextind - nexttime)) - (loop rest)))))])) + (indexed-future-event-index e) + (future-event-time (indexed-future-event-fevent e)) + i)))))])) (define log1 (parameterize ([current-output-port (open-output-string)]) @@ -67,16 +58,18 @@ Invariants: (check-true (<= syncs-len 2000)) (check-ordering log1) (define tr1 (build-trace log1)) -;Keys should include all unique future id's, and one entry for #f +;Keys should include all unique future id's, and one entry for #f (no future context, on rt thread) ;(events logged on runtime thread outside scope of any future) (check-equal? (length (hash-keys (trace-future-timelines tr1))) 1001) + (define log3 (trace-futures (parameterize ([current-command-line-arguments #("2000")] [current-output-port (open-output-string)]) (void (dynamic-require 'tests/racket/benchmarks/shootout/mandelbrot-futures #f))))) (check-true (> (length log3) 0)) +(check-true (list? (memf jitcompile-event? log3)) "No JIT compilation events found in mandelbrot") (define tr3 (build-trace log3)) (check-equal? (length (hash-keys (trace-future-timelines tr3))) 2001) From a34b7ea3d9436344f037fb18c76e6ecd98319c56 Mon Sep 17 00:00:00 2001 From: James Swaine Date: Thu, 19 Jul 2012 12:04:21 -0500 Subject: [PATCH 604/746] Change future visualizer trace collection slightly to be more composable (cherry picked from commit f0aaca0dde8b2f7376ced7e0e74f0bd352f35fda) --- collects/future-visualizer/main.rkt | 4 +- .../private/visualizer-data.rkt | 23 +++++++++--- collects/future-visualizer/trace.rkt | 5 ++- .../scribblings/reference/futures-trace.scrbl | 8 +++- .../reference/futures-visualizer.scrbl | 7 ++-- src/racket/src/future.c | 37 ++++++++++++++++--- src/racket/src/schminc.h | 2 +- 7 files changed, 67 insertions(+), 19 deletions(-) diff --git a/collects/future-visualizer/main.rkt b/collects/future-visualizer/main.rkt index 713f43b525..1084a995a1 100644 --- a/collects/future-visualizer/main.rkt +++ b/collects/future-visualizer/main.rkt @@ -4,7 +4,7 @@ racket/bool future-visualizer/trace "private/visualizer-gui.rkt" - "private/visualizer-drawing.rkt") + "private/visualizer-drawing.rkt") (provide visualize-futures (contract-out @@ -38,6 +38,7 @@ (define-syntax-rule (visualize-futures e ...) (begin (start-future-tracing!) (begin0 (begin e ...) + (stop-future-tracing!) (show-visualizer)))) ;;visualize-futures-thunk : (-> any/c) -> any/c @@ -45,6 +46,7 @@ (start-future-tracing!) (begin0 (thunk) + (stop-future-tracing!) (show-visualizer))) diff --git a/collects/future-visualizer/private/visualizer-data.rkt b/collects/future-visualizer/private/visualizer-data.rkt index 4553f5d8fc..9a2bec9ccd 100644 --- a/collects/future-visualizer/private/visualizer-data.rkt +++ b/collects/future-visualizer/private/visualizer-data.rkt @@ -6,9 +6,12 @@ racket/set "constants.rkt" "graph-drawing.rkt" - (only-in '#%futures init-visualizer-tracking!)) + (only-in '#%futures + reset-future-logs-for-tracing! + mark-future-trace-end!)) (provide start-future-tracing! + stop-future-tracing! (struct-out future-event) (struct-out indexed-future-event) (struct-out trace) @@ -163,22 +166,30 @@ (define recv #f) ;;start-future-tracing! -> void -(define (start-future-tracing!) +(define (start-future-tracing!) + (reset-future-logs-for-tracing!) (when (not recv) - (set! recv (make-log-receiver (init-visualizer-tracking!) 'debug)))) + (set! recv (make-log-receiver (current-logger) 'debug)))) +;;stop-future-tracing! -> void +(define (stop-future-tracing!) + (mark-future-trace-end!)) + +;;timeline-events/private : -> void (define (timeline-events/private) (let ([info (sync/timeout 0 recv)]) (if info (let ([v (vector-ref info 2)]) (if (future-event? v) - (cons v (timeline-events/private)) + (case (future-event-what v) + [(stop-trace) '()] + [else (cons v (timeline-events/private))]) (timeline-events/private))) - '()))) + (timeline-events/private)))) ;Gets log events for an execution timeline ;;timeline-events : (listof indexed-future-event) -(define (timeline-events) +(define (timeline-events) (define sorted (sort (timeline-events/private) #:key future-event-time <)) diff --git a/collects/future-visualizer/trace.rkt b/collects/future-visualizer/trace.rkt index 57a1953d9e..70abf7083c 100644 --- a/collects/future-visualizer/trace.rkt +++ b/collects/future-visualizer/trace.rkt @@ -5,13 +5,15 @@ (struct-out indexed-future-event) trace-futures (contract-out - [start-future-tracing! (-> void?)] + [start-future-tracing! (-> void?)] + [stop-future-tracing! (-> void?)] [timeline-events (-> (listof indexed-future-event?))] [trace-futures-thunk ((-> any/c) . -> . (listof indexed-future-event?))])) (define-syntax-rule (trace-futures e ...) (begin (start-future-tracing!) (begin (begin e ...) + (stop-future-tracing!) (timeline-events)))) ;;trace-futures-thunk : (-> any) -> (listof indexed-future-event) @@ -19,4 +21,5 @@ (start-future-tracing!) (begin (thunk) + (stop-future-tracing!) (timeline-events))) \ No newline at end of file diff --git a/collects/scribblings/reference/futures-trace.scrbl b/collects/scribblings/reference/futures-trace.scrbl index 8eddfd6c22..bff687080e 100644 --- a/collects/scribblings/reference/futures-trace.scrbl +++ b/collects/scribblings/reference/futures-trace.scrbl @@ -40,19 +40,25 @@ the execution of parallel programs written using @racket[future]. (let ([f (future (lambda () ...))]) ... (touch f)) - + (stop-future-tracing!) (timeline-events) ] } @deftogether[( @defproc[(start-future-tracing!) void?] + @defproc[(stop-future-tracing!) void?] @defproc[(timeline-events) (listof indexed-future-event?)] )]{ The @racket[start-future-tracing!] procedure enables the collection of future-related execution data. This function should be called immediately prior to executing code the programmer wishes to profile. + The @racket[stop-future-tracing!] procedure must be used to indicate the + end of code the programmer wishes to trace. Tracing works by simply using a + log receiver to record all future-related log events; this procedure logs a + special message that is well-known to the log receiver to mean 'stop recording'. + The @racket[timeline-events] procedure returns the program trace as a list of @racket[indexed-future-event] structures. } diff --git a/collects/scribblings/reference/futures-visualizer.scrbl b/collects/scribblings/reference/futures-visualizer.scrbl index 84ab0c3c23..ed78cecf55 100644 --- a/collects/scribblings/reference/futures-visualizer.scrbl +++ b/collects/scribblings/reference/futures-visualizer.scrbl @@ -46,15 +46,16 @@ at any point during the program's lifetime. (let ([f (future (lambda () ...))]) ... (touch f)) - + (stop-future-tracing!) (show-visualizer) ] } @defproc[(show-visualizer [#:timeline timeline (listof indexed-future-event?)]) void?]{ Displays the visualizer window. If the function is called with no arguments, - it must be preceded by a call to @racket[start-future-tracing!] -- in which case - the visualizer will show data for all events logged in between (via @racket[timeline-events]). + it must be preceded by the following sequence: a call to @racket[start-future-tracing!], + program code that is being traced, and a call to @racket[stop-future-tracing!] -- in which case + the visualizer will show data for all events logged in between those calls (via @racket[timeline-events]). Note that @racket[visualize-futures] and @racket[visualize-futures-thunk] are simpler alternatives to using these primitives directly. The @racket[timeline] argument can be used to show the visualizer for a previously-generated diff --git a/src/racket/src/future.c b/src/racket/src/future.c index 4e19817ce1..acbda3b95c 100644 --- a/src/racket/src/future.c +++ b/src/racket/src/future.c @@ -242,6 +242,11 @@ static Scheme_Object *reset_future_logs_for_tracking(int argc, Scheme_Object *ar return scheme_void; } +static Scheme_Object *mark_future_trace_end(int argc, Scheme_Object *argv[]) +{ + return scheme_void; +} + # define FUTURE_PRIM_W_ARITY(name, func, a1, a2, env) GLOBAL_PRIM_W_ARITY(name, func, a1, a2, env) void scheme_init_futures(Scheme_Env *newenv) @@ -259,7 +264,8 @@ void scheme_init_futures(Scheme_Env *newenv) FUTURE_PRIM_W_ARITY("fsemaphore-count", scheme_fsemaphore_count, 1, 1, newenv); FUTURE_PRIM_W_ARITY("would-be-future", would_be_future, 1, 1, newenv); FUTURE_PRIM_W_ARITY("futures-enabled?", futures_enabled, 0, 0, newenv); - FUTURE_PRIM_W_ARITY("init-visualizer-tracking!", reset_future_logs_for_tracking, 0, 0, newenv); + FUTURE_PRIM_W_ARITY("reset-future-logs-for-tracing!", reset_future_logs_for_tracking, 0, 0, newenv); + GLOBAL_PRIM_W_ARITY("mark-future-trace-end!", mark_future_trace_end, 0, 0, newenv); scheme_finish_primitive_module(newenv); scheme_protect_primitive_provide(newenv, NULL); @@ -340,7 +346,8 @@ enum { FEVENT_OVERFLOW, FEVENT_TOUCH_PAUSE, FEVENT_TOUCH_RESUME, - FEVENT_MISSING, + FEVENT_MISSING, + FEVENT_STOP_TRACE, _FEVENT_COUNT_ }; @@ -350,7 +357,7 @@ static const char * const fevent_strs[] = { "create", "complete", "sync", "sync", "block", "touch", "block", "result", "result", "abort", "abort", "suspend", "overflow", - "touch-pause", "touch-resume", "missing" }; + "touch-pause", "touch-resume", "missing", "stop-trace" }; static const char * const fevent_long_strs[] = { "created", "completed", "started work", "started (process 0, only)", "started (overflow)", "ended work", @@ -360,7 +367,7 @@ static const char * const fevent_long_strs[] = { "created", "completed", "abort from process 0", "abort determined", "suspended", "overflow", "paused for touch", "resumed for touch", - "events missing" }; + "events missing", "stop future tracing" }; typedef struct Scheme_Future_State { @@ -429,6 +436,7 @@ static void pop_suspended_lw(Scheme_Future_State *fs, future_t *ft); static Scheme_Object *bad_multi_result_proc; static Scheme_Object *bad_multi_result(int argc, Scheme_Object **argv); static Scheme_Object *reset_future_logs_for_tracking(int argc, Scheme_Object *argv[]); +static Scheme_Object *mark_future_trace_end(int argc, Scheme_Object *argv[]); READ_ONLY static int cpucount; static void init_cpucount(void); @@ -554,7 +562,8 @@ void scheme_init_futures(Scheme_Env *newenv) GLOBAL_PRIM_W_ARITY("would-be-future", would_be_future, 1, 1, newenv); GLOBAL_PRIM_W_ARITY("futures-enabled?", futures_enabled, 0, 0, newenv); - GLOBAL_PRIM_W_ARITY("init-visualizer-tracking!", reset_future_logs_for_tracking, 0, 0, newenv); + GLOBAL_PRIM_W_ARITY("reset-future-logs-for-tracing!", reset_future_logs_for_tracking, 0, 0, newenv); + GLOBAL_PRIM_W_ARITY("mark-future-trace-end!", mark_future_trace_end, 0, 0, newenv); scheme_finish_primitive_module(newenv); scheme_protect_primitive_provide(newenv, NULL); @@ -985,7 +994,7 @@ static Scheme_Object *reset_future_logs_for_tracking(int argc, Scheme_Object **a } - return logger; + return scheme_void; } static double get_future_timestamp() XFORM_SKIP_PROC { @@ -1111,6 +1120,22 @@ static void log_future_event(Scheme_Future_State *fs, } +static Scheme_Object *mark_future_trace_end(int argc, Scheme_Object **argv) +{ + Scheme_Future_State *fs; + fs = scheme_future_state; + log_future_event(fs, + "future %d, process %d: %s: %s; time: %f", + "tracing", + -1, + FEVENT_STOP_TRACE, + get_future_timestamp(), + 0, + 0); + + return scheme_void; +} + static void log_overflow_event(Scheme_Future_State *fs, int which, double timestamp) { log_future_event(fs, diff --git a/src/racket/src/schminc.h b/src/racket/src/schminc.h index 3c67ce324e..832a9620c0 100644 --- a/src/racket/src/schminc.h +++ b/src/racket/src/schminc.h @@ -17,7 +17,7 @@ #define EXPECTED_PRIM_COUNT 1064 #define EXPECTED_UNSAFE_COUNT 79 #define EXPECTED_FLFXNUM_COUNT 69 -#define EXPECTED_FUTURES_COUNT 14 +#define EXPECTED_FUTURES_COUNT 15 #ifdef MZSCHEME_SOMETHING_OMITTED # undef USE_COMPILED_STARTUP From b7ef4569654cc9f5194cb8d948a3a91e62b76db3 Mon Sep 17 00:00:00 2001 From: James Swaine Date: Thu, 19 Jul 2012 13:38:07 -0500 Subject: [PATCH 605/746] Performance improvements in future visualizer GUI (dragging, scrolling, sizing) (cherry picked from commit 06358fa19d5d8b93c9878f07cb8a7e726839955e) --- .../future-visualizer/private/gui-helpers.rkt | 121 +--------------- .../future-visualizer/private/pict-canvas.rkt | 131 ++++++++++++++++++ .../private/visualizer-gui.rkt | 42 +++--- 3 files changed, 154 insertions(+), 140 deletions(-) create mode 100644 collects/future-visualizer/private/pict-canvas.rkt diff --git a/collects/future-visualizer/private/gui-helpers.rkt b/collects/future-visualizer/private/gui-helpers.rkt index d8a0e2736a..60af714779 100644 --- a/collects/future-visualizer/private/gui-helpers.rkt +++ b/collects/future-visualizer/private/gui-helpers.rkt @@ -2,9 +2,9 @@ (require framework slideshow/pict "display.rkt" - "constants.rkt") -(provide pict-canvas% - label + "constants.rkt" + "pict-canvas.rkt") +(provide label mt-label bold-label mt-bold-label @@ -14,115 +14,6 @@ add-receiver post-event) -(define pict-canvas% - (class canvas% - (init redraw-on-resize pict-builder hover-handler click-handler overlay-builder) - (inherit get-dc get-client-size refresh get-view-start) - (define bp pict-builder) ;Builds the main pict for the canvas - (define mh hover-handler) ;Mouse hover handler - (define ob overlay-builder) ;Hover overlay pict builder - (define ch click-handler) ;Mouse click handler - (define draw-on-resize redraw-on-resize) - (define do-logging #f) - (define redraw-overlay #f) ;Whether we should redraw the overlay pict in the canvas - (define redo-bitmap-on-paint #t) ;Redraw the base bitmap on paint? #f for mouse events - (define scale-factor 1) - - (define/public (set-redo-bitmap-on-paint! v) - (set! redo-bitmap-on-paint v)) - - (define/public (set-do-logging! v) - (set! do-logging v)) - - ;;set-build-pict! : (viewable-region -> pict) -> void - (define/public (set-build-pict! f) - (set! bp f)) - - ;;set-mouse-handler! : (uint uint -> segment) -> void - (define/public (set-mouse-handler! f) - (set! mh f)) - - ;;set-overlay-builder! : (viewable-region -> pict) -> void - (define/public (set-overlay-builder! f) - (set! ob f)) - - ;;set-click-handler! : (uint uint -> segment) -> void - (define/public (set-click-handler! f) - (set! ch f)) - - ;;set-redraw-overlay! : bool -> void - (define/public (set-redraw-overlay! b) - (set! redraw-overlay b)) - - (define/public (set-scale-factor! s) - (set! scale-factor s)) - - (define the-drawer #f) - (define img-width 0) - (define bm #f) - (define overlay-pict #f) - - (define/private (get-viewable-region) - (define-values (x y) (get-view-start)) - (define-values (w h) (get-client-size)) - (scale-viewable-region (viewable-region x y w h) (/ 1 scale-factor))) - - (define/private (overlay-drawer dc vregion) - (when ob - (define p (ob vregion scale-factor)) - (unless (or (not p) (void? p)) - (draw-pict p - dc - (viewable-region-x vregion) - (viewable-region-y vregion))))) - - (define/private (redo-bitmap vregion) - (when bp - (define p (scale (bp vregion) scale-factor)) - (set! bm (pict->bitmap p)))) - - (define/public (redraw-everything) - (redo-bitmap (get-viewable-region)) - (refresh)) - - (define/override (on-size width height) - (when (or draw-on-resize - (not bm)) - (set! bm #f) - (refresh)) - (set! redraw-overlay #t)) - - (define/override (on-paint) - (define vregion (get-viewable-region)) - (when (or redo-bitmap-on-paint (not bm)) - (redo-bitmap vregion)) - (unless redo-bitmap-on-paint - (set! redo-bitmap-on-paint #t)) - (when bm - (let ([dc (get-dc)]) - (send dc draw-bitmap - bm - (viewable-region-x vregion) - (viewable-region-y vregion)) - (overlay-drawer dc vregion)))) - - (define/override (on-event event) - (define vregion (get-viewable-region)) - (define x (+ (viewable-region-x vregion) (/ (send event get-x) scale-factor))) - (define y (+ (viewable-region-y vregion) (/ (send event get-y) scale-factor))) - (case (send event get-event-type) - [(motion) - (set! redo-bitmap-on-paint #f) - (when mh (mh x y vregion))] - [(left-up) - (set! redo-bitmap-on-paint #f) - (when ch (ch x y vregion))]) - (when redraw-overlay - (refresh))) - - (super-new) - (send (get-dc) set-smoothing 'aligned))) - (define bold-system-font (send the-font-list find-or-create-font (send normal-control-font get-point-size) @@ -165,9 +56,6 @@ HEADER-HEIGHT) (header-backcolor)) text-container))] - [hover-handler #f] - [click-handler #f] - [overlay-builder #f] [min-height HEADER-HEIGHT] [stretchable-width #t] [stretchable-height #f])]) @@ -182,9 +70,6 @@ (header-backcolor)) text-container) -1.57079633))] - [hover-handler #f] - [click-handler #f] - [overlay-builder #f] [min-width HEADER-HEIGHT] [stretchable-width #f] [stretchable-height #t])]) diff --git a/collects/future-visualizer/private/pict-canvas.rkt b/collects/future-visualizer/private/pict-canvas.rkt new file mode 100644 index 0000000000..ded6627c98 --- /dev/null +++ b/collects/future-visualizer/private/pict-canvas.rkt @@ -0,0 +1,131 @@ +#lang racket/gui +(require framework + slideshow/pict + "display.rkt") +(provide pict-canvas%) + + +(define pict-canvas% + (class canvas% + (init pict-builder [hover-handler #f] + [click-handler #f] + [overlay-builder #f] + [redraw-on-resize #f]) + (inherit get-dc get-client-size refresh get-view-start) + (define bp pict-builder) ;Builds the main pict for the canvas + (define mh hover-handler) ;Mouse hover handler + (define ob overlay-builder) ;Hover overlay pict builder + (define ch click-handler) ;Mouse click handler + (define redraw-on-size redraw-on-resize) ;Whether we should rebuild the pict for on-size events + + (define redraw-overlay #f) ;Whether we should redraw the overlay pict in the canvas + (define redo-bitmap-on-paint #t) ;Redraw the base bitmap on paint? #f for mouse events + (define scale-factor 1) + + ;;set-redraw-overlay! : bool -> void + (define/public (set-redraw-overlay! b) + (set! redraw-overlay b)) + + (define/public (set-scale-factor! s) + (set! scale-factor s)) + + (define needs-redraw #f) + (define delaying-redraw #f) + (define cached-bitmap #f) + (define cached-base-pict #f) + + (define/private (get-viewable-region) + (define-values (x y) (get-view-start)) + (define-values (w h) (get-client-size)) + (scale-viewable-region (viewable-region x y w h) (/ 1 scale-factor))) + + (define/public (redraw-everything) + (redraw-the-bitmap/maybe-delayed! (get-viewable-region))) + + ;Rebuild both the bottom (base) and overlay (top) + ;pict layers for the canvas + ;;rebuild-the-pict : viewable-region -> void + (define/private (rebuild-the-pict vregion #:only-the-overlay? [only-the-overlay? #f]) + (define p (cond + [(or (not cached-base-pict) (not only-the-overlay?)) + (define base (scale (bp vregion) scale-factor)) + (set! cached-base-pict base) + (if ob + (pin-over base + 0 + 0 + (ob vregion scale-factor)) + base)] + [else (if ob + (pin-over cached-base-pict + 0 + 0 + (ob vregion scale-factor)) + cached-base-pict)])) + (pict->bitmap p)) + + ;Rebuilds the pict and stashes in a bitmap + ;to be drawn to the canvas later + ;;redraw-the-bitmap : viewable-region -> void + (define/private (redraw-the-bitmap! vregion #:only-the-overlay? [only-the-overlay? #f]) + (set! cached-bitmap (rebuild-the-pict vregion #:only-the-overlay? only-the-overlay?)) + (set! needs-redraw #f)) + + ;;redraw-the-bitmap/maybe-delayed! : viewable-region -> void + (define/private (redraw-the-bitmap/maybe-delayed! vregion + #:only-the-overlay? [only-the-overlay? #f]) + (cond + [needs-redraw (redraw-the-bitmap! vregion #:only-the-overlay? only-the-overlay?)] + [(not delaying-redraw) + (new timer% [notify-callback (λ () + (set! delaying-redraw #f) + (set! needs-redraw #t) + (redraw-the-bitmap/maybe-delayed! (get-viewable-region)) + (refresh))] + [interval 100] + [just-once? #t]) + (set! delaying-redraw #t)])) + + ;If we haven't already introduced a 100ms delay, + ;add one. If the delay's expired, rebuild the pict + ;;on-size : uint uint -> void + (define/override (on-size width height) + (when redraw-on-size + (redraw-the-bitmap/maybe-delayed! (get-viewable-region)))) + + (define/override (on-paint) + (define vregion (get-viewable-region)) + (redraw-the-bitmap/maybe-delayed! vregion) + (define dc (get-dc)) + (when cached-bitmap + (send dc + draw-bitmap + cached-bitmap + (viewable-region-x vregion) + (viewable-region-y vregion)))) + + (define/override (on-event event) + (define vregion (get-viewable-region)) + (define x (+ (viewable-region-x vregion) (/ (send event get-x) scale-factor))) + (define y (+ (viewable-region-y vregion) (/ (send event get-y) scale-factor))) + (case (send event get-event-type) + [(motion) + (when mh + (when (mh x y vregion) ;Mouse handler returns non-false if a state change requiring redraw occurred + (redraw-the-bitmap/maybe-delayed! vregion #:only-the-overlay? #t)))] + [(left-up) + (when ch (ch x y vregion)) ;Ditto for click handler + (redraw-the-bitmap/maybe-delayed! vregion #:only-the-overlay? #t)])) + + (super-new) + (send (get-dc) set-smoothing 'aligned))) + + + + + + + + + + diff --git a/collects/future-visualizer/private/visualizer-gui.rkt b/collects/future-visualizer/private/visualizer-gui.rkt index d5a5b37bbd..3244cb303d 100644 --- a/collects/future-visualizer/private/visualizer-gui.rkt +++ b/collects/future-visualizer/private/visualizer-gui.rkt @@ -7,7 +7,8 @@ "gui-helpers.rkt" "graph-drawing.rkt" "display.rkt" - "constants.rkt") + "constants.rkt" + "pict-canvas.rkt") (provide show-visualizer) @@ -102,13 +103,16 @@ [height winh])) (define main-panel (new panel:horizontal-dragable% [parent (send f get-area-container)])) + (define left-panel (new panel:horizontal-dragable% [parent main-panel] - [stretchable-width #t])) + [stretchable-width #t] + [min-width 0])) (define hlist-ctl (new hierarchical-list% [parent left-panel] [stretchable-width #t] [stretchable-height #t] - [style '(control-border)])) + [style '(control-border)] + [min-width 0])) ;Build up items in the hierlist (define block-node (send hlist-ctl new-list)) @@ -128,8 +132,7 @@ [stretchable-width #t])) (define graphic-panel (new panel:horizontal-dragable% [parent right-panel] - [stretchable-height #t] - [min-width (inexact->exact (round (* winw .8)))])) + [stretchable-height #t])) (define timeline-container (new vertical-panel% [parent graphic-panel] [stretchable-width #t] @@ -145,8 +148,7 @@ (define-values (frameinfo segments) (calc-segments the-trace)) (define timeline-mouse-index (rebuild-mouse-index frameinfo the-trace segments)) (define timeline-panel (new pict-canvas% - [parent timeline-container] - [redraw-on-resize #f] + [parent timeline-container] [pict-builder (λ (vregion) (timeline-pict-for-trace-data vregion the-trace frameinfo segments))] [hover-handler (λ (x y vregion) (let ([seg (find-seg-for-coords x y timeline-mouse-index)]) @@ -155,15 +157,14 @@ [click-handler (λ (x y vregion) (let ([seg (find-seg-for-coords x y timeline-mouse-index)]) (set! tacked-seg seg) - (post-event listener-table 'segment-click timeline-panel seg)))] + (post-event listener-table 'segment-click timeline-panel seg) + seg))] [overlay-builder (λ (vregion scale-factor) (timeline-overlay vregion tacked-seg hover-seg frameinfo the-trace))] - [min-width 500] - [min-height (inexact->exact (round (* winh .7)))] [style '(hscroll vscroll)] [stretchable-width #t])) ;; TODO sometimes the sizes passed to the scrollbars are so big we blow up! @@ -182,16 +183,15 @@ (define hovered-graph-node #f) (define creategraph-panel (new pict-canvas% - [parent graph-container] - [redraw-on-resize #f] + [parent graph-container] [pict-builder (λ (vregion) (draw-creategraph-pict vregion creation-tree-layout))] - [hover-handler #f #;(λ (x y vregion) - (set! hovered-graph-node - (find-node-for-coords x - y - (graph-layout-nodes creation-tree-layout))))] + #;[hover-handler #f (λ (x y vregion) + (set! hovered-graph-node + (find-node-for-coords x + y + (graph-layout-nodes creation-tree-layout))))] [click-handler (λ (x y vregion) (define fid (find-fid-for-coords x y (graph-layout-nodes creation-tree-layout) @@ -202,14 +202,12 @@ (send timeline-panel set-redraw-overlay! #t) (send timeline-panel refresh) (post-event listener-table 'segment-click timeline-panel seg)))] - [overlay-builder (λ (vregion scale-factor) + #;[overlay-builder (λ (vregion scale-factor) (graph-overlay-pict hovered-graph-node the-trace creation-tree-layout vregion scale-factor))] - [min-width 500] - [min-height 500] [style '(hscroll vscroll)] [stretchable-width #t])) @@ -218,7 +216,7 @@ (inexact->exact (floor (graph-layout-width creation-tree-layout))) (inexact->exact (floor (graph-layout-height creation-tree-layout))) 0.0 - 0.0) + 0.0) (define graph-footer (new horizontal-panel% @@ -350,5 +348,5 @@ (send graphic-panel add-child graph-container) (send item set-label "Hide Creation Tree"))) (set! showing-create-graph (not showing-create-graph)))]) - + (send f show #t)) From a79b122f5e0448261e15f41780eb657f990e5e47 Mon Sep 17 00:00:00 2001 From: James Swaine Date: Thu, 19 Jul 2012 15:13:13 -0500 Subject: [PATCH 606/746] Fix "dancing flags" issue with timeline ticks in future visualizer (cherry picked from commit 6eed135d023755d4afc9d01430d9c711f878d9bf) --- .../private/visualizer-drawing.rkt | 137 ++++++++---------- collects/tests/future/visualizer.rkt | 23 ++- 2 files changed, 72 insertions(+), 88 deletions(-) diff --git a/collects/future-visualizer/private/visualizer-drawing.rkt b/collects/future-visualizer/private/visualizer-drawing.rkt index 4b3ada59c2..673f905848 100644 --- a/collects/future-visualizer/private/visualizer-drawing.rkt +++ b/collects/future-visualizer/private/visualizer-drawing.rkt @@ -58,7 +58,8 @@ ;Represents a vertical line depicting a specific time in the execution history (struct timeline-tick (x abs-time - rel-time) #:transparent) + rel-time + show-label?) #:transparent) ;;viewable-region-from-frame : frame-info -> viewable-region (define (viewable-region-from-frame finfo) @@ -179,19 +180,29 @@ [else (loop (cdr ss))]))) +;;timeline-tick-label-pict : real -> pict +(define (timeline-tick-label-pict rel-time) + (text-block-pict (format "~a ms" (real->decimal-string rel-time)) + #:backcolor (timeline-tick-label-backcolor) + #:forecolor (timeline-tick-label-forecolor) + #:padding 3)) + ;;calc-ticks : (listof segment) float trace -> (listof timeline-tick) (define (calc-ticks segs timeToPixMod tr) + (define LABEL-PAD 3) (define trace-start (inexact->exact (trace-start-time tr))) (define segs-len (length segs)) - (define-values (lt lx tks _) + (define-values (lt lx tks _ __) (for/fold ([last-time trace-start] [last-x 0] [ticks '()] + [last-label-x-extent 0] [remain-segs segs]) ([i (in-range 0 (floor (/ (- (trace-end-time tr) trace-start) DEFAULT-TIME-INTERVAL)))]) - (define tick-time (+ last-time DEFAULT-TIME-INTERVAL)) - (define tick-rel-time (* (add1 i) DEFAULT-TIME-INTERVAL)) + #;(define tick-time (+ last-time DEFAULT-TIME-INTERVAL)) + (define tick-rel-time (* (add1 i) DEFAULT-TIME-INTERVAL)) + (define tick-time (+ trace-start tick-rel-time)) (define want-x (+ last-x (* DEFAULT-TIME-INTERVAL timeToPixMod))) (define-values (most-recent-seg next-seg r-segs) (find-most-recent-and-next remain-segs tick-time)) @@ -201,31 +212,37 @@ (define next-evt-time (inexact->exact (event-start-time next-evt))) (define most-recent-edge (segment-edge most-recent-seg)) (define next-edge (segment-x next-seg)) - (cond - [(= most-recent-time tick-time) - (values tick-time - (segment-x most-recent-seg) - (cons (timeline-tick (segment-x most-recent-seg) tick-time tick-rel-time) ticks) - r-segs)] - [(= (segment-x next-seg) (add1 (+ (segment-x most-recent-seg) (segment-width most-recent-seg)))) - (values tick-time - (+ (segment-x most-recent-seg) (segment-width most-recent-seg)) - (cons (timeline-tick (+ (segment-x most-recent-seg) - (segment-width most-recent-seg)) - tick-time - tick-rel-time) - ticks) - r-segs)] - [else - (define start-x (max most-recent-edge last-x)) - (define start-time (max most-recent-time last-time)) - (define size-mod (/ (- next-edge start-x) (- next-evt-time start-time))) - (define x-offset (ceiling (* (- tick-time start-time) size-mod))) - (define tick-x (round (+ start-x x-offset))) - (values tick-time - tick-x - (cons (timeline-tick tick-x tick-time tick-rel-time) ticks) - r-segs)]))) + (define tick-x + (cond + [(= most-recent-time tick-time) (segment-x most-recent-seg)] + [(= (segment-x next-seg) (add1 (+ (segment-x most-recent-seg) (segment-width most-recent-seg)))) + (+ (segment-x most-recent-seg) (segment-width most-recent-seg))] + [else + (define start-x (max most-recent-edge last-x)) + (define start-time (max most-recent-time last-time)) + (define size-mod (/ (- next-edge start-x) (- next-evt-time start-time))) + (define x-offset (ceiling (* (- tick-time start-time) size-mod))) + (round (+ start-x x-offset))])) + (define show-tick? ((- tick-x last-x) . >= . TIMELINE-MIN-TICK-PADDING)) + (define show-label? + (if (not show-tick?) + #f + (>= tick-x (+ last-label-x-extent LABEL-PAD)))) + (define new-label-x-extent + (if show-label? + (+ tick-x (pict-width (timeline-tick-label-pict tick-rel-time))) + last-label-x-extent)) + (if show-tick? + (values tick-time + tick-x + (cons (timeline-tick tick-x tick-time tick-rel-time show-label?) ticks) + new-label-x-extent + r-segs) + (values tick-time + last-x + ticks + new-label-x-extent + r-segs)))) tks) ;;calc-process-timespan-lines : trace (listof segment) -> (listof (uint . uint)) @@ -373,51 +390,23 @@ ;;draw-ruler-on : pict viewable-region frameinfo -> pict (define (draw-ruler-on base vregion frameinfo) - (let loop ([pct base] - [ticks (filter (λ (t) (in-viewable-region-horiz vregion (timeline-tick-x t))) - (frame-info-timeline-ticks frameinfo))] - [next-label-x (viewable-region-x-extent vregion)] - [next-tick-x (viewable-region-x-extent vregion)]) - (cond - [(null? ticks) pct] - [(< (- next-tick-x (timeline-tick-x (car ticks))) TIMELINE-MIN-TICK-PADDING) - (loop pct - (cdr ticks) - next-label-x - next-tick-x)] - [else (let* ([LABEL-PAD 2] - [VERT-PAD 3] - [cur-tick (car ticks)] - [cur-x (timeline-tick-x cur-tick)] - [tick-desc (format "~a ms" (real->decimal-string - (timeline-tick-rel-time cur-tick) 1))] - [t (text-block-pict tick-desc - #:backcolor (timeline-tick-label-backcolor) - #:forecolor (timeline-tick-label-forecolor) - #:padding 3)] - [text-width (pict-width t)] - [show-label? (<= (+ cur-x LABEL-PAD text-width) next-label-x)] - [pinnedline (pin-over pct - (- cur-x (viewable-region-x vregion)) - 0 - (linestyle 'dot - (colorize (vline 1 - (frame-info-adjusted-height frameinfo)) - (if show-label? - (timeline-tick-bold-color) - (timeline-tick-color)))))]) - (if show-label? - (loop (pin-over pinnedline - (- cur-x (viewable-region-x vregion)) - VERT-PAD - t) - (cdr ticks) - cur-x - cur-x) - (loop pinnedline - (cdr ticks) - next-label-x - cur-x)))]))) + (for/fold ([pct base]) ([tick (in-list (filter (λ (t) (in-viewable-region-horiz vregion (timeline-tick-x t))) + (frame-info-timeline-ticks frameinfo)))]) + (define cur-x (timeline-tick-x tick)) + (define pinnedline + (pin-over pct + (- cur-x (viewable-region-x vregion)) + 0 + (linestyle 'dot + (colorize (vline 1 + (frame-info-adjusted-height frameinfo)) + (timeline-tick-color))))) + (if (timeline-tick-show-label? tick) + (pin-over pinnedline + (- cur-x (viewable-region-x vregion)) + 3 + (timeline-tick-label-pict (timeline-tick-rel-time tick))) + pinnedline))) ;;draw-row-lines-on : pict viewable-region trace frameinfo -> pict (define (draw-row-lines-on base vregion tr finfo opacity) diff --git a/collects/tests/future/visualizer.rkt b/collects/tests/future/visualizer.rkt index f6962617a2..ebcc4b3f03 100644 --- a/collects/tests/future/visualizer.rkt +++ b/collects/tests/future/visualizer.rkt @@ -41,11 +41,11 @@ (check-true (in-viewable-region-horiz vr 222))) (let ([vr (viewable-region 0 0 732 685)] - [ticks (list (timeline-tick 222.0 #f 0.4999999999999982) - (timeline-tick 169.0 #f 0.3999999999999986) - (timeline-tick 116.0 #f 0.29999999999999893) - (timeline-tick 63.0 #f 0.1999999999999993) - (timeline-tick 10 #f 0.09999999999999964))]) + [ticks (list (timeline-tick 222.0 #f 0.4999999999999982 #f) + (timeline-tick 169.0 #f 0.3999999999999986 #f) + (timeline-tick 116.0 #f 0.29999999999999893 #f) + (timeline-tick 63.0 #f 0.1999999999999993 #f) + (timeline-tick 10 #f 0.09999999999999964 #f))]) (define in-vr (filter (λ (t) (in-viewable-region-horiz vr (timeline-tick-x t))) ticks)) @@ -250,14 +250,9 @@ (indexed-future-event 1 (future-event 0 0 'start-work 11.0 #f #f)) (indexed-future-event 2 (future-event 0 0 'end-work 20.0 #f #f)))]) (define-values (tr finfo segs ticks) (compile-trace-data l)) - ;Check that number of ticks stays constant whatever the time->pixel modifier - (check-equal? (length ticks) 100) - (check-equal? (length (calc-ticks segs 700 tr)) 100) - (for ([i (in-range 0.1 20)]) - (check-equal? (length (calc-ticks segs i tr)) - 100 - (format "Wrong number of ticks for time->pix mod ~a\n" i))) - (check-seg-layout tr segs ticks)) + ;Number of ticks can vary, but cannot exceed (total trace time / tick interval) + (check-true (<= (length ticks) 100)) + (check-equal? (length (calc-ticks segs 1000 tr)) 99)) (let ([l (list (indexed-future-event 0 '#s(future-event #f 0 create 1334778395768.733 #f 3)) (indexed-future-event 1 '#s(future-event 3 2 start-work 1334778395768.771 #f #f)) @@ -267,7 +262,7 @@ (define last-evt (indexed-future-event-fevent (list-ref l 3))) (define first-evt (indexed-future-event-fevent (list-ref l 0))) (define total-time (- (future-event-time last-evt) (future-event-time first-evt))) - (check-equal? (length ticks) (inexact->exact (floor (* 10 total-time))))) + (check-true (<= (length ticks) (inexact->exact (floor (* 10 total-time)))))) (define mand-first (list (indexed-future-event 0 '#s(future-event #f 0 create 1334779294212.415 #f 1)) From 53d0aa1fe426e5f1551d002af24a64f48f57c0ec Mon Sep 17 00:00:00 2001 From: James Swaine Date: Thu, 19 Jul 2012 16:00:10 -0500 Subject: [PATCH 607/746] Improvements to mouseover performance in future visualizer (cherry picked from commit b6c4bece11058864d776e50efabb49659d65a905) --- .../future-visualizer/private/pict-canvas.rkt | 8 +- .../private/visualizer-drawing.rkt | 92 +++++++++---------- 2 files changed, 48 insertions(+), 52 deletions(-) diff --git a/collects/future-visualizer/private/pict-canvas.rkt b/collects/future-visualizer/private/pict-canvas.rkt index ded6627c98..f45fd8b884 100644 --- a/collects/future-visualizer/private/pict-canvas.rkt +++ b/collects/future-visualizer/private/pict-canvas.rkt @@ -33,6 +33,7 @@ (define delaying-redraw #f) (define cached-bitmap #f) (define cached-base-pict #f) + (define repainting? #f) (define/private (get-viewable-region) (define-values (x y) (get-view-start)) @@ -80,7 +81,8 @@ (new timer% [notify-callback (λ () (set! delaying-redraw #f) (set! needs-redraw #t) - (redraw-the-bitmap/maybe-delayed! (get-viewable-region)) + (redraw-the-bitmap/maybe-delayed! (get-viewable-region) #:only-the-overlay? only-the-overlay?) + (set! repainting? #t) (refresh))] [interval 100] [just-once? #t]) @@ -95,7 +97,9 @@ (define/override (on-paint) (define vregion (get-viewable-region)) - (redraw-the-bitmap/maybe-delayed! vregion) + (unless repainting? + (redraw-the-bitmap/maybe-delayed! vregion)) + (set! repainting? #f) (define dc (get-dc)) (when cached-bitmap (send dc diff --git a/collects/future-visualizer/private/visualizer-drawing.rkt b/collects/future-visualizer/private/visualizer-drawing.rkt index 673f905848..7cec144d98 100644 --- a/collects/future-visualizer/private/visualizer-drawing.rkt +++ b/collects/future-visualizer/private/visualizer-drawing.rkt @@ -526,47 +526,6 @@ #:width width #:with-arrow with-arrow #:style style)))) - -;;draw-arrows : pict viewable-region segment -> pict -(define (draw-arrows base-pct vregion seg) - (let ([fst (get-seg-previous-to-vregion vregion seg)]) - (let loop ([pct base-pct] - [cur-seg fst]) - (if (not cur-seg) - pct - (let ([next (segment-next-future-seg cur-seg)]) - (let* ([next-targ (segment-next-targ-future-seg cur-seg)] - [prev-targ (segment-prev-targ-future-seg cur-seg)] - [ftl-arrows (if (not next) - pct - (draw-connection vregion - cur-seg - next - pct - (event-connection-line-color) - #:width 2))] - [prev-targ-arr (if (not prev-targ) - ftl-arrows - (draw-connection vregion - prev-targ - cur-seg - ftl-arrows - (event-target-future-line-color) - #:with-arrow #t - #:style 'dot))] - [next-targ-arr (if (not next-targ) - prev-targ-arr - (draw-connection vregion - cur-seg - next-targ - prev-targ-arr - (event-target-future-line-color) - #:with-arrow #t - #:style 'dot))]) - (if (and next - ((seg-in-vregion vregion) next)) - (loop next-targ-arr next) - next-targ-arr))))))) ;;timeline-pict : (listof indexed-future-event) [viewable-region] [integer] -> pict (define (timeline-pict logs @@ -617,6 +576,47 @@ overlay)] [else tp])) +;;draw-arrows : pict viewable-region segment -> pict +(define (draw-arrows base-pct vregion seg) + (let ([fst (get-seg-previous-to-vregion vregion seg)]) + (let loop ([pct base-pct] + [cur-seg fst]) + (if (not cur-seg) + pct + (let ([next (segment-next-future-seg cur-seg)]) + (let* ([next-targ (segment-next-targ-future-seg cur-seg)] + [prev-targ (segment-prev-targ-future-seg cur-seg)] + [ftl-arrows (if (not next) + pct + (draw-connection vregion + cur-seg + next + pct + (event-connection-line-color) + #:width 2))] + [prev-targ-arr (if (not prev-targ) + ftl-arrows + (draw-connection vregion + prev-targ + cur-seg + ftl-arrows + (event-target-future-line-color) + #:with-arrow #t + #:style 'dot))] + [next-targ-arr (if (not next-targ) + prev-targ-arr + (draw-connection vregion + cur-seg + next-targ + prev-targ-arr + (event-target-future-line-color) + #:with-arrow #t + #:style 'dot))]) + (if (and next + ((seg-in-vregion vregion) next)) + (loop next-targ-arr next) + next-targ-arr))))))) + ;Draws the pict that is layered on top of the exec. timeline canvas ;to highlight a specific future's event sequence ;;timeline-overlay : uint uint (or segment #f) (or segment #f) frame-info trace -> pict @@ -629,17 +629,9 @@ (if tacked (values tacked #t) (values hovered #f))) (if seg-with-arrows (let* ([bg base] - [dots (let loop ([p bg] [cur-seg (get-first-future-seg-in-region vregion seg-with-arrows)]) - (if (or (not cur-seg) (not ((seg-in-vregion vregion) cur-seg))) - p - (loop (pin-over p - (- (segment-x cur-seg) (viewable-region-x vregion)) - (- (segment-y cur-seg) (viewable-region-y vregion)) - (pict-for-segment cur-seg)) - (segment-next-future-seg cur-seg))))] [aseg-rel-x (- (segment-x seg-with-arrows) (viewable-region-x vregion))] [aseg-rel-y (- (segment-y seg-with-arrows) (viewable-region-y vregion))] - [line (pin-over dots + [line (pin-over bg (- (+ aseg-rel-x (/ (segment-width seg-with-arrows) 2)) 2) From a8a6875cd6beb135d22b969a20a0fbb24df8a5d0 Mon Sep 17 00:00:00 2001 From: James Swaine Date: Thu, 19 Jul 2012 16:13:00 -0500 Subject: [PATCH 608/746] Fix minor display issue in event details panel (future visualizer) (cherry picked from commit ee426f7ecb762c8ac519bb1c8290391c28955a1e) --- collects/future-visualizer/private/visualizer-gui.rkt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collects/future-visualizer/private/visualizer-gui.rkt b/collects/future-visualizer/private/visualizer-gui.rkt index 3244cb303d..5ac8f0039b 100644 --- a/collects/future-visualizer/private/visualizer-gui.rkt +++ b/collects/future-visualizer/private/visualizer-gui.rkt @@ -70,7 +70,8 @@ [(touch) (send data-label1 set-label (format "Touching future ~a" (event-user-data evt)))] [else - (send data-label1 set-label "")])) + (send data-label1 set-label "") + (send data-label2 set-label "")])) (begin (send selected-label set-label "") (send time-label set-label "") From ce41446bd40cc71f323274ff3028d793bae32dce Mon Sep 17 00:00:00 2001 From: James Swaine Date: Thu, 19 Jul 2012 17:05:04 -0500 Subject: [PATCH 609/746] Future visualizer - only redraw overlay when moused-over event changes (cherry picked from commit 0b8bccc8d4cbeba6e3b5a9a413cd066c27da33fb) --- collects/future-visualizer/private/pict-canvas.rkt | 2 +- .../future-visualizer/private/visualizer-gui.rkt | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/collects/future-visualizer/private/pict-canvas.rkt b/collects/future-visualizer/private/pict-canvas.rkt index f45fd8b884..f2115e5efd 100644 --- a/collects/future-visualizer/private/pict-canvas.rkt +++ b/collects/future-visualizer/private/pict-canvas.rkt @@ -83,7 +83,7 @@ (set! needs-redraw #t) (redraw-the-bitmap/maybe-delayed! (get-viewable-region) #:only-the-overlay? only-the-overlay?) (set! repainting? #t) - (refresh))] + (refresh))] [interval 100] [just-once? #t]) (set! delaying-redraw #t)])) diff --git a/collects/future-visualizer/private/visualizer-gui.rkt b/collects/future-visualizer/private/visualizer-gui.rkt index 5ac8f0039b..7c02681dde 100644 --- a/collects/future-visualizer/private/visualizer-gui.rkt +++ b/collects/future-visualizer/private/visualizer-gui.rkt @@ -71,7 +71,7 @@ (send data-label1 set-label (format "Touching future ~a" (event-user-data evt)))] [else (send data-label1 set-label "") - (send data-label2 set-label "")])) + (send data-label2 set-label "")])) (begin (send selected-label set-label "") (send time-label set-label "") @@ -152,9 +152,13 @@ [parent timeline-container] [pict-builder (λ (vregion) (timeline-pict-for-trace-data vregion the-trace frameinfo segments))] [hover-handler (λ (x y vregion) - (let ([seg (find-seg-for-coords x y timeline-mouse-index)]) - (set! hover-seg seg) - (post-event listener-table 'segment-hover timeline-panel seg)))] + (let ([seg (find-seg-for-coords x y timeline-mouse-index)]) + (cond + [(equal? seg hover-seg) #f] + [else + (set! hover-seg seg) + (post-event listener-table 'segment-hover timeline-panel seg) + #t])))] [click-handler (λ (x y vregion) (let ([seg (find-seg-for-coords x y timeline-mouse-index)]) (set! tacked-seg seg) From 59324a1b0c51798b6e2270b7dd1bbfa45faffd8d Mon Sep 17 00:00:00 2001 From: James Swaine Date: Thu, 19 Jul 2012 17:42:38 -0500 Subject: [PATCH 610/746] Fix future visualizer drawing outside visible area (in y dimension) (cherry picked from commit 5042b73fc89df2c66474a391efcc8443e5ae4524) --- .../future-visualizer/private/display.rkt | 7 +- .../future-visualizer/private/pict-canvas.rkt | 5 +- .../private/visualizer-drawing.rkt | 159 ++++++++++-------- .../private/visualizer-gui.rkt | 5 +- 4 files changed, 101 insertions(+), 75 deletions(-) diff --git a/collects/future-visualizer/private/display.rkt b/collects/future-visualizer/private/display.rkt index 21f75e6fea..4a33d9430b 100644 --- a/collects/future-visualizer/private/display.rkt +++ b/collects/future-visualizer/private/display.rkt @@ -26,7 +26,8 @@ viewable-region-x-extent viewable-region-y-extent in-viewable-region - in-viewable-region-horiz + in-viewable-region-horiz + in-viewable-region-vert? scale-viewable-region between) @@ -55,6 +56,10 @@ (define (in-viewable-region-horiz vregion x) (between x (viewable-region-x vregion) (viewable-region-x-extent vregion))) +;;in-viewable-region-vert : viewable-region uint -> bool +(define (in-viewable-region-vert? vregion y) + (between y (viewable-region-y vregion) (viewable-region-y-extent vregion))) + ;;in-viewable-region : viewable-region segment -> bool (define (in-viewable-region vregion x y w h) (define-values (start-x start-y end-x end-y) diff --git a/collects/future-visualizer/private/pict-canvas.rkt b/collects/future-visualizer/private/pict-canvas.rkt index f2115e5efd..31b9fabac5 100644 --- a/collects/future-visualizer/private/pict-canvas.rkt +++ b/collects/future-visualizer/private/pict-canvas.rkt @@ -116,7 +116,10 @@ [(motion) (when mh (when (mh x y vregion) ;Mouse handler returns non-false if a state change requiring redraw occurred - (redraw-the-bitmap/maybe-delayed! vregion #:only-the-overlay? #t)))] + #;(redraw-the-bitmap/maybe-delayed! vregion #:only-the-overlay? #t) + (set! repainting? #f) + (redraw-the-bitmap! vregion #:only-the-overlay? #t) + (refresh)))] [(left-up) (when ch (ch x y vregion)) ;Ditto for click handler (redraw-the-bitmap/maybe-delayed! vregion #:only-the-overlay? #t)])) diff --git a/collects/future-visualizer/private/visualizer-drawing.rkt b/collects/future-visualizer/private/visualizer-drawing.rkt index 7cec144d98..ee631cb87e 100644 --- a/collects/future-visualizer/private/visualizer-drawing.rkt +++ b/collects/future-visualizer/private/visualizer-drawing.rkt @@ -199,8 +199,7 @@ [last-label-x-extent 0] [remain-segs segs]) ([i (in-range 0 (floor (/ (- (trace-end-time tr) trace-start) - DEFAULT-TIME-INTERVAL)))]) - #;(define tick-time (+ last-time DEFAULT-TIME-INTERVAL)) + DEFAULT-TIME-INTERVAL)))]) (define tick-rel-time (* (add1 i) DEFAULT-TIME-INTERVAL)) (define tick-time (+ trace-start tick-rel-time)) (define want-x (+ last-x (* DEFAULT-TIME-INTERVAL timeToPixMod))) @@ -270,19 +269,11 @@ ;; get-seg-previous-to-vregion : viewable-region segment -> segment (define (get-seg-previous-to-vregion vregion seg) - (define first-seg - (let loop ([cur seg]) - (define prev (segment-prev-future-seg cur)) - (if (not prev) - cur - (loop prev)))) - (let loop ([cur first-seg]) - (define next (segment-next-future-seg cur)) - (if (or (not next) - (> (segment-x next) (viewable-region-x vregion))) - cur - (loop next)))) - + (let loop ([cur seg]) + (define prev (segment-prev-future-seg cur)) + (cond + [(or (not prev) (not ((seg-in-vregion vregion) cur))) cur] + [else (loop prev)]))) ;;adjust-work-segs! : (listof segment) -> void (define (adjust-work-segs! segs) @@ -399,7 +390,7 @@ 0 (linestyle 'dot (colorize (vline 1 - (frame-info-adjusted-height frameinfo)) + (viewable-region-height vregion)) (timeline-tick-color))))) (if (timeline-tick-show-label? tick) (pin-over pinnedline @@ -413,8 +404,14 @@ (pin-over base 0 0 - (for/fold ([pct base]) ([tl (in-list (trace-proc-timelines tr))] - [i (in-naturals)]) + (for/fold ([pct base]) ([tl (in-list (filter (λ (tline) + (define midy (calc-row-mid-y (process-timeline-proc-index tline) + (frame-info-row-height finfo))) + (define topy (- midy (frame-info-row-height finfo))) + (define boty (+ midy (frame-info-row-height finfo))) + (or (in-viewable-region-vert? vregion topy) + (in-viewable-region-vert? vregion boty))) + (trace-proc-timelines tr)))]) (let* ([line-coords (list-ref (frame-info-process-line-coords finfo) (process-timeline-proc-index tl))] [line-start (car line-coords)] @@ -431,7 +428,8 @@ [(between line-end vregion-start vregion-end) (- line-end vregion-start)] [else vregion-end])] - [proc-name (if (zero? i) + [index (process-timeline-proc-index tl)] + [proc-name (if (zero? index) "Thread 0 (Runtime Thread)" (format "Thread ~a" (process-timeline-proc-id tl)))] [proc-title (text-block-pict proc-name @@ -442,15 +440,15 @@ #:width (viewable-region-width vregion))]) (draw-stack-onto pct (at 0 - (- (* (add1 i) (frame-info-row-height finfo)) (viewable-region-y vregion)) + (- (* (add1 index) (frame-info-row-height finfo)) (viewable-region-y vregion)) (colorize (hline (viewable-region-width vregion) 1) (timeline-baseline-color))) (at 0 - (+ (+ (- (* i (frame-info-row-height finfo)) (viewable-region-y vregion)) + (+ (+ (- (* index (frame-info-row-height finfo)) (viewable-region-y vregion)) (- (frame-info-row-height finfo) (pict-height proc-title))) 1) proc-title) (at start-x - (- (calc-row-mid-y (process-timeline-proc-index tl) (frame-info-row-height finfo)) + (- (calc-row-mid-y index (frame-info-row-height finfo)) (viewable-region-y vregion)) (colorize (hline (- end-x start-x) 1) (timeline-event-baseline-color)))))))) @@ -478,55 +476,6 @@ (let ([with-ruler (draw-ruler-on base vregion finfo)]) (draw-row-lines-on with-ruler vregion tr finfo opacity))) -;;draw-connection : viewable-region segment segment pict string [uint bool symbol] -> pict -(define (draw-connection vregion - start - end - base-pct - color - #:width [width 1] - #:with-arrow [with-arrow #f] - #:style [style 'solid]) - (let*-values ([(midx midy) (calc-center (- (segment-x start) (viewable-region-x vregion)) - (- (segment-y start) (viewable-region-y vregion)) - MIN-SEG-WIDTH)] - [(nextx nexty) (calc-center (- (segment-x end) (viewable-region-x vregion)) - (- (segment-y end) (viewable-region-y vregion)) - MIN-SEG-WIDTH)] - [(dx dy) (values (- nextx midx) (- nexty midy))]) - (if (and (zero? dy) - (or (not (eq? (segment-next-proc-seg start) end)) - (< dx CONNECTION-LINE-HAT-THRESHOLD))) - (let* ([dxa (/ dx 2)] - [dya (- HAT-HEIGHT CONNECTION-LINE-HAT-THRESHOLD)] - [breakx (+ midx dxa)] - [breaky (+ midy dya)]) - (draw-line-onto (draw-line-onto base-pct - midx - midy - breakx - breaky - color - #:width width - #:style style) - breakx - breaky - nextx - nexty - color - #:width width - #:with-arrow with-arrow - #:style style)) - (draw-line-onto base-pct - midx - midy - nextx - nexty - color - #:width width - #:with-arrow with-arrow - #:style style)))) - ;;timeline-pict : (listof indexed-future-event) [viewable-region] [integer] -> pict (define (timeline-pict logs #:x [x #f] @@ -576,8 +525,74 @@ overlay)] [else tp])) -;;draw-arrows : pict viewable-region segment -> pict +;;draw-connection : viewable-region segment segment pict string [uint bool symbol] -> pict +(define (draw-connection vregion + start + end + base-pct + color + #:width [width 1] + #:with-arrow [with-arrow #f] + #:style [style 'solid]) + (let*-values ([(midx midy) (calc-center (- (segment-x start) (viewable-region-x vregion)) + (- (segment-y start) (viewable-region-y vregion)) + MIN-SEG-WIDTH)] + [(nextx nexty) (calc-center (- (segment-x end) (viewable-region-x vregion)) + (- (segment-y end) (viewable-region-y vregion)) + MIN-SEG-WIDTH)] + [(dx dy) (values (- nextx midx) (- nexty midy))]) + (if (and (zero? dy) + (or (not (eq? (segment-next-proc-seg start) end)) + (< dx CONNECTION-LINE-HAT-THRESHOLD))) + (let* ([dxa (/ dx 2)] + [dya (- HAT-HEIGHT CONNECTION-LINE-HAT-THRESHOLD)] + [breakx (+ midx dxa)] + [breaky (+ midy dya)]) + (draw-line-onto (draw-line-onto base-pct + midx + midy + breakx + breaky + color + #:width width + #:style style) + breakx + breaky + nextx + nexty + color + #:width width + #:with-arrow with-arrow + #:style style)) + (draw-line-onto base-pct + midx + midy + nextx + nexty + color + #:width width + #:with-arrow with-arrow + #:style style)))) + (define (draw-arrows base-pct vregion seg) + (define fst (get-seg-previous-to-vregion vregion seg)) + (let loop ([p base-pct] + [cur-seg fst]) + (define next-seg (segment-next-future-seg cur-seg)) + (cond + [(not next-seg) p] + [else + (define new-p (draw-connection vregion + cur-seg + next-seg + p + (event-connection-line-color) + #:width 2)) + (loop new-p next-seg)]))) + + +;;draw-arrows : pict viewable-region segment -> pict +#;(define (draw-arrows base-pct vregion seg) (let ([fst (get-seg-previous-to-vregion vregion seg)]) (let loop ([pct base-pct] [cur-seg fst]) diff --git a/collects/future-visualizer/private/visualizer-gui.rkt b/collects/future-visualizer/private/visualizer-gui.rkt index 7c02681dde..c30b2de81d 100644 --- a/collects/future-visualizer/private/visualizer-gui.rkt +++ b/collects/future-visualizer/private/visualizer-gui.rkt @@ -133,7 +133,8 @@ [stretchable-width #t])) (define graphic-panel (new panel:horizontal-dragable% [parent right-panel] - [stretchable-height #t])) + [stretchable-height #t] + [stretchable-width #t])) (define timeline-container (new vertical-panel% [parent graphic-panel] [stretchable-width #t] @@ -353,5 +354,7 @@ (send graphic-panel add-child graph-container) (send item set-label "Hide Creation Tree"))) (set! showing-create-graph (not showing-create-graph)))]) + + (send main-panel set-percentages '(1/5 4/5)) (send f show #t)) From f458b167f0559eabf75cb68058247da71f78820e Mon Sep 17 00:00:00 2001 From: James Swaine Date: Sun, 22 Jul 2012 00:53:27 -0500 Subject: [PATCH 611/746] Future visualizer performance improvements (cherry picked from commit 0b5d574aae05de4643864f05574307b07b0c756e) --- .../future-visualizer/private/pict-canvas.rkt | 59 +++++++++---------- .../private/visualizer-drawing.rkt | 27 ++++++++- .../private/visualizer-gui.rkt | 3 +- 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/collects/future-visualizer/private/pict-canvas.rkt b/collects/future-visualizer/private/pict-canvas.rkt index 31b9fabac5..7d27710413 100644 --- a/collects/future-visualizer/private/pict-canvas.rkt +++ b/collects/future-visualizer/private/pict-canvas.rkt @@ -29,9 +29,10 @@ (define/public (set-scale-factor! s) (set! scale-factor s)) - (define needs-redraw #f) + (define need-redraw? #f) (define delaying-redraw #f) (define cached-bitmap #f) + (define cached-overlay-bitmap #f) (define cached-base-pict #f) (define repainting? #f) @@ -46,45 +47,36 @@ ;Rebuild both the bottom (base) and overlay (top) ;pict layers for the canvas ;;rebuild-the-pict : viewable-region -> void - (define/private (rebuild-the-pict vregion #:only-the-overlay? [only-the-overlay? #f]) - (define p (cond - [(or (not cached-base-pict) (not only-the-overlay?)) - (define base (scale (bp vregion) scale-factor)) - (set! cached-base-pict base) - (if ob - (pin-over base - 0 - 0 - (ob vregion scale-factor)) - base)] - [else (if ob - (pin-over cached-base-pict - 0 - 0 - (ob vregion scale-factor)) - cached-base-pict)])) - (pict->bitmap p)) + (define/private (rebuild-the-pict! vregion #:only-the-overlay? [only-the-overlay? #f]) + (when (or (not cached-base-pict) (not only-the-overlay?)) + (define base (scale (bp vregion) scale-factor)) + ;(set! cached-base-pict base) + (set! cached-bitmap (pict->bitmap base))) + (when ob + (set! cached-overlay-bitmap (pict->bitmap (ob vregion scale-factor))))) ;Rebuilds the pict and stashes in a bitmap ;to be drawn to the canvas later ;;redraw-the-bitmap : viewable-region -> void (define/private (redraw-the-bitmap! vregion #:only-the-overlay? [only-the-overlay? #f]) - (set! cached-bitmap (rebuild-the-pict vregion #:only-the-overlay? only-the-overlay?)) - (set! needs-redraw #f)) + (rebuild-the-pict! vregion #:only-the-overlay? only-the-overlay?) + (set! need-redraw? #f)) ;;redraw-the-bitmap/maybe-delayed! : viewable-region -> void (define/private (redraw-the-bitmap/maybe-delayed! vregion + #:delay [delay 100] #:only-the-overlay? [only-the-overlay? #f]) (cond - [needs-redraw (redraw-the-bitmap! vregion #:only-the-overlay? only-the-overlay?)] + [need-redraw? + (redraw-the-bitmap! vregion #:only-the-overlay? only-the-overlay?) + (set! need-redraw? #f)] [(not delaying-redraw) (new timer% [notify-callback (λ () (set! delaying-redraw #f) - (set! needs-redraw #t) + (set! need-redraw? #t) (redraw-the-bitmap/maybe-delayed! (get-viewable-region) #:only-the-overlay? only-the-overlay?) - (set! repainting? #t) (refresh))] - [interval 100] + [interval delay] [just-once? #t]) (set! delaying-redraw #t)])) @@ -95,17 +87,25 @@ (when redraw-on-size (redraw-the-bitmap/maybe-delayed! (get-viewable-region)))) + (define last-vregion #f) + (define/override (on-paint) (define vregion (get-viewable-region)) - (unless repainting? + (when (and (not delaying-redraw) (not (equal? vregion last-vregion))) (redraw-the-bitmap/maybe-delayed! vregion)) - (set! repainting? #f) + (set! last-vregion vregion) (define dc (get-dc)) (when cached-bitmap (send dc draw-bitmap cached-bitmap (viewable-region-x vregion) + (viewable-region-y vregion))) + (when cached-overlay-bitmap + (send dc + draw-bitmap + cached-overlay-bitmap + (viewable-region-x vregion) (viewable-region-y vregion)))) (define/override (on-event event) @@ -116,10 +116,7 @@ [(motion) (when mh (when (mh x y vregion) ;Mouse handler returns non-false if a state change requiring redraw occurred - #;(redraw-the-bitmap/maybe-delayed! vregion #:only-the-overlay? #t) - (set! repainting? #f) - (redraw-the-bitmap! vregion #:only-the-overlay? #t) - (refresh)))] + (redraw-the-bitmap/maybe-delayed! vregion #:delay 0 #:only-the-overlay? #t)))] [(left-up) (when ch (ch x y vregion)) ;Ditto for click handler (redraw-the-bitmap/maybe-delayed! vregion #:only-the-overlay? #t)])) diff --git a/collects/future-visualizer/private/visualizer-drawing.rkt b/collects/future-visualizer/private/visualizer-drawing.rkt index ee631cb87e..824cd2cb6a 100644 --- a/collects/future-visualizer/private/visualizer-drawing.rkt +++ b/collects/future-visualizer/private/visualizer-drawing.rkt @@ -437,8 +437,20 @@ #:forecolor (header-forecolor) #:padding HEADER-PADDING #:opacity opacity - #:width (viewable-region-width vregion))]) + #:width (viewable-region-width vregion))] + [row-mid (- (- (* index (frame-info-row-height finfo)) + (pict-height proc-title)) + (viewable-region-y vregion))]) (draw-stack-onto pct + (at 0 + (- (* (add1 index) (frame-info-row-height finfo)) (frame-info-row-height finfo)) + (colorize (filled-rectangle (viewable-region-width vregion) (/ (frame-info-row-height finfo) 2)) + (make-object color% 212 210 214 0.3))) + + (at 0 + row-mid + (colorize (filled-rectangle (viewable-region-width vregion) (/ (frame-info-row-height finfo) 2)) + (make-object color% 230 229 231 0.3))) (at 0 (- (* (add1 index) (frame-info-row-height finfo)) (viewable-region-y vregion)) (colorize (hline (viewable-region-width vregion) 1) (timeline-baseline-color))) @@ -574,8 +586,15 @@ #:with-arrow with-arrow #:style style)))) +(define (get-seg-left-of-vregion vregion seg) + (define prev-in-time (segment-prev-future-seg seg)) + (cond + [(or (not prev-in-time) (not (in-viewable-region-horiz vregion (segment-edge seg)))) + seg] + [else (get-seg-left-of-vregion vregion prev-in-time)])) + (define (draw-arrows base-pct vregion seg) - (define fst (get-seg-previous-to-vregion vregion seg)) + (define fst (get-seg-left-of-vregion vregion seg)) (let loop ([p base-pct] [cur-seg fst]) (define next-seg (segment-next-future-seg cur-seg)) @@ -588,7 +607,9 @@ p (event-connection-line-color) #:width 2)) - (loop new-p next-seg)]))) + (if (not (in-viewable-region-horiz vregion (segment-x next-seg))) + new-p + (loop new-p next-seg))]))) ;;draw-arrows : pict viewable-region segment -> pict diff --git a/collects/future-visualizer/private/visualizer-gui.rkt b/collects/future-visualizer/private/visualizer-gui.rkt index c30b2de81d..a5642883b4 100644 --- a/collects/future-visualizer/private/visualizer-gui.rkt +++ b/collects/future-visualizer/private/visualizer-gui.rkt @@ -159,7 +159,7 @@ [else (set! hover-seg seg) (post-event listener-table 'segment-hover timeline-panel seg) - #t])))] + seg])))] [click-handler (λ (x y vregion) (let ([seg (find-seg-for-coords x y timeline-mouse-index)]) (set! tacked-seg seg) @@ -356,5 +356,6 @@ (set! showing-create-graph (not showing-create-graph)))]) (send main-panel set-percentages '(1/5 4/5)) + (send right-panel set-percentages '(3/4 1/4)) (send f show #t)) From 32fe5e272264f699ed9f23522fc34591fbc2aa64 Mon Sep 17 00:00:00 2001 From: James Swaine Date: Sun, 22 Jul 2012 01:05:09 -0500 Subject: [PATCH 612/746] Future visualizer - more performance improvement (cherry picked from commit 1355c711a87ad9f12ef16c0232e9736cceaa6492) --- .../future-visualizer/private/pict-canvas.rkt | 43 ++++++------------- .../private/visualizer-drawing.rkt | 26 +++-------- 2 files changed, 21 insertions(+), 48 deletions(-) diff --git a/collects/future-visualizer/private/pict-canvas.rkt b/collects/future-visualizer/private/pict-canvas.rkt index 7d27710413..a26480dffc 100644 --- a/collects/future-visualizer/private/pict-canvas.rkt +++ b/collects/future-visualizer/private/pict-canvas.rkt @@ -17,24 +17,15 @@ (define ob overlay-builder) ;Hover overlay pict builder (define ch click-handler) ;Mouse click handler (define redraw-on-size redraw-on-resize) ;Whether we should rebuild the pict for on-size events - - (define redraw-overlay #f) ;Whether we should redraw the overlay pict in the canvas - (define redo-bitmap-on-paint #t) ;Redraw the base bitmap on paint? #f for mouse events (define scale-factor 1) - ;;set-redraw-overlay! : bool -> void - (define/public (set-redraw-overlay! b) - (set! redraw-overlay b)) - (define/public (set-scale-factor! s) (set! scale-factor s)) (define need-redraw? #f) - (define delaying-redraw #f) - (define cached-bitmap #f) + (define delaying-redraw? #f) + (define cached-base-bitmap #f) (define cached-overlay-bitmap #f) - (define cached-base-pict #f) - (define repainting? #f) (define/private (get-viewable-region) (define-values (x y) (get-view-start)) @@ -48,10 +39,8 @@ ;pict layers for the canvas ;;rebuild-the-pict : viewable-region -> void (define/private (rebuild-the-pict! vregion #:only-the-overlay? [only-the-overlay? #f]) - (when (or (not cached-base-pict) (not only-the-overlay?)) - (define base (scale (bp vregion) scale-factor)) - ;(set! cached-base-pict base) - (set! cached-bitmap (pict->bitmap base))) + (when (or (not cached-base-bitmap) (not only-the-overlay?)) + (set! cached-base-bitmap (pict->bitmap (scale (bp vregion) scale-factor)))) (when ob (set! cached-overlay-bitmap (pict->bitmap (ob vregion scale-factor))))) @@ -70,35 +59,31 @@ [need-redraw? (redraw-the-bitmap! vregion #:only-the-overlay? only-the-overlay?) (set! need-redraw? #f)] - [(not delaying-redraw) + [(not delaying-redraw?) (new timer% [notify-callback (λ () - (set! delaying-redraw #f) + (set! delaying-redraw? #f) (set! need-redraw? #t) (redraw-the-bitmap/maybe-delayed! (get-viewable-region) #:only-the-overlay? only-the-overlay?) (refresh))] [interval delay] [just-once? #t]) - (set! delaying-redraw #t)])) - - ;If we haven't already introduced a 100ms delay, - ;add one. If the delay's expired, rebuild the pict - ;;on-size : uint uint -> void - (define/override (on-size width height) - (when redraw-on-size - (redraw-the-bitmap/maybe-delayed! (get-viewable-region)))) + (set! delaying-redraw? #t)])) (define last-vregion #f) + (define (scroll-or-size-event? vregion) + (not (equal? vregion last-vregion))) + (define/override (on-paint) (define vregion (get-viewable-region)) - (when (and (not delaying-redraw) (not (equal? vregion last-vregion))) + (when (and (not delaying-redraw?) (scroll-or-size-event? vregion)) (redraw-the-bitmap/maybe-delayed! vregion)) (set! last-vregion vregion) (define dc (get-dc)) - (when cached-bitmap + (when cached-base-bitmap (send dc draw-bitmap - cached-bitmap + cached-base-bitmap (viewable-region-x vregion) (viewable-region-y vregion))) (when cached-overlay-bitmap @@ -115,7 +100,7 @@ (case (send event get-event-type) [(motion) (when mh - (when (mh x y vregion) ;Mouse handler returns non-false if a state change requiring redraw occurred + (when (mh x y vregion) ;Mouse handler returns non-false if a state change requiring redraw occurred (redraw-the-bitmap/maybe-delayed! vregion #:delay 0 #:only-the-overlay? #t)))] [(left-up) (when ch (ch x y vregion)) ;Ditto for click handler diff --git a/collects/future-visualizer/private/visualizer-drawing.rkt b/collects/future-visualizer/private/visualizer-drawing.rkt index 824cd2cb6a..fbcefb8b6c 100644 --- a/collects/future-visualizer/private/visualizer-drawing.rkt +++ b/collects/future-visualizer/private/visualizer-drawing.rkt @@ -437,20 +437,8 @@ #:forecolor (header-forecolor) #:padding HEADER-PADDING #:opacity opacity - #:width (viewable-region-width vregion))] - [row-mid (- (- (* index (frame-info-row-height finfo)) - (pict-height proc-title)) - (viewable-region-y vregion))]) + #:width (viewable-region-width vregion))]) (draw-stack-onto pct - (at 0 - (- (* (add1 index) (frame-info-row-height finfo)) (frame-info-row-height finfo)) - (colorize (filled-rectangle (viewable-region-width vregion) (/ (frame-info-row-height finfo) 2)) - (make-object color% 212 210 214 0.3))) - - (at 0 - row-mid - (colorize (filled-rectangle (viewable-region-width vregion) (/ (frame-info-row-height finfo) 2)) - (make-object color% 230 229 231 0.3))) (at 0 (- (* (add1 index) (frame-info-row-height finfo)) (viewable-region-y vregion)) (colorize (hline (viewable-region-width vregion) 1) (timeline-baseline-color))) @@ -586,14 +574,14 @@ #:with-arrow with-arrow #:style style)))) -(define (get-seg-left-of-vregion vregion seg) +#;(define (get-seg-left-of-vregion vregion seg) (define prev-in-time (segment-prev-future-seg seg)) (cond - [(or (not prev-in-time) (not (in-viewable-region-horiz vregion (segment-edge seg)))) - seg] + [(not prev-in-time) seg] + [((segment-edge prev-in-time) . < . (viewable-region-x vregion)) prev-in-time] [else (get-seg-left-of-vregion vregion prev-in-time)])) -(define (draw-arrows base-pct vregion seg) +#;(define (draw-arrows base-pct vregion seg) (define fst (get-seg-left-of-vregion vregion seg)) (let loop ([p base-pct] [cur-seg fst]) @@ -606,14 +594,14 @@ next-seg p (event-connection-line-color) - #:width 2)) + #:width 1)) (if (not (in-viewable-region-horiz vregion (segment-x next-seg))) new-p (loop new-p next-seg))]))) ;;draw-arrows : pict viewable-region segment -> pict -#;(define (draw-arrows base-pct vregion seg) +(define (draw-arrows base-pct vregion seg) (let ([fst (get-seg-previous-to-vregion vregion seg)]) (let loop ([pct base-pct] [cur-seg fst]) From fc9f3bb2ab45677a715cdf6a54062b19b979e693 Mon Sep 17 00:00:00 2001 From: James Swaine Date: Sun, 22 Jul 2012 19:52:13 -0500 Subject: [PATCH 613/746] Fix block/sync counts in future visualizer and per-future block counts in creation graph mouseover (cherry picked from commit 087ec3890c4fe1701839e2120aa5fba7ca4eb69e) --- .../future-visualizer/private/pict-canvas.rkt | 6 ++- .../private/visualizer-data.rkt | 42 +++++++++---------- .../private/visualizer-drawing.rkt | 17 +++++--- .../private/visualizer-gui.rkt | 34 ++++++++------- 4 files changed, 56 insertions(+), 43 deletions(-) diff --git a/collects/future-visualizer/private/pict-canvas.rkt b/collects/future-visualizer/private/pict-canvas.rkt index a26480dffc..21bf71b8dd 100644 --- a/collects/future-visualizer/private/pict-canvas.rkt +++ b/collects/future-visualizer/private/pict-canvas.rkt @@ -42,7 +42,11 @@ (when (or (not cached-base-bitmap) (not only-the-overlay?)) (set! cached-base-bitmap (pict->bitmap (scale (bp vregion) scale-factor)))) (when ob - (set! cached-overlay-bitmap (pict->bitmap (ob vregion scale-factor))))) + (define overlay-pict (ob vregion scale-factor)) + (set! cached-overlay-bitmap + (if overlay-pict + (pict->bitmap overlay-pict) + #f)))) ;Rebuilds the pict and stashes in a bitmap ;to be drawn to the canvas later diff --git a/collects/future-visualizer/private/visualizer-data.rkt b/collects/future-visualizer/private/visualizer-data.rkt index 9a2bec9ccd..1b1faf3b25 100644 --- a/collects/future-visualizer/private/visualizer-data.rkt +++ b/collects/future-visualizer/private/visualizer-data.rkt @@ -148,10 +148,22 @@ [(block sync) #t] [else #f])) +;;runtime-thread-evt? : (or event indexed-future-event future-event) -> bool +(define (runtime-thread-evt? evt) + (= (process-id evt) RT-THREAD-ID)) + ;;runtime-synchronization-event? : (or event indexed-future-event future-event) -> bool (define (runtime-synchronization-event? evt) (and (synchronization-event? evt) (= (process-id evt) RT-THREAD-ID))) +;;runtime-block-evt? : (or event indexed-future-event future-event) -> bool +(define (runtime-block-evt? evt) + (and (runtime-thread-evt? evt) (equal? (what evt) 'block))) + +;;runtime-sync-evt? : (or event indexed-future-event future-event) -> bool +(define (runtime-sync-evt? evt) + (and (runtime-thread-evt? evt) (equal? (what evt) 'sync))) + ;;final-event? : event -> bool (define (final-event? evt) (case (event-timeline-position evt) @@ -311,18 +323,13 @@ (define block-hash (make-hash)) (define sync-hash (make-hash)) (define rt-hash (make-hash)) - (for ([evt (in-list (filter (λ (e) (and (= (event-proc-id e) RT-THREAD-ID) - (or (equal? (event-type e) 'block) - (equal? (event-type e) 'sync)))) - evts))]) - (define isblock (case (event-type evt) - [(block) #t] - [else #f])) + (for ([evt (in-list (filter runtime-synchronization-event? evts))]) + (define isblock (runtime-block-evt? evt)) (define ophash (if isblock block-hash sync-hash)) (hash-update! ophash (event-prim-name evt) - (λ (old) (add1 old)) - 1) + (λ (old) (+ old 1)) + 0) (hash-update! rt-hash (event-future-id evt) (λ (old) @@ -331,19 +338,10 @@ (rtcall-info-sync-hash old))]) (hash-update! h (event-prim-name evt) - (λ (o) (add1 o)) - (λ () 1))) - old) - (λ () - (let* ([ri (rtcall-info (event-future-id evt) (make-hash) (make-hash))] - [h (if isblock - (rtcall-info-block-hash ri) - (rtcall-info-sync-hash ri))]) - (hash-update! h - (event-prim-name evt) - (λ (o) (add1 o)) - (λ () 1)) - ri)))) + (λ (o) (+ o 1)) + 0)) + old) + (rtcall-info (event-future-id evt) (make-hash) (make-hash)))) (values block-hash sync-hash rt-hash)) ;;connect-event-chains! : trace -> void diff --git a/collects/future-visualizer/private/visualizer-drawing.rkt b/collects/future-visualizer/private/visualizer-drawing.rkt index fbcefb8b6c..a285a33cf0 100644 --- a/collects/future-visualizer/private/visualizer-drawing.rkt +++ b/collects/future-visualizer/private/visualizer-drawing.rkt @@ -777,11 +777,16 @@ ;;graph-overlay-pict : drawable-node trace graph-layout -> pict (define (graph-overlay-pict hover-node tr layout vregion scale-factor) - (when hover-node - (unless (equal? (node-data (drawable-node-node hover-node)) 'runtime-thread) - (define fid (event-user-data (node-data (drawable-node-node hover-node)))) - (define ri (hash-ref (trace-future-rtcalls tr) fid (λ () #f))) - (when ri + (define (root-sym-or-first-evt n) (node-data (drawable-node-node n))) + (cond + [(or (not hover-node) (equal? (root-sym-or-first-evt hover-node) 'runtime-thread)) + #f] + [else + (define fid (event-user-data (root-sym-or-first-evt hover-node))) + (define ri (hash-ref (trace-future-rtcalls tr) fid #f)) + (cond + [(not ri) #f] + [else (define block-ops (sort (hash-keys (rtcall-info-block-hash ri)) > #:key (λ (p) @@ -831,5 +836,5 @@ TOOLTIP-MARGIN txtp)) (+ yacc (pict-height txtbg) CREATE-GRAPH-PADDING)))) - pct)))) + pct])])) \ No newline at end of file diff --git a/collects/future-visualizer/private/visualizer-gui.rkt b/collects/future-visualizer/private/visualizer-gui.rkt index a5642883b4..9ece04be8c 100644 --- a/collects/future-visualizer/private/visualizer-gui.rkt +++ b/collects/future-visualizer/private/visualizer-gui.rkt @@ -106,14 +106,12 @@ [parent (send f get-area-container)])) (define left-panel (new panel:horizontal-dragable% [parent main-panel] - [stretchable-width #t] - [min-width 0])) + [stretchable-width #t])) (define hlist-ctl (new hierarchical-list% [parent left-panel] [stretchable-width #t] [stretchable-height #t] - [style '(control-border)] - [min-width 0])) + [style '(control-border)])) ;Build up items in the hierlist (define block-node (send hlist-ctl new-list)) @@ -193,22 +191,30 @@ [pict-builder (λ (vregion) (draw-creategraph-pict vregion creation-tree-layout))] - #;[hover-handler #f (λ (x y vregion) + [hover-handler (λ (x y vregion) + (define hovered (find-node-for-coords x y + (graph-layout-nodes creation-tree-layout))) + (cond + [(eq? hovered hovered-graph-node) #f] + [else (set! hovered-graph-node (find-node-for-coords x y - (graph-layout-nodes creation-tree-layout))))] - [click-handler (λ (x y vregion) + (graph-layout-nodes creation-tree-layout))) + hovered-graph-node]))] + #;[click-handler (λ (x y vregion) (define fid (find-fid-for-coords x y (graph-layout-nodes creation-tree-layout) vregion)) - (when fid - (define seg (first-seg-for-fid fid segments)) - (set! tacked-seg seg) - (send timeline-panel set-redraw-overlay! #t) - (send timeline-panel refresh) - (post-event listener-table 'segment-click timeline-panel seg)))] - #;[overlay-builder (λ (vregion scale-factor) + (cond + [(not fid) #f] + [else + (define seg (first-seg-for-fid fid segments)) + (set! tacked-seg seg) + (send timeline-panel redraw-everything) + (post-event listener-table 'segment-click timeline-panel seg) + #t]))] + [overlay-builder (λ (vregion scale-factor) (graph-overlay-pict hovered-graph-node the-trace creation-tree-layout From b87b33da756e8aa73e05ebe2a16318b21429e01f Mon Sep 17 00:00:00 2001 From: James Swaine Date: Sun, 22 Jul 2012 20:08:51 -0500 Subject: [PATCH 614/746] Add test to track performance of code inside a future over time (cherry picked from commit ca360cdaedc6d87a069d6cc41756622d941c29e6) --- collects/tests/future/timing-test.rkt | 120 ++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 collects/tests/future/timing-test.rkt diff --git a/collects/tests/future/timing-test.rkt b/collects/tests/future/timing-test.rkt new file mode 100644 index 0000000000..3300555f1c --- /dev/null +++ b/collects/tests/future/timing-test.rkt @@ -0,0 +1,120 @@ +#lang typed/racket/base +(require (only-in racket/math pi) + (only-in racket/future future touch) + racket/fixnum racket/flonum) + +(: decimate-in-time + (FlVector FlVector + FlVector FlVector + Integer Integer + -> Void)) +(define (decimate-in-time as-r as-i + xs-r xs-i + n/2 start) + (for ([i (in-range n/2)]) + (define si (+ start i)) + (define si2 (+ si i)) + (define si21 (+ si2 1)) + (define sin2 (+ si n/2)) + (flvector-set! + xs-r si (flvector-ref as-r si2)) + (flvector-set! + xs-i si (flvector-ref as-i si2)) + (flvector-set! + xs-r sin2 (flvector-ref as-r si21)) + (flvector-set! + xs-i sin2 (flvector-ref as-i si21)))) + +(: twiddle-factor + (FlVector FlVector + Integer Integer -> Void)) +(define (twiddle-factor cs-r cs-i + n/2 start) + (define c (/ (* pi 0.0+1.0i) (->fl n/2))) + (for ([k (in-range n/2)]) + (define k-start (+ k start)) + (define res + (* (make-rectangular + (flvector-ref cs-r k-start) + (flvector-ref cs-i k-start)) + (exp (* c (->fl k))))) + (flvector-set! cs-r k-start + (real-part res)) + (flvector-set! cs-i k-start + (imag-part res)))) + +(: fft/depth + (FlVector FlVector FlVector FlVector + Integer Integer Integer + -> Void)) +(define (fft/depth as-r as-i xs-r xs-i + n start d) + (unless (= n 1) + (define n/2 (quotient n 2)) + (decimate-in-time as-r as-i xs-r + xs-i n/2 start) + (cond + [(= d 0) + (fft/depth xs-r xs-i as-r as-i + n/2 start 0) + (fft/depth xs-r xs-i as-r as-i + n/2 (+ start n/2) 0) + (twiddle-factor xs-r xs-i n/2 + (+ start n/2))] + [else + (define bs + (future + (λ () + (fft/depth xs-r xs-i as-r + as-i n/2 start + (- d 1))))) + (define cs + (future + (λ () + (fft/depth xs-r xs-i as-r + as-i n/2 + (+ start n/2) (- d 1)) + (twiddle-factor xs-r xs-i n/2 + (+ start n/2))))) + (touch bs) + (touch cs)]) + (for ([k (in-range n/2)]) + (define sk (+ start k)) + (define sk2 (+ sk n/2)) + (define br (flvector-ref xs-r sk)) + (define bi (flvector-ref xs-i sk)) + (define cr (flvector-ref xs-r sk2)) + (define ci (flvector-ref xs-i sk2)) + (flvector-set! as-r sk2 (- br cr)) + (flvector-set! as-i sk2 (- bi ci)) + (flvector-set! as-r sk (+ br cr)) + (flvector-set! as-i sk (+ bi ci))))) + +(: run-fft : (Listof Float-Complex) + -> (values (Listof Any) Integer Integer Integer)) +(define (run-fft l) + (define as-r (apply flvector (map real-part l))) + (define as-i (apply flvector (map imag-part l))) + (define n (flvector-length as-r)) + (define xs-r (make-flvector n 0.0)) + (define xs-i (make-flvector n 0.0)) + (collect-garbage) (collect-garbage) (collect-garbage) + (collect-garbage) (collect-garbage) (collect-garbage) + ((inst time-apply Void FlVector FlVector FlVector FlVector + Integer Integer Integer) + (λ () + (let ([f (future (λ () + (fft/depth as-r as-i xs-r xs-i n 0 0)))]) + (sleep 0.1) + (touch f))) + '())) + +(define: input : (Listof Float-Complex) + (for/list ([t 1048576]) + (define in (real->double-flonum (* t (/ (* 2 pi) 500)))) + (make-rectangular + (flsin (if (= in 0) 0.0 in)) + (flcos (if (= in 0) 0.0 in))))) +(run-fft input) + + From 9b066fa1e4874c9df31ab25a1743a06e90a32760 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 22 Jul 2012 21:40:31 -0500 Subject: [PATCH 615/746] fix `syntax-local-get-shadower' for submodules Closes PR 12926, 12928 Merge to v5.3 (cherry picked from commit a0ba30d8e7c16fbd572856ea950e82d98ccca4be) --- collects/tests/racket/package.rktl | 16 ++++++++++++++++ collects/tests/racket/submodule.rktl | 1 - collects/tests/racket/unitsig.rktl | 21 +++++++++++++++++++++ src/racket/src/env.c | 10 ++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/collects/tests/racket/package.rktl b/collects/tests/racket/package.rktl index fb947c744b..a331dca4f3 100644 --- a/collects/tests/racket/package.rktl +++ b/collects/tests/racket/package.rktl @@ -247,6 +247,22 @@ (open-package p5) q) +;; ---------------------------------------- +;; In a submodule + +(module package-in-a-submodule racket/base + (require racket/package) + + (define-package pkg (foo) + (define foo 5)) + + (module+ main + (open-package pkg) + (define out foo) + (provide out))) + +(test 5 dynamic-require '(submod 'package-in-a-submodule main) 'out) + ;; ---------------------------------------- (report-errs) diff --git a/collects/tests/racket/submodule.rktl b/collects/tests/racket/submodule.rktl index bce629630c..966a9f1aba 100644 --- a/collects/tests/racket/submodule.rktl +++ b/collects/tests/racket/submodule.rktl @@ -761,7 +761,6 @@ (provide v))))) (test 130 dynamic-require `(submod ,path main) 'v)) - ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/collects/tests/racket/unitsig.rktl b/collects/tests/racket/unitsig.rktl index f47f0157ad..9b38ca12c5 100644 --- a/collects/tests/racket/unitsig.rktl +++ b/collects/tests/racket/unitsig.rktl @@ -714,6 +714,27 @@ (list (signature->symbols s^)) (list (list)))) +;; ---------------------------------------- +;; In a submodule + +(module unit-in-a-submodule racket/base + (require racket/unit) + + (define-signature foo^ (f)) + + (module+ main + (define-unit foo@ + (import) + (export foo^) + + (define f (lambda (x) x))) + (define-values/invoke-unit/infer foo@) + + (define out (f 50)) + (provide out))) + +(test 50 dynamic-require '(submod 'unit-in-a-submodule main) 'out) + ;; -------------------------------------------------- (report-errs) diff --git a/src/racket/src/env.c b/src/racket/src/env.c index 912b3d9e10..240f2d8074 100644 --- a/src/racket/src/env.c +++ b/src/racket/src/env.c @@ -2232,6 +2232,16 @@ local_module_introduce(int argc, Scheme_Object *argv[]) v = scheme_stx_source_module(s, 0, 0); if (SCHEME_FALSEP(v)) { + if (env->genv->module + && env->genv->module->rn_stx + && SCHEME_VECTORP(env->genv->module->rn_stx)) { + /* This is a submodule, and `rn_stx' has renames for the enclosing modules */ + int i; + for (i = SCHEME_VEC_SIZE(env->genv->module->rn_stx); i-- > 1; ) { + v = SCHEME_VEC_ELS(env->genv->module->rn_stx)[i]; + s = scheme_add_rename(s, scheme_stx_to_rename(v)); + } + } if (env->genv->rename_set) s = scheme_add_rename(s, env->genv->rename_set); if (env->genv->post_ex_rename_set) From 7ada2691b93f8a4aa619759b15fdb6edb76b4985 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 23 Jul 2012 07:03:09 -0500 Subject: [PATCH 616/746] errortrace: fix profiling for phase >= 2 code Closes PR 25050 Merge to v5.3 (cherry picked from commit 05495764ea51260710fd3a976c93a7eb58b0acb4) --- collects/errortrace/stacktrace.rkt | 41 +++++++++++-------- collects/tests/errortrace/phase-2-profile.rkt | 19 +++++++++ 2 files changed, 44 insertions(+), 16 deletions(-) create mode 100644 collects/tests/errortrace/phase-2-profile.rkt diff --git a/collects/errortrace/stacktrace.rkt b/collects/errortrace/stacktrace.rkt index 8abeeb5974..0e057cfb96 100644 --- a/collects/errortrace/stacktrace.rkt +++ b/collects/errortrace/stacktrace.rkt @@ -127,16 +127,23 @@ [profile-key (datum->syntax #f profile-key (quote-syntax here))] [register-profile-start register-profile-start] - [register-profile-done register-profile-done]) + [register-profile-done register-profile-done] + [app (syntax-shift-phase-level #'#%plain-app (- phase base-phase))] + [lt (syntax-shift-phase-level #'let (- phase base-phase))] + [qt (syntax-shift-phase-level #'quote (- phase base-phase))] + [bgn (syntax-shift-phase-level #'begin (- phase base-phase))] + [wcm (syntax-shift-phase-level #'with-continuation-mark (- phase base-phase))]) (with-syntax ([rest (insert-at-tail* - (syntax (#%plain-app register-profile-done 'key start)) + (syntax (app (qt register-profile-done) (qt key) start)) bodies phase)]) (syntax - (let ([start (#%plain-app register-profile-start 'key)]) - (with-continuation-mark 'profile-key 'key - (begin . rest)))))))) + (lt ([start (app (qt register-profile-start) (qt key))]) + (wcm + (qt profile-key) + (qt key) + (bgn . rest)))))))) (define (insert-at-tail* e exprs phase) (let ([new @@ -153,21 +160,23 @@ (define (insert-at-tail se sexpr phase) (with-syntax ([expr sexpr] - [e se]) + [e se] + [bgn (syntax-shift-phase-level #'begin (- phase base-phase))] + [bgn0 (syntax-shift-phase-level #'begin0 (- phase base-phase))]) (kernel-syntax-case/phase sexpr phase ;; negligible time to eval [id (identifier? sexpr) - (syntax (begin e expr))] - [(quote _) (syntax (begin e expr))] - [(quote-syntax _) (syntax (begin e expr))] - [(#%top . d) (syntax (begin e expr))] - [(#%variable-reference . d) (syntax (begin e expr))] + (syntax (bgn e expr))] + [(quote _) (syntax (bgn e expr))] + [(quote-syntax _) (syntax (bgn e expr))] + [(#%top . d) (syntax (bgn e expr))] + [(#%variable-reference . d) (syntax (bgn e expr))] ;; No tail effect, and we want to account for the time - [(#%plain-lambda . _) (syntax (begin0 expr e))] - [(case-lambda . _) (syntax (begin0 expr e))] - [(set! . _) (syntax (begin0 expr e))] + [(#%plain-lambda . _) (syntax (bgn0 expr e))] + [(case-lambda . _) (syntax (bgn0 expr e))] + [(set! . _) (syntax (bgn0 expr e))] [(let-values bindings . body) (insert-at-tail* se sexpr phase)] @@ -182,7 +191,7 @@ (insert-at-tail* se sexpr phase)] [(begin0 body ...) - (rearm sexpr (syntax (begin0 body ... e)))] + (rearm sexpr (syntax (bgn0 body ... e)))] [(if test then else) ;; WARNING: se inserted twice! @@ -197,7 +206,7 @@ [(#%plain-app . rest) (if (stx-null? (syntax rest)) ;; null constant - (syntax (begin e expr)) + (syntax (bgn e expr)) ;; application; exploit guaranteed left-to-right evaluation (insert-at-tail* se sexpr phase))] diff --git a/collects/tests/errortrace/phase-2-profile.rkt b/collects/tests/errortrace/phase-2-profile.rkt new file mode 100644 index 0000000000..976a277244 --- /dev/null +++ b/collects/tests/errortrace/phase-2-profile.rkt @@ -0,0 +1,19 @@ +#lang racket/base + +(provide phase-2-profile-tests) + +(define (phase-2-profile-tests) + (define ns (make-base-namespace)) + (parameterize ([current-namespace ns]) + (dynamic-require 'errortrace #f) + ((dynamic-require 'errortrace 'profiling-enabled) #t) + (eval + '(module m racket/base + (require (for-syntax racket/base)) + (begin-for-syntax + (require (for-syntax racket/base)) + (define-syntax (a stx) + (syntax-case stx () + [(_) #'123]))))))) + +(phase-2-profile-tests) From f3f9f61f912c66a32c2ace4d0f2eac67b6738dcd Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 23 Jul 2012 11:31:51 -0400 Subject: [PATCH 617/746] fixed small mistake in defform/none from conversion to syntax/parse merge into v5.3 but ask Matthew for second opinion (cherry picked from commit bf8c30727d4cb8def581f63e43cb79a1111ad8ff) --- collects/scribble/private/manual-form.rkt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribble/private/manual-form.rkt b/collects/scribble/private/manual-form.rkt index 3628ca8651..e08f114846 100644 --- a/collects/scribble/private/manual-form.rkt +++ b/collects/scribble/private/manual-form.rkt @@ -139,7 +139,7 @@ (*defforms k.kind #f '(spec) (list (lambda (ignored) (racketblock0/form spec))) null null - (list (list (lambda () (racket c.contract-id)) + (list (list (lambda () (racket c.contract-nonterm)) (lambda () (racketblock0 c.contract-expr))) ...) (lambda () (list desc ...)))))])) From e128d034146ce5ac6b911191f6007534b986c72a Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 23 Jul 2012 11:34:49 -0400 Subject: [PATCH 618/746] add redundancy for scene? to universe docs; Closes PR12924 merge into v5.3 (cherry picked from commit 94d472340d5684977a68c03e0c24a036b7a9626b) --- .../2htdp/scribblings/universe.scrbl | 80 +++++++++++-------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index 275fd09112..5a2983d345 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -7,6 +7,8 @@ 2htdp/image)) @(require scribble/struct) +@(define note-scene @margin-note*{See @secref{scene} for @racket[scene?].}) + @(define (table* . stuff) ;; (list paragraph paragraph) *-> Table (define (flow* x) (make-flow (list x))) @@ -56,27 +58,40 @@ The purpose of this documentation is to give experienced Schemers and HtDP @link["http://world.cs.brown.edu/"]{How to Design Worlds}. @; ----------------------------------------------------------------------------- -@section{Background} +@section[#:tag "scene"]{Background} -The universe teachpack assumes working knowledge of the basic image manipulation primitives, -either @racketmodname[htdp/image] or @racketmodname[2htdp/image]. Its operations -sometimes require scenes which for @racket[htdp/image] images means an image whose -pinhole is at (0,0). For @racketmodname[2htdp/image], every image is a scene. +The universe teachpack assumes working knowledge of the basic image +manipulation operations, either @racketmodname[htdp/image] or +@racketmodname[2htdp/image]. As far as this extended reference is +concerned, the major difference between the two image teachpacks is +the assumption that +@nested[#:style 'inset]{ + @racketmodname[htdp/image] programs render their state as @emph{scenes}, + i.e., images that satisfy the @racket[scene?] predicate. +} +Recall that @racketmodname[htdp/image] defines a scene to be an image whose +pinhole is at @math{(0,0)}. If your program uses the operations of +@racketmodname[2htdp/image], all images are also scenes. -The example programs in this document are all written using @racketmodname[2htdp/image] -primitives. +While the operations of this teachpack work with both image teachpacks, we +hope to eliminate @racketmodname[htdp/image] in the not-too-distant future. +All example programs are already written using @racketmodname[2htdp/image] +operations. We urge programmers to use @racketmodname[2htdp/image] when +they design new ``world'' and ``universe'' programs and to rewrite their +existing @racketmodname[htdp/image] programs to use +@racketmodname[2htdp/image]. @; ----------------------------------------------------------------------------- @section[#:tag "simulations"]{Simple Simulations} The simplest kind of animated @tech{world} program is a time-based - simulation, which is a series of scenes. The programmer's task is to - supply a function that creates a scene for each natural number. Handing + simulation, which is a series of images. The programmer's task is to + supply a function that creates an image for each natural number. Handing this function to the teachpack displays the simulation. @defproc[(animate [create-image (-> natural-number/c scene?)]) natural-number/c]{ - +@note-scene opens a canvas and starts a clock that ticks 28 times per second. Every time the clock ticks, DrRacket applies @racket[create-image] to the number of ticks passed since this function call. The results of these @@ -102,7 +117,7 @@ Example: @defproc[(run-simulation [create-image (-> natural-number/c scene?)]) true]{ - +@note-scene @racket[animate] was originally called @racket[run-simulation], and this binding is retained for backwards compatibility} @@ -147,7 +162,7 @@ The following picture provides an intuitive overview of the workings of a The handlers @racket[tock], @racket[react], and @racket[click] transform one world into another one; each time an event is handled, @racket[done] is used to check whether the world is final, in which case the program is - shut down; and finally, @racket[draw] renders each world as a scene, which + shut down; and finally, @racket[draw] renders each world as an image, which is then displayed on an external canvas. @deftech{WorldState} : @racket[any/c] @@ -190,7 +205,7 @@ The design of a world program demands that you come up with a data designated in the optional @racket[spec] clauses, especially how the @tech{world} program deals with clock ticks, with key events, with mouse events, and eventually with messages from the universe; how it renders - itself as a scene; when the program must shut down; where to register the + itself as an image; when the program must shut down; where to register the world with a universe; and whether to record the stream of events. A world specification may not contain more than one @racket[on-tick], @racket[to-draw], or @racket[register] clause. A @racket[big-bang] @@ -208,11 +223,11 @@ The only mandatory clause of a @racket[big-bang] description is @defform[(to-draw render-expr) #:contracts ([render-expr (-> (unsyntax @tech{WorldState}) scene?)])]{ - +@note-scene tells DrRacket to call the function @racket[render-expr] whenever the canvas must be drawn. The external canvas is usually re-drawn after DrRacket has dealt with an event. Its size is determined by the size of the first - generated @tech{scene}.} + generated image.} @defform/none[#:literals (to-draw) (to-draw render-expr width-expr height-expr) @@ -220,9 +235,9 @@ The only mandatory clause of a @racket[big-bang] description is ([render-expr (-> (unsyntax @tech{WorldState}) scene?)] [width-expr natural-number/c] [height-expr natural-number/c])]{ - +@note-scene tells DrRacket to use a @racket[width-expr] by @racket[height-expr] - canvas instead of one determine by the first generated @tech{scene}. + canvas instead of one determine by the first generated image. } For compatibility reasons, the teachpack also supports the keyword @@ -405,7 +420,7 @@ Second, some keys have multiple-character string representations. Strings @item{A @tech{PadEvent} is a @tech{KeyEvent} for a game-pad simulation via @racket[big-bang]. The presence of an @racket[on-pad] clause superimposes -the game-pad image onto the current scene, suitably scaled to its size: +the game-pad image onto the current image, suitably scaled to its size: @image["gamepad.png"] @@ -644,9 +659,10 @@ All @tech{MouseEvent}s are represented via strings: #:contracts ([last-world? (-> (unsyntax @tech{WorldState}) boolean?)] [last-picture (-> (unsyntax @tech{WorldState}) scene?)])]{ +@note-scene tells DrRacket to call the @racket[last-world?] function whenever the canvas is drawn. If this call produces @racket[true], the world program is shut - down after displaying the world one last time, this time using the scene + down after displaying the world one last time, this time using the image rendered with @racket[last-picture]. Specifically, the clock is stopped; no more tick events, @tech{KeyEvent}s, or @tech{MouseEvent}s are forwarded to the respective handlers. The @racket[big-bang] expression returns this @@ -681,7 +697,7 @@ and @racket[big-bang] will close down all event handling.} ([r-expr any/c])]{ tells DrRacket to enable a visual replay of the interaction, unless @racket[#f]. - The replay action generates one png image per scene and + The replay action generates one png image per image and an animated gif for the entire sequence in the directory of the user's choice. If @racket[r-expr] evaluates to the name of an existing directory/folder (in the local directory/folder), the directory is used to @@ -1758,8 +1774,8 @@ The communication protocol and the refined data definition of @tech{WorldState} ;; or stay @racket['resting] (define (move w) ...) -;; WorldState -> Scene -;; render the world as a scene +;; WorldState -> Image +;; render the world as an image (define (render w) ...) )) @@ -1786,9 +1802,9 @@ Since there are two kinds of states, we make up at least two kinds of to @emph{receive}: @itemize[ -@item{@racket[HEIGHT] when the ball is at the bottom of the scene;} -@item{@racket[(- HEIGHT 1)] when the ball is properly inside the scene; and} -@item{@racket[0] when the ball has hit the top of the scene.} +@item{@racket[HEIGHT] when the ball is at the bottom of the image;} +@item{@racket[(- HEIGHT 1)] when the ball is properly inside the image; and} +@item{@racket[0] when the ball has hit the top of the image.} ] In the third case the function could produce three distinct results: @@ -1802,7 +1818,7 @@ We choose to design @emph{receive} so that it ignores the message and moves in a continuous fashion and that the @tech{world} remains active. Exercise: One alternative design is to move the ball back to the bottom of -the scene every time @racket['it-is-your-turn] is received. Design this function, too. +the image every time @racket['it-is-your-turn] is received. Design this function, too. @(begin #reader scribble/comment-reader @@ -1858,13 +1874,13 @@ Exercise: what could happen if we had designed @emph{receive} so that it state change to the tick event handler instead of the message receipt handler? -Finally, here is the third function, which renders the state as a scene: +Finally, here is the third function, which renders the state as an image: @(begin #reader scribble/comment-reader (racketblock -; WorldState -> Scene -; render the state of the world as a scene +; WorldState -> Image +; render the state of the world as an image (check-expect (render HEIGHT) (underlay/xy MT 50 HEIGHT BALL)) (check-expect (render 'resting) @@ -1880,14 +1896,14 @@ Finally, here is the third function, which renders the state as a scene: )) - Here is an improvement that adds a name to the scene and abstracts over + Here is an improvement that adds a name to the image and abstracts over the name at the same time: @(begin #reader scribble/comment-reader (racketblock -; String -> (WorldState -> Scene) -; render the state of the world as a scene +; String -> (WorldState -> Image) +; render the state of the world as an image (check-expect ((draw "Carl") 100) From 87cfa42c6da400e23e99b0567c105b983026d517 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 23 Jul 2012 12:52:44 -0400 Subject: [PATCH 619/746] Fix GUI doc typo reported by Kieron Hardy Closes PR 12830 Merge to v5.3 (cherry picked from commit e0e5f7dd285731098e56ba31a12ff08bf372615d) --- collects/scribblings/gui/timer-class.scrbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collects/scribblings/gui/timer-class.scrbl b/collects/scribblings/gui/timer-class.scrbl index e71611e97b..05c49fff33 100644 --- a/collects/scribblings/gui/timer-class.scrbl +++ b/collects/scribblings/gui/timer-class.scrbl @@ -5,7 +5,7 @@ A @racket[timer%] object encapsulates an event-based alarm. To use a timer, either instantiate it with a @racket[timer-callback] thunk to - perform the alarm-based action, to derive a new class and override + perform the alarm-based action, or derive a new class and override the @method[timer% notify] method to perform the alarm-based action. Start a timer with @method[timer% start] and stop it with @method[timer% stop]. Supplying an initial @racket[interval] (in From 915deb2266066f279e2558a7643d6fad058ac252 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 23 Jul 2012 13:10:05 -0400 Subject: [PATCH 620/746] Doc fixes reported by Gary Baumgartner The typo on 'redex.racket-lang.org' still remains. Relevant to PR 12680 Merge to v5.3 (cherry picked from commit ea1636d4f1a7017da6ea1e25dc0c527174e2fdaa) --- collects/scribblings/drracket/keybindings.scrbl | 2 +- collects/scribblings/reference/class.scrbl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/scribblings/drracket/keybindings.scrbl b/collects/scribblings/drracket/keybindings.scrbl index 5e483e97c0..f6f1629d1d 100644 --- a/collects/scribblings/drracket/keybindings.scrbl +++ b/collects/scribblings/drracket/keybindings.scrbl @@ -254,7 +254,7 @@ s-exp framework/keybinding-lang (λ (ed evt) (when (is-a? ed text:basic<%>) (define fr (send ed get-top-level-window)) - ;; note: fr could be #f + @code:comment{note: fr could be #f} (when fr (send fr command)))))) (frame-key "t" execute-callback) diff --git a/collects/scribblings/reference/class.scrbl b/collects/scribblings/reference/class.scrbl index 5e42bc2e2c..9babc39139 100644 --- a/collects/scribblings/reference/class.scrbl +++ b/collects/scribblings/reference/class.scrbl @@ -1260,7 +1260,7 @@ initialization variables can be mutated with @racket[set!]. @subsection[#:tag "methodcalls"]{Methods} -Method names within a class can only be used in the procedure position +Method names used within a class can only be used in the procedure position of an application expression; any other use is a syntax error. To allow methods to be applied to lists of arguments, a method @@ -1313,7 +1313,7 @@ Calls the method on @racket[obj] whose name matches @racket[kw-arg]s.} -@defform/subs[(send* obj-expr msg ...) +@defform/subs[(send* obj-expr msg ...+) ([msg (method-id arg ...) (method-id arg ... . arg-list-expr)])]{ From 1150423fffa28130f8954048bef9b689451c1c1d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 23 Jul 2012 10:03:28 -0500 Subject: [PATCH 621/746] ffi/com: AddRef on IUnknown arguments to COM methods Merge to v5.3 (cherry picked from commit cd90510f07b228a153d7e8a6f06e4290ec6a0e7f) --- collects/ffi/unsafe/com.rkt | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index 95911fb53e..5fa6b43a22 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -132,12 +132,18 @@ (lambda (p) (cast p _pointer _string/utf-16)))) (define current-cleanup (make-parameter #f)) +(define current-commit (make-parameter #f)) (define (register-cleanup! proc) (let ([c (current-cleanup)]) (when c (set-box! c (cons proc (unbox c)))))) +(define (register-commit! proc) + (let ([c (current-commit)]) + (when c + (set-box! c (cons proc (unbox c)))))) + ;; ---------------------------------------- ;; Describing COM interfaces for direct calls @@ -285,12 +291,14 @@ refiid)) (and p (cast p _pointer _type))))) +(define AddRef/no-release + (lambda (obj) + (check-com-type 'AddRef 'IUknown IUnknown? obj) + ((IUnknown_vt-AddRef (cast (IUnknown-vt obj) _pointer _IUnknown_vt-pointer)) + obj))) + (define AddRef - ((retainer Release) - (lambda (obj) - (check-com-type 'AddRef 'IUknown IUnknown? obj) - ((IUnknown_vt-AddRef (cast (IUnknown-vt obj) _pointer _IUnknown_vt-pointer)) - obj)))) + ((retainer Release) AddRef/no-release)) ;; -------------------------------------------------- ;; IDispatch @@ -1591,9 +1599,12 @@ (make-ctype _IUnknown-pointer (lambda (v) - (if (com-object? v) - (com-object-get-iunknown v) - v)) + (define p + (if (com-object? v) + (com-object-get-iunknown v) + v)) + (register-commit! (lambda () (AddRef/no-release p))) + p) (lambda (p) (((allocator Release) (lambda () p))) (define obj (make-com-object p #f)) @@ -1691,7 +1702,9 @@ (define cleanup (box (if vars (list (lambda () (free vars))) null))) - (parameterize ([current-cleanup cleanup]) + (define commit (box null)) + (parameterize ([current-cleanup cleanup] + [current-commit commit]) (for ([i (in-range count)] [a (in-sequences (in-list args) (in-cycle (list com-omit)))] @@ -1708,7 +1721,8 @@ (if (= inv-kind INVOKE_PROPERTYPUT) count 0)) - (unbox cleanup))) + (unbox cleanup) + (unbox commit))) (define (variant-to-scheme var) (define _t (to-ctype (vt-to-scheme-type (VARIANT-vt var)))) @@ -1761,7 +1775,7 @@ (mx-com-type-desc-memid type-desc) (find-memid who obj name)) => (lambda (memid) - (define-values (num-params-passed method-arguments cleanups) + (define-values (num-params-passed method-arguments cleanups commits) (build-method-arguments type-desc (cadr t) inv-kind @@ -1780,6 +1794,7 @@ (if (= inv-kind INVOKE_PROPERTYPUT) #f (make-a-VARIANT 'atomic))) + (for ([proc (in-list commits)]) (proc)) (define-values (hr exn-info error-index) (Invoke (com-object-get-dispatch obj) memid IID_NULL LOCALE_SYSTEM_DEFAULT From 87b5e83c6b85e1127659b5f3d98f611b52f70cfd Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 23 Jul 2012 15:04:07 -0400 Subject: [PATCH 622/746] Fix guide description of `when` Closes PR 12445 Merge to v5.3 (cherry picked from commit 2b173612e6a50b972442e719b84f025f50928d16) --- collects/scribblings/guide/begin.scrbl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/collects/scribblings/guide/begin.scrbl b/collects/scribblings/guide/begin.scrbl index b0883215cd..e94932c37f 100644 --- a/collects/scribblings/guide/begin.scrbl +++ b/collects/scribblings/guide/begin.scrbl @@ -101,8 +101,10 @@ sequencing for the ``then'' clause and no ``else'' clause: @specform[(when test-expr then-expr ...)] If @racket[_test-expr] produces a true value, then all of the -@racket[_then-expr]s are evaluated. Otherwise, no @racket[_then-expr]s -are evaluated. The result is @|void-const| in any case. +@racket[_then-expr]s are evaluated. The result of the last +@racket[_then-expr] is the result of the @racket[when] form. +Otherwise, no @racket[_then-expr]s are evaluated and the +result is @|void-const|. The @racket[unless] form is similar: From e8ea68634003392a950bf472880c7f73da3b89ff Mon Sep 17 00:00:00 2001 From: Matthias Felleisen Date: Mon, 23 Jul 2012 16:57:16 -0400 Subject: [PATCH 623/746] addex index entry for add/plus, multiply, and friends Closes PR12895 -- well, except that index points to htdp-langs for all five occurrences of each (to be fixed) merge to v5.3 (cherry picked from commit f9724f389db1a04d0eb4bdb6af9198b67410a62b) --- collects/lang/private/beginner-funs.rkt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/collects/lang/private/beginner-funs.rkt b/collects/lang/private/beginner-funs.rkt index f518a1c3a5..08ab14ddc8 100644 --- a/collects/lang/private/beginner-funs.rkt +++ b/collects/lang/private/beginner-funs.rkt @@ -125,37 +125,37 @@ @interaction[#:eval (bsl) (>= 42 42)] } @defproc[((beginner-+ +) [x number][y number][z number] ...) number]{ - Adds up all numbers. + @index["plus"]{}@index["add"]{Adds} up all numbers. @interaction[#:eval (bsl) (+ 2/3 1/16) (+ 3 2 5 8)] } @defproc[(- [x number][y number] ...) number]{ - Subtracts the second (and following) number(s) from the first ; + @index["subtract"]{Subtracts} the second (and following) number(s) from the first ; negates the number if there is only one argument. @interaction[#:eval (bsl) (- 5) (- 5 3) (- 5 3 1)] } @defproc[((beginner-* *) [x number][y number][z number] ...) number]{ - Multiplies all numbers. + @index["times"]{}@index["product"]{}@index["multiply"]{Multiplies} all numbers. @interaction[#:eval (bsl) (* 5 3) (* 5 3 2)] } @defproc[((beginner-/ /) [x number][y number][z number] ...) number]{ - Divides the first by the second (and all following) number(s). + @index["divide"]{Divides} the first by the second (and all following) number(s). @interaction[#:eval (bsl) (/ 12 2) (/ 12 2 3)] } @defproc[(max [x real][y real] ...) real]{ - Determines the largest number. + Determines the largest number---aka, the @index["maximum"]{maxiumum}. @interaction[#:eval (bsl) (max 3 2 8 7 2 9 0)] } @defproc[(min [x real][y real] ...) real]{ - Determines the smallest number. + Determines the smallest number---aka, the @index["minimum"]{miniumum}. @interaction[#:eval (bsl) (min 3 2 8 7 2 9 0)] } @defproc[(quotient [x integer][y integer]) integer]{ Divides the second integer---also called divisor---into the first---known as - dividend---to obtain the quotient. + dividend---to obtain the @index[(list "divide" "quotient")]{quotient}. @interaction[#:eval (bsl) (quotient 9 2) (quotient 3 4)] } @defproc[(remainder [x integer][y integer]) integer]{ - Determines the remainder of dividing the first by the second integer + Determines the @index[(list "divide" "remainder")]{remainder} of dividing the first by the second integer (exact or inexact). @interaction[#:eval (bsl) (remainder 9 2) (remainder 3 4)] } @@ -164,7 +164,7 @@ @interaction[#:eval (bsl) (modulo 9 2) (modulo 3 -4)] } @defproc[((beginner-sqr sqr) [x number]) number]{ - Computes the square of a number. + Computes the @index["square"]{square} of a number. @interaction[#:eval (bsl) (sqr 8)] } @defproc[(sqrt [x number]) number]{ @@ -200,15 +200,15 @@ ;; trigonometry @defproc[(sin [x number]) number]{ - Computes the sine of a number (radians). + Computes the @index["sine"]{sine} of a number (radians). @interaction[#:eval (bsl) (sin pi)] } @defproc[(cos [x number]) number]{ - Computes the cosine of a number (radians). + Computes the @index["cosine"]{cosine} of a number (radians). @interaction[#:eval (bsl) (cos pi)] } @defproc[(tan [x number]) number]{ - Computes the tangent of a number (radians). + Computes the @index["tangent"]{tangent} of a number (radians). @interaction[#:eval (bsl) (tan pi)] } @defproc[(asin [x number]) number]{ From 31029f9c7731cbda93f0c57683f0919ad0ed36c4 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 23 Jul 2012 20:54:31 -0400 Subject: [PATCH 624/746] Make some web server example code use a valid URL. (cherry picked from commit 8e889cfdb1b9e2a012bde2d09be60731a725f8eb) --- collects/web-server/scribblings/http.scrbl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collects/web-server/scribblings/http.scrbl b/collects/web-server/scribblings/http.scrbl index 667c2aad25..a5c61aab43 100644 --- a/collects/web-server/scribblings/http.scrbl +++ b/collects/web-server/scribblings/http.scrbl @@ -184,7 +184,7 @@ Here is an example typical of what you will find in many applications: 301 #"Moved Permanently" (current-seconds) TEXT/HTML-MIME-TYPE (list (make-header #"Location" - #"http://racket-lang.org/downloads")) + #"http://racket-lang.org/download")) (λ (op) (write-bytes #"Moved" op))) ] } @@ -200,10 +200,10 @@ Here is an example typical of what you will find in many applications: 301 #"Moved Permanently" (current-seconds) TEXT/HTML-MIME-TYPE (list (make-header #"Location" - #"http://racket-lang.org/downloads")) + #"http://racket-lang.org/download")) (list #"