diff options
| -rw-r--r-- | lisp/calendar/calendar.el | 31 | ||||
| -rw-r--r-- | lisp/calendar/solar.el | 21 |
2 files changed, 42 insertions, 10 deletions
diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index 96ccd94382c..76b077ba95c 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el | |||
| @@ -115,6 +115,37 @@ | |||
| 115 | 115 | ||
| 116 | (load "cal-loaddefs" nil t) | 116 | (load "cal-loaddefs" nil t) |
| 117 | 117 | ||
| 118 | ;; Calendar has historically relied heavily on dynamic scoping. | ||
| 119 | ;; Concretely, this manifests in the use of references to let-bound variables | ||
| 120 | ;; in Custom vars as well as code in diary files. | ||
| 121 | ;; `eval` is hence the core of the culprit. It's used on: | ||
| 122 | ;; - calendar-date-display-form | ||
| 123 | ;; - calendar-time-display-form | ||
| 124 | ;; - calendar-chinese-time-zone | ||
| 125 | ;; - in cal-dst's there are various calls to `eval' but they seem not to refer | ||
| 126 | ;; to let-bound variables, surprisingly. | ||
| 127 | ;; - calendar-date-echo-text | ||
| 128 | ;; - calendar-mode-line-format | ||
| 129 | ;; - cal-tex-daily-string | ||
| 130 | ;; - diary-date-forms | ||
| 131 | ;; - diary-remind-message | ||
| 132 | ;; - calendar-holidays | ||
| 133 | ;; - calendar-location-name | ||
| 134 | ;; - whatever is passed to calendar-string-spread | ||
| 135 | ;; - whatever is passed to calendar-insert-at-column | ||
| 136 | ;; - whatever is passed to diary-sexp-entry | ||
| 137 | ;; - whatever is passed to diary-remind | ||
| 138 | |||
| 139 | (defmacro calendar-dlet* (binders &rest body) | ||
| 140 | "Like `let*' but using dynamic scoping." | ||
| 141 | (declare (indent 1) (debug let)) | ||
| 142 | `(progn | ||
| 143 | (with-no-warnings ;Silence "lacks a prefix" warnings! | ||
| 144 | ,@(mapcar (lambda (binder) | ||
| 145 | `(defvar ,(if (consp binder) (car binder) binder))) | ||
| 146 | binders)) | ||
| 147 | (let* ,binders ,@body))) | ||
| 148 | |||
| 118 | ;; Avoid recursive load of calendar when loading cal-menu. Yuck. | 149 | ;; Avoid recursive load of calendar when loading cal-menu. Yuck. |
| 119 | (provide 'calendar) | 150 | (provide 'calendar) |
| 120 | (require 'cal-menu) | 151 | (require 'cal-menu) |
diff --git a/lisp/calendar/solar.el b/lisp/calendar/solar.el index 5bf072384fd..84e8bb3d259 100644 --- a/lisp/calendar/solar.el +++ b/lisp/calendar/solar.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;;; solar.el --- calendar functions for solar events | 1 | ;;; solar.el --- calendar functions for solar events -*- lexical-binding:t -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1992-1993, 1995, 1997, 2001-2017 Free Software | 3 | ;; Copyright (C) 1992-1993, 1995, 1997, 2001-2017 Free Software |
| 4 | ;; Foundation, Inc. | 4 | ;; Foundation, Inc. |
| @@ -552,12 +552,14 @@ degrees to find out if polar regions have 24 hours of sun or only night." | |||
| 552 | "Printable form for decimal fraction TIME in TIME-ZONE. | 552 | "Printable form for decimal fraction TIME in TIME-ZONE. |
| 553 | Format used is given by `calendar-time-display-form'." | 553 | Format used is given by `calendar-time-display-form'." |
| 554 | (let* ((time (round (* 60 time))) | 554 | (let* ((time (round (* 60 time))) |
| 555 | (24-hours (/ time 60)) | 555 | (24-hours (/ time 60))) |
| 556 | (calendar-dlet* | ||
| 557 | ((time-zone time-zone) | ||
| 556 | (minutes (format "%02d" (% time 60))) | 558 | (minutes (format "%02d" (% time 60))) |
| 557 | (12-hours (format "%d" (1+ (% (+ 24-hours 11) 12)))) | 559 | (12-hours (format "%d" (1+ (% (+ 24-hours 11) 12)))) |
| 558 | (am-pm (if (>= 24-hours 12) "pm" "am")) | 560 | (am-pm (if (>= 24-hours 12) "pm" "am")) |
| 559 | (24-hours (format "%02d" 24-hours))) | 561 | (24-hours (format "%02d" 24-hours))) |
| 560 | (mapconcat 'eval calendar-time-display-form ""))) | 562 | (mapconcat #'eval calendar-time-display-form "")))) |
| 561 | 563 | ||
| 562 | (defun solar-daylight (time) | 564 | (defun solar-daylight (time) |
| 563 | "Printable form for TIME expressed in hours." | 565 | "Printable form for TIME expressed in hours." |
| @@ -661,10 +663,10 @@ Optional NOLOCATION non-nil means do not print the location." | |||
| 661 | (format | 663 | (format |
| 662 | "%s, %s%s (%s hrs daylight)" | 664 | "%s, %s%s (%s hrs daylight)" |
| 663 | (if (car l) | 665 | (if (car l) |
| 664 | (concat "Sunrise " (apply 'solar-time-string (car l))) | 666 | (concat "Sunrise " (apply #'solar-time-string (car l))) |
| 665 | "No sunrise") | 667 | "No sunrise") |
| 666 | (if (cadr l) | 668 | (if (cadr l) |
| 667 | (concat "sunset " (apply 'solar-time-string (cadr l))) | 669 | (concat "sunset " (apply #'solar-time-string (cadr l))) |
| 668 | "no sunset") | 670 | "no sunset") |
| 669 | (if nolocation "" | 671 | (if nolocation "" |
| 670 | (format " at %s" (eval calendar-location-name))) | 672 | (format " at %s" (eval calendar-location-name))) |
| @@ -749,7 +751,7 @@ The values of `calendar-daylight-savings-starts', | |||
| 749 | (+ 4.9353929 | 751 | (+ 4.9353929 |
| 750 | (* 62833.1961680 U) | 752 | (* 62833.1961680 U) |
| 751 | (* 0.0000001 | 753 | (* 0.0000001 |
| 752 | (apply '+ | 754 | (apply #'+ |
| 753 | (mapcar (lambda (x) | 755 | (mapcar (lambda (x) |
| 754 | (* (car x) | 756 | (* (car x) |
| 755 | (sin (mod | 757 | (sin (mod |
| @@ -889,13 +891,12 @@ Accurate to a few seconds." | |||
| 889 | (insert (format "%s %2d: " (calendar-month-name month t) (1+ i)) | 891 | (insert (format "%s %2d: " (calendar-month-name month t) (1+ i)) |
| 890 | (solar-sunrise-sunset-string date t) "\n"))))) | 892 | (solar-sunrise-sunset-string date t) "\n"))))) |
| 891 | 893 | ||
| 892 | (defvar date) | ||
| 893 | |||
| 894 | ;; To be called from diary-list-sexp-entries, where DATE is bound. | ||
| 895 | ;;;###diary-autoload | 894 | ;;;###diary-autoload |
| 896 | (defun diary-sunrise-sunset () | 895 | (defun diary-sunrise-sunset () |
| 897 | "Local time of sunrise and sunset as a diary entry. | 896 | "Local time of sunrise and sunset as a diary entry. |
| 898 | Accurate to a few seconds." | 897 | Accurate to a few seconds." |
| 898 | ;; To be called from diary-list-sexp-entries, where DATE is bound. | ||
| 899 | (with-no-warnings (defvar date)) | ||
| 899 | (or (and calendar-latitude calendar-longitude calendar-time-zone) | 900 | (or (and calendar-latitude calendar-longitude calendar-time-zone) |
| 900 | (solar-setup)) | 901 | (solar-setup)) |
| 901 | (solar-sunrise-sunset-string date)) | 902 | (solar-sunrise-sunset-string date)) |
| @@ -938,7 +939,7 @@ Accurate to within a minute between 1951 and 2050." | |||
| 938 | (W (- (* 35999.373 T) 2.47)) | 939 | (W (- (* 35999.373 T) 2.47)) |
| 939 | (Delta-lambda (+ 1 (* 0.0334 (solar-cosine-degrees W)) | 940 | (Delta-lambda (+ 1 (* 0.0334 (solar-cosine-degrees W)) |
| 940 | (* 0.0007 (solar-cosine-degrees (* 2 W))))) | 941 | (* 0.0007 (solar-cosine-degrees (* 2 W))))) |
| 941 | (S (apply '+ (mapcar (lambda(x) | 942 | (S (apply #'+ (mapcar (lambda(x) |
| 942 | (* (car x) (solar-cosine-degrees | 943 | (* (car x) (solar-cosine-degrees |
| 943 | (+ (* (nth 2 x) T) (cadr x))))) | 944 | (+ (* (nth 2 x) T) (cadr x))))) |
| 944 | solar-seasons-data))) | 945 | solar-seasons-data))) |