1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-02-05 15:11:30 -08:00

* lisp/calendar/solar.el: Use lexical-binding

(date): Don't declare globally.
(solar-time-string): Use calendar-dlet*.

* lisp/calendar/calendar.el (calendar-dlet*): New macro.
This commit is contained in:
Stefan Monnier 2017-12-04 15:36:22 -05:00
parent 4cf5a3ac57
commit 512f81407c
2 changed files with 42 additions and 10 deletions

View file

@ -115,6 +115,37 @@
(load "cal-loaddefs" nil t)
;; Calendar has historically relied heavily on dynamic scoping.
;; Concretely, this manifests in the use of references to let-bound variables
;; in Custom vars as well as code in diary files.
;; `eval` is hence the core of the culprit. It's used on:
;; - calendar-date-display-form
;; - calendar-time-display-form
;; - calendar-chinese-time-zone
;; - in cal-dst's there are various calls to `eval' but they seem not to refer
;; to let-bound variables, surprisingly.
;; - calendar-date-echo-text
;; - calendar-mode-line-format
;; - cal-tex-daily-string
;; - diary-date-forms
;; - diary-remind-message
;; - calendar-holidays
;; - calendar-location-name
;; - whatever is passed to calendar-string-spread
;; - whatever is passed to calendar-insert-at-column
;; - whatever is passed to diary-sexp-entry
;; - whatever is passed to diary-remind
(defmacro calendar-dlet* (binders &rest body)
"Like `let*' but using dynamic scoping."
(declare (indent 1) (debug let))
`(progn
(with-no-warnings ;Silence "lacks a prefix" warnings!
,@(mapcar (lambda (binder)
`(defvar ,(if (consp binder) (car binder) binder)))
binders))
(let* ,binders ,@body)))
;; Avoid recursive load of calendar when loading cal-menu. Yuck.
(provide 'calendar)
(require 'cal-menu)

View file

@ -1,4 +1,4 @@
;;; solar.el --- calendar functions for solar events
;;; solar.el --- calendar functions for solar events -*- lexical-binding:t -*-
;; Copyright (C) 1992-1993, 1995, 1997, 2001-2017 Free Software
;; Foundation, Inc.
@ -552,12 +552,14 @@ degrees to find out if polar regions have 24 hours of sun or only night."
"Printable form for decimal fraction TIME in TIME-ZONE.
Format used is given by `calendar-time-display-form'."
(let* ((time (round (* 60 time)))
(24-hours (/ time 60))
(24-hours (/ time 60)))
(calendar-dlet*
((time-zone time-zone)
(minutes (format "%02d" (% time 60)))
(12-hours (format "%d" (1+ (% (+ 24-hours 11) 12))))
(am-pm (if (>= 24-hours 12) "pm" "am"))
(24-hours (format "%02d" 24-hours)))
(mapconcat 'eval calendar-time-display-form "")))
(mapconcat #'eval calendar-time-display-form ""))))
(defun solar-daylight (time)
"Printable form for TIME expressed in hours."
@ -661,10 +663,10 @@ Optional NOLOCATION non-nil means do not print the location."
(format
"%s, %s%s (%s hrs daylight)"
(if (car l)
(concat "Sunrise " (apply 'solar-time-string (car l)))
(concat "Sunrise " (apply #'solar-time-string (car l)))
"No sunrise")
(if (cadr l)
(concat "sunset " (apply 'solar-time-string (cadr l)))
(concat "sunset " (apply #'solar-time-string (cadr l)))
"no sunset")
(if nolocation ""
(format " at %s" (eval calendar-location-name)))
@ -749,7 +751,7 @@ The values of `calendar-daylight-savings-starts',
(+ 4.9353929
(* 62833.1961680 U)
(* 0.0000001
(apply '+
(apply #'+
(mapcar (lambda (x)
(* (car x)
(sin (mod
@ -889,13 +891,12 @@ Accurate to a few seconds."
(insert (format "%s %2d: " (calendar-month-name month t) (1+ i))
(solar-sunrise-sunset-string date t) "\n")))))
(defvar date)
;; To be called from diary-list-sexp-entries, where DATE is bound.
;;;###diary-autoload
(defun diary-sunrise-sunset ()
"Local time of sunrise and sunset as a diary entry.
Accurate to a few seconds."
;; To be called from diary-list-sexp-entries, where DATE is bound.
(with-no-warnings (defvar date))
(or (and calendar-latitude calendar-longitude calendar-time-zone)
(solar-setup))
(solar-sunrise-sunset-string date))
@ -938,7 +939,7 @@ Accurate to within a minute between 1951 and 2050."
(W (- (* 35999.373 T) 2.47))
(Delta-lambda (+ 1 (* 0.0334 (solar-cosine-degrees W))
(* 0.0007 (solar-cosine-degrees (* 2 W)))))
(S (apply '+ (mapcar (lambda(x)
(S (apply #'+ (mapcar (lambda(x)
(* (car x) (solar-cosine-degrees
(+ (* (nth 2 x) T) (cadr x)))))
solar-seasons-data)))